Improve AI logic

This commit is contained in:
Urtzi Alfaro
2025-11-05 13:34:56 +01:00
parent 5c87fbcf48
commit 394ad3aea4
218 changed files with 30627 additions and 7658 deletions

View File

@@ -7,7 +7,7 @@ Purchase Orders API - Endpoints for purchase order management
import uuid
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from fastapi import APIRouter, Depends, HTTPException, Path, Query
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.database import get_db
@@ -24,11 +24,14 @@ from app.schemas.purchase_order_schemas import (
SupplierInvoiceCreate,
SupplierInvoiceResponse,
)
from shared.routing import RouteBuilder
import structlog
logger = structlog.get_logger()
router = APIRouter(prefix="/api/v1/tenants/{tenant_id}/purchase-orders", tags=["Purchase Orders"])
# Create route builder for consistent URL structure
route_builder = RouteBuilder('procurement')
router = APIRouter(tags=["purchase-orders"])
def get_po_service(db: AsyncSession = Depends(get_db)) -> PurchaseOrderService:
@@ -40,10 +43,14 @@ def get_po_service(db: AsyncSession = Depends(get_db)) -> PurchaseOrderService:
# PURCHASE ORDER CRUD
# ================================================================
@router.post("", response_model=PurchaseOrderResponse, status_code=201)
@router.post(
route_builder.build_base_route("purchase-orders"),
response_model=PurchaseOrderResponse,
status_code=201
)
async def create_purchase_order(
tenant_id: str,
po_data: PurchaseOrderCreate,
tenant_id: str = Path(..., description="Tenant ID"),
service: PurchaseOrderService = Depends(get_po_service)
):
"""
@@ -76,10 +83,13 @@ async def create_purchase_order(
raise HTTPException(status_code=500, detail=str(e))
@router.get("/{po_id}", response_model=PurchaseOrderWithSupplierResponse)
@router.get(
route_builder.build_resource_detail_route("purchase-orders", "po_id"),
response_model=PurchaseOrderWithSupplierResponse
)
async def get_purchase_order(
tenant_id: str,
po_id: str,
tenant_id: str = Path(..., description="Tenant ID"),
service: PurchaseOrderService = Depends(get_po_service)
):
"""Get purchase order by ID with items"""
@@ -101,9 +111,12 @@ async def get_purchase_order(
raise HTTPException(status_code=500, detail=str(e))
@router.get("", response_model=List[PurchaseOrderResponse])
@router.get(
route_builder.build_base_route("purchase-orders"),
response_model=List[PurchaseOrderResponse]
)
async def list_purchase_orders(
tenant_id: str,
tenant_id: str = Path(..., description="Tenant ID"),
skip: int = Query(default=0, ge=0),
limit: int = Query(default=50, ge=1, le=100),
supplier_id: Optional[str] = Query(default=None),
@@ -139,11 +152,14 @@ async def list_purchase_orders(
raise HTTPException(status_code=500, detail=str(e))
@router.patch("/{po_id}", response_model=PurchaseOrderResponse)
@router.patch(
route_builder.build_resource_detail_route("purchase-orders", "po_id"),
response_model=PurchaseOrderResponse
)
async def update_purchase_order(
tenant_id: str,
po_id: str,
po_data: PurchaseOrderUpdate,
tenant_id: str = Path(..., description="Tenant ID"),
service: PurchaseOrderService = Depends(get_po_service)
):
"""
@@ -181,11 +197,13 @@ async def update_purchase_order(
raise HTTPException(status_code=500, detail=str(e))
@router.patch("/{po_id}/status")
@router.patch(
route_builder.build_resource_action_route("purchase-orders", "po_id", "status")
)
async def update_order_status(
tenant_id: str,
po_id: str,
status: str = Query(..., description="New status"),
tenant_id: str = Path(..., description="Tenant ID"),
notes: Optional[str] = Query(default=None),
service: PurchaseOrderService = Depends(get_po_service)
):
@@ -239,11 +257,14 @@ async def update_order_status(
# APPROVAL WORKFLOW
# ================================================================
@router.post("/{po_id}/approve", response_model=PurchaseOrderResponse)
@router.post(
route_builder.build_resource_action_route("purchase-orders", "po_id", "approve"),
response_model=PurchaseOrderResponse
)
async def approve_purchase_order(
tenant_id: str,
po_id: str,
approval_data: PurchaseOrderApproval,
tenant_id: str = Path(..., description="Tenant ID"),
service: PurchaseOrderService = Depends(get_po_service)
):
"""
@@ -289,12 +310,15 @@ async def approve_purchase_order(
raise HTTPException(status_code=500, detail=str(e))
@router.post("/{po_id}/cancel", response_model=PurchaseOrderResponse)
@router.post(
route_builder.build_resource_action_route("purchase-orders", "po_id", "cancel"),
response_model=PurchaseOrderResponse
)
async def cancel_purchase_order(
tenant_id: str,
po_id: str,
reason: str = Query(..., description="Cancellation reason"),
cancelled_by: Optional[str] = Query(default=None),
tenant_id: str = Path(..., description="Tenant ID"),
service: PurchaseOrderService = Depends(get_po_service)
):
"""
@@ -335,11 +359,15 @@ async def cancel_purchase_order(
# DELIVERY MANAGEMENT
# ================================================================
@router.post("/{po_id}/deliveries", response_model=DeliveryResponse, status_code=201)
@router.post(
route_builder.build_nested_resource_route("purchase-orders", "po_id", "deliveries"),
response_model=DeliveryResponse,
status_code=201
)
async def create_delivery(
tenant_id: str,
po_id: str,
delivery_data: DeliveryCreate,
tenant_id: str = Path(..., description="Tenant ID"),
service: PurchaseOrderService = Depends(get_po_service)
):
"""
@@ -375,11 +403,14 @@ async def create_delivery(
raise HTTPException(status_code=500, detail=str(e))
@router.patch("/deliveries/{delivery_id}/status")
@router.patch(
route_builder.build_nested_resource_route("purchase-orders", "po_id", "deliveries") + "/{delivery_id}/status"
)
async def update_delivery_status(
tenant_id: str,
po_id: str,
delivery_id: str,
status: str = Query(..., description="New delivery status"),
tenant_id: str = Path(..., description="Tenant ID"),
service: PurchaseOrderService = Depends(get_po_service)
):
"""
@@ -421,11 +452,15 @@ async def update_delivery_status(
# INVOICE MANAGEMENT
# ================================================================
@router.post("/{po_id}/invoices", response_model=SupplierInvoiceResponse, status_code=201)
@router.post(
route_builder.build_nested_resource_route("purchase-orders", "po_id", "invoices"),
response_model=SupplierInvoiceResponse,
status_code=201
)
async def create_invoice(
tenant_id: str,
po_id: str,
invoice_data: SupplierInvoiceCreate,
tenant_id: str = Path(..., description="Tenant ID"),
service: PurchaseOrderService = Depends(get_po_service)
):
"""