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 - check for False/None values p_street = company.street or "" p_city = company.city or "" p_state = company.state_id.code or company.state_id.name or "" p_zip = company.zip or "" p_country = company.country_id.name or "Canada" # Format: "Street, City State Zip, Country" pickup_address = f"{p_street}, {p_city} {p_state} {p_zip}, {p_country}".replace(" ", " ").strip(", ") # 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') or '').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 city = address_data.get('city', '').strip() zip_code = address_data.get('zip', '').strip() country = address_data.get('country', 'Canada').strip() country_record = request.env['res.country'].sudo().search([ '|', ('name', '=ilike', country), ('code', '=ilike', country) ], limit=1) country_name = country_record.name if country_record else "Canada" dropoff_address = f"{full_street}, {city} {state_to_send} {zip_code}, {country_name}".replace(" ", " ").strip(", ") _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