from fastapi import APIRouter, HTTPException, Header, Request from pydantic import BaseModel from typing import Optional, Dict, Any import httpx import hmac import hashlib from app.config import get_settings router = APIRouter(prefix="/api/webhooks", tags=["webhooks"]) settings = get_settings() class OdooWebhookPayload(BaseModel): model: str action: str record_id: int values: Dict[str, Any] = {} old_values: Dict[str, Any] = {} @router.post("/odoo") async def handle_odoo_webhook(payload: OdooWebhookPayload): """ Handle webhooks from Odoo. Odoo sends events when records are created/updated/deleted. """ handlers = { "sale.order": handle_sale_order_event, "stock.picking": handle_stock_picking_event, "account.move": handle_invoice_event, } handler = handlers.get(payload.model) if handler: await handler(payload) return {"status": "received"} async def handle_sale_order_event(payload: OdooWebhookPayload): """Handle sale order events""" if payload.action != "write": return old_state = payload.old_values.get("state") new_state = payload.values.get("state") # Order confirmed if old_state == "draft" and new_state == "sale": await send_order_confirmation(payload.record_id) # Order delivered elif new_state == "done": await send_order_delivered(payload.record_id) async def handle_stock_picking_event(payload: OdooWebhookPayload): """Handle stock picking (delivery) events""" if payload.action != "write": return new_state = payload.values.get("state") # Shipment sent if new_state == "done": await send_shipment_notification(payload.record_id) async def handle_invoice_event(payload: OdooWebhookPayload): """Handle invoice events""" if payload.action != "write": return # Payment received if payload.values.get("payment_state") == "paid": await send_payment_confirmation(payload.record_id) async def send_order_confirmation(order_id: int): """Send WhatsApp message for order confirmation""" try: async with httpx.AsyncClient() as client: # Get order details response = await client.get( f"{settings.API_GATEWAY_URL}/api/odoo/sales/{order_id}", timeout=10, ) if response.status_code != 200: return order = response.json() # Get partner details partner_response = await client.get( f"{settings.API_GATEWAY_URL}/api/odoo/partners/{order['partner_id']}", timeout=10, ) if partner_response.status_code != 200: return partner = partner_response.json() phone = partner.get("mobile") or partner.get("phone") if not phone: return # Format message message = f"""*Pedido Confirmado* Hola {partner.get('name', '')}, Tu pedido *{order['name']}* ha sido confirmado. Total: {order['currency']} {order['amount_total']:.2f} Gracias por tu compra.""" # Send via API Gateway await client.post( f"{settings.API_GATEWAY_URL}/api/internal/send-by-phone", json={"phone": phone, "message": message}, timeout=10, ) except Exception as e: print(f"Failed to send order confirmation: {e}") async def send_shipment_notification(picking_id: int): """Send WhatsApp message for shipment""" # Similar implementation - get picking details and send notification pass async def send_order_delivered(order_id: int): """Send WhatsApp message for delivered order""" # Similar implementation pass async def send_payment_confirmation(invoice_id: int): """Send WhatsApp message for payment received""" # Similar implementation pass @router.get("/odoo/test") async def test_webhook(): """Test endpoint for webhook connectivity""" return {"status": "ok", "service": "webhooks"}