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()