93 lines
3.9 KiB
Python

from odoo import http
from odoo.http import request
import json
import logging
_logger = logging.getLogger(__name__)
class UberWebhookController(http.Controller):
@http.route('/uber/webhook/delivery', type='json', auth='none', methods=['POST'], csrf=False)
def uber_delivery_webhook(self, **post):
"""Handle status updates from Uber Direct"""
data = json.loads(request.httprequest.data)
_logger.info("Uber Webhook Received: %s", json.dumps(data, indent=2))
uber_delivery_id = data.get('delivery_id')
status = data.get('status') # e.g., 'picked_up', 'delivered'
if uber_delivery_id:
order = request.env['pos.order'].sudo().search([('uber_delivery_id', '=', uber_delivery_id)], limit=1)
if order:
# Map Uber status to Odoo status
status_map = {
'pickup': 'pickup',
'pickup_completed': 'delivering',
'dropoff_completed': 'delivered',
'cancelled': 'cancelled'
}
order.uber_status = status_map.get(status, order.uber_status)
return {'status': 'success'}
return {'status': 'ignored'}
class UberDeliveryController(http.Controller):
@http.route('/shop/uber/quote', type='json', auth='public', website=True, csrf=False)
def uber_quote(self, address_data, **post):
"""Get Uber quote for a website address with cleaned address formatting"""
order = request.website.sale_get_order()
if not order:
return {'success': False, 'error': 'No active order'}
config = request.env['uber.config'].sudo().search([('active', '=', True)], limit=1)
if not config:
return {'success': False, 'error': 'Uber not configured'}
company = request.website.company_id
# Build clean pickup address using State CODE (e.g. ON for Ontario)
p_state = company.state_id.code or company.state_id.name or ""
pickup_address = f"{company.street}, {company.city} {p_state} {company.zip}, {company.country_id.name}"
# User entered address
street = address_data.get('street', '').strip()
street2 = address_data.get('street2', '').strip()
full_street = f"{street}, {street2}" if street2 else street
# Clean state (Try for code if possible)
state_input = address_data.get('state', '').split('(')[0].strip()
state_record = request.env['res.country.state'].sudo().search([
'|', ('name', '=ilike', state_input), ('code', '=ilike', state_input)
], limit=1)
state_to_send = state_record.code if state_record else state_input
# Construct dropoff string in exact POS format: "Street, City State Zip, Country"
city = address_data.get('city', '').strip()
zip_code = address_data.get('zip', '').strip()
country = address_data.get('country', 'Canada').strip()
# Canada country code is CA
country_code = "Canada"
country_record = request.env['res.country'].sudo().search([
'|', ('name', '=ilike', country), ('code', '=ilike', country)
], limit=1)
if country_record: country_code = country_record.name
dropoff_address = f"{full_street}, {city} {state_to_send} {zip_code}, {country_code}"
_logger.info("Uber Direct API Call - Pickup: '%s' | Dropoff: '%s'", pickup_address, dropoff_address)
result = config.get_uber_quote(pickup_address, dropoff_address)
if result.get('success'):
order.sudo()._add_uber_delivery_fee(result['fee_amount'])
return {
'success': True,
'fee': result['fee_amount'],
'eta': result.get('estimated_arrival'),
}
else:
_logger.warning("Uber Quote Failed: %s", result.get('error'))
return result