diff --git a/services/integrations/app/main.py b/services/integrations/app/main.py index 98808d8..43913b6 100644 --- a/services/integrations/app/main.py +++ b/services/integrations/app/main.py @@ -1,5 +1,6 @@ from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware +from app.routers import odoo_router app = FastAPI(title="WhatsApp Central - Integrations Service") @@ -11,6 +12,8 @@ app.add_middleware( allow_headers=["*"], ) +app.include_router(odoo_router) + @app.get("/health") def health_check(): diff --git a/services/integrations/app/routers/__init__.py b/services/integrations/app/routers/__init__.py new file mode 100644 index 0000000..3bda305 --- /dev/null +++ b/services/integrations/app/routers/__init__.py @@ -0,0 +1,3 @@ +from app.routers.odoo import router as odoo_router + +__all__ = ["odoo_router"] diff --git a/services/integrations/app/routers/odoo.py b/services/integrations/app/routers/odoo.py new file mode 100644 index 0000000..f520a6b --- /dev/null +++ b/services/integrations/app/routers/odoo.py @@ -0,0 +1,233 @@ +from fastapi import APIRouter, HTTPException +from typing import Optional + +from app.services.partner import PartnerService +from app.services.sale import SaleOrderService +from app.services.product import ProductService +from app.services.crm import CRMService +from app.schemas.partner import PartnerCreate, PartnerUpdate +from app.schemas.sale import QuotationCreate +from app.schemas.crm import LeadCreate +from app.odoo.exceptions import OdooError, OdooNotFoundError + +router = APIRouter(prefix="/api/odoo", tags=["odoo"]) + + +# ============== Partners ============== + +@router.get("/partners/search") +def search_partner(phone: str = None, email: str = None): + """Search partner by phone or email""" + service = PartnerService() + + if phone: + result = service.search_by_phone(phone) + elif email: + result = service.search_by_email(email) + else: + raise HTTPException(400, "Provide phone or email") + + if not result: + raise HTTPException(404, "Partner not found") + return result + + +@router.get("/partners/{partner_id}") +def get_partner(partner_id: int): + """Get partner by ID""" + try: + service = PartnerService() + return service.get_by_id(partner_id) + except OdooNotFoundError: + raise HTTPException(404, "Partner not found") + + +@router.post("/partners") +def create_partner(data: PartnerCreate): + """Create a new partner""" + try: + service = PartnerService() + partner_id = service.create(data) + return {"id": partner_id} + except OdooError as e: + raise HTTPException(400, str(e)) + + +@router.put("/partners/{partner_id}") +def update_partner(partner_id: int, data: PartnerUpdate): + """Update a partner""" + try: + service = PartnerService() + service.update(partner_id, data) + return {"success": True} + except OdooError as e: + raise HTTPException(400, str(e)) + + +@router.get("/partners/{partner_id}/balance") +def get_partner_balance(partner_id: int): + """Get partner balance""" + try: + service = PartnerService() + return service.get_balance(partner_id) + except OdooNotFoundError: + raise HTTPException(404, "Partner not found") + + +# ============== Sales ============== + +@router.get("/sales/partner/{partner_id}") +def get_partner_orders(partner_id: int, state: str = None, limit: int = 10): + """Get orders for a partner""" + service = SaleOrderService() + return service.search_by_partner(partner_id, state, limit) + + +@router.get("/sales/{order_id}") +def get_order(order_id: int): + """Get order details""" + try: + service = SaleOrderService() + return service.get_by_id(order_id) + except OdooNotFoundError: + raise HTTPException(404, "Order not found") + + +@router.get("/sales/name/{name}") +def get_order_by_name(name: str): + """Get order by name (SO001)""" + service = SaleOrderService() + result = service.get_by_name(name) + if not result: + raise HTTPException(404, "Order not found") + return result + + +@router.post("/sales/quotation") +def create_quotation(data: QuotationCreate): + """Create a quotation""" + try: + service = SaleOrderService() + order_id = service.create_quotation(data) + return {"id": order_id} + except OdooError as e: + raise HTTPException(400, str(e)) + + +@router.post("/sales/{order_id}/confirm") +def confirm_order(order_id: int): + """Confirm quotation to sale order""" + try: + service = SaleOrderService() + service.confirm_order(order_id) + return {"success": True} + except OdooError as e: + raise HTTPException(400, str(e)) + + +# ============== Products ============== + +@router.get("/products") +def search_products(q: str = None, category_id: int = None, limit: int = 20): + """Search products""" + service = ProductService() + return service.search(q, category_id, limit) + + +@router.get("/products/{product_id}") +def get_product(product_id: int): + """Get product details""" + try: + service = ProductService() + return service.get_by_id(product_id) + except OdooNotFoundError: + raise HTTPException(404, "Product not found") + + +@router.get("/products/sku/{sku}") +def get_product_by_sku(sku: str): + """Get product by SKU""" + service = ProductService() + result = service.get_by_sku(sku) + if not result: + raise HTTPException(404, "Product not found") + return result + + +@router.get("/products/{product_id}/stock") +def check_product_stock(product_id: int): + """Check product stock""" + try: + service = ProductService() + return service.check_stock(product_id) + except OdooNotFoundError: + raise HTTPException(404, "Product not found") + + +@router.get("/products/{product_id}/availability") +def check_availability(product_id: int, quantity: float): + """Check if quantity is available""" + try: + service = ProductService() + return service.check_availability(product_id, quantity) + except OdooNotFoundError: + raise HTTPException(404, "Product not found") + + +# ============== CRM ============== + +@router.post("/crm/leads") +def create_lead(data: LeadCreate): + """Create a new lead""" + try: + service = CRMService() + lead_id = service.create_lead(data) + return {"id": lead_id} + except OdooError as e: + raise HTTPException(400, str(e)) + + +@router.get("/crm/leads/{lead_id}") +def get_lead(lead_id: int): + """Get lead details""" + try: + service = CRMService() + return service.get_by_id(lead_id) + except OdooNotFoundError: + raise HTTPException(404, "Lead not found") + + +@router.get("/crm/leads/partner/{partner_id}") +def get_partner_leads(partner_id: int, limit: int = 10): + """Get leads for a partner""" + service = CRMService() + return service.search_by_partner(partner_id, limit) + + +@router.put("/crm/leads/{lead_id}/stage") +def update_lead_stage(lead_id: int, stage_id: int): + """Update lead stage""" + try: + service = CRMService() + service.update_stage(lead_id, stage_id) + return {"success": True} + except OdooError as e: + raise HTTPException(400, str(e)) + + +@router.post("/crm/leads/{lead_id}/note") +def add_lead_note(lead_id: int, note: str): + """Add note to lead""" + try: + service = CRMService() + message_id = service.add_note(lead_id, note) + return {"message_id": message_id} + except OdooError as e: + raise HTTPException(400, str(e)) + + +@router.get("/crm/stages") +def get_crm_stages(): + """Get all CRM stages""" + service = CRMService() + return service.get_stages()