from fastapi import APIRouter, Depends, Query from typing import Optional from auth.models import TokenPayload from auth.dependencies import require_permission from crm.models import OrderCreate, OrderUpdate, OrderInDB, OrderListResponse from crm import service router = APIRouter(prefix="/api/crm/customers/{customer_id}/orders", tags=["crm-orders"]) @router.get("", response_model=OrderListResponse) def list_orders( customer_id: str, _user: TokenPayload = Depends(require_permission("crm", "view")), ): orders = service.list_orders(customer_id) return OrderListResponse(orders=orders, total=len(orders)) # IMPORTANT: specific sub-paths must come before /{order_id} @router.get("/next-order-number") def get_next_order_number( customer_id: str, _user: TokenPayload = Depends(require_permission("crm", "view")), ): """Return the next globally unique order number (ORD-DDMMYY-NNN across all customers).""" return {"order_number": service._generate_order_number(customer_id)} @router.post("/init-negotiations", response_model=OrderInDB, status_code=201) def init_negotiations( customer_id: str, body: dict, _user: TokenPayload = Depends(require_permission("crm", "edit")), ): return service.init_negotiations( customer_id=customer_id, title=body.get("title", ""), note=body.get("note", ""), date=body.get("date"), created_by=body.get("created_by", ""), ) @router.post("", response_model=OrderInDB, status_code=201) def create_order( customer_id: str, body: OrderCreate, _user: TokenPayload = Depends(require_permission("crm", "edit")), ): return service.create_order(customer_id, body) @router.get("/{order_id}", response_model=OrderInDB) def get_order( customer_id: str, order_id: str, _user: TokenPayload = Depends(require_permission("crm", "view")), ): return service.get_order(customer_id, order_id) @router.patch("/{order_id}", response_model=OrderInDB) def update_order( customer_id: str, order_id: str, body: OrderUpdate, _user: TokenPayload = Depends(require_permission("crm", "edit")), ): return service.update_order(customer_id, order_id, body) @router.delete("/{order_id}", status_code=204) def delete_order( customer_id: str, order_id: str, _user: TokenPayload = Depends(require_permission("crm", "edit")), ): service.delete_order(customer_id, order_id) @router.post("/{order_id}/timeline", response_model=OrderInDB) def append_timeline_event( customer_id: str, order_id: str, body: dict, _user: TokenPayload = Depends(require_permission("crm", "edit")), ): return service.append_timeline_event(customer_id, order_id, body) @router.patch("/{order_id}/timeline/{index}", response_model=OrderInDB) def update_timeline_event( customer_id: str, order_id: str, index: int, body: dict, _user: TokenPayload = Depends(require_permission("crm", "edit")), ): return service.update_timeline_event(customer_id, order_id, index, body) @router.delete("/{order_id}/timeline/{index}", response_model=OrderInDB) def delete_timeline_event( customer_id: str, order_id: str, index: int, _user: TokenPayload = Depends(require_permission("crm", "edit")), ): return service.delete_timeline_event(customer_id, order_id, index) @router.patch("/{order_id}/payment-status", response_model=OrderInDB) def update_payment_status( customer_id: str, order_id: str, body: dict, _user: TokenPayload = Depends(require_permission("crm", "edit")), ): return service.update_order_payment_status(customer_id, order_id, body) # ── Global order list (collection group) ───────────────────────────────────── # Separate router registered at /api/crm/orders for the global OrderList page global_router = APIRouter(prefix="/api/crm/orders", tags=["crm-orders-global"]) @global_router.get("") def list_all_orders( status: Optional[str] = Query(None), _user: TokenPayload = Depends(require_permission("crm", "view")), ): orders = service.list_all_orders(status=status) # Enrich with customer names customer_ids = list({o.customer_id for o in orders if o.customer_id}) customer_names: dict[str, str] = {} for cid in customer_ids: try: c = service.get_customer(cid) parts = [c.name, c.organization] if c.organization else [c.name] customer_names[cid] = " / ".join(filter(None, parts)) except Exception: pass enriched = [] for o in orders: d = o.model_dump() d["customer_name"] = customer_names.get(o.customer_id) enriched.append(d) return {"orders": enriched, "total": len(enriched)}