from typing import Optional from fastapi import APIRouter, Query, Request from app.modules.also.backend.service import also_service from app.modules.also.models.schemas import ( AlsoApproveResult, AlsoCompanyMappingUpsert, AlsoDifferenceItem, AlsoDashboardSummaryResponse, AlsoImportJobCreate, AlsoImportJobResponse, AlsoImportLinesRequest, AlsoProductMappingUpsert, AlsoQueueApproveRequest, AlsoQueueLineResponse, AlsoQueueProcessRequest, AlsoQueueProcessResult, ) router = APIRouter() def _user_id_from_request(request: Request) -> Optional[int]: raw_user_id = getattr(request.state, "user_id", None) if raw_user_id is None: return None try: return int(raw_user_id) except (TypeError, ValueError): return None @router.get("/also/config") async def also_config() -> dict: return also_service.get_config() @router.post("/also/import-jobs", response_model=AlsoImportJobResponse) async def create_import_job(payload: AlsoImportJobCreate, request: Request): return also_service.create_import_job(payload, _user_id_from_request(request)) @router.get("/also/import-jobs", response_model=list[AlsoImportJobResponse]) async def list_import_jobs( status: Optional[str] = Query(default=None), limit: int = Query(default=100, ge=1, le=500), ): return also_service.list_import_jobs(status=status, limit=limit) @router.get("/also/import-jobs/{job_id}", response_model=AlsoImportJobResponse) async def get_import_job(job_id: int): return also_service.get_import_job(job_id) @router.post("/also/import-jobs/{job_id}/lines") async def import_lines(job_id: int, payload: AlsoImportLinesRequest): return also_service.import_lines(job_id=job_id, payload=payload) @router.get("/also/queue", response_model=list[AlsoQueueLineResponse]) async def get_queue( status: Optional[str] = Query(default=None), limit: int = Query(default=200, ge=1, le=1000), ): return also_service.get_queue(status=status, limit=limit) @router.get("/also/dashboard/summary", response_model=AlsoDashboardSummaryResponse) async def get_dashboard_summary(): return also_service.get_dashboard_summary() @router.get("/also/dashboard/differences", response_model=list[AlsoDifferenceItem]) async def get_dashboard_differences(limit: int = Query(default=50, ge=1, le=200)): return also_service.get_monthly_differences(limit=limit) @router.post("/also/queue/run-matching", response_model=AlsoQueueProcessResult) async def run_matching(payload: AlsoQueueProcessRequest): return also_service.run_matching( import_job_id=payload.import_job_id, line_ids=payload.line_ids, limit=payload.limit, ) @router.post("/also/queue/run-validation", response_model=AlsoQueueProcessResult) async def run_validation(payload: AlsoQueueProcessRequest): return also_service.run_validation( import_job_id=payload.import_job_id, line_ids=payload.line_ids, limit=payload.limit, ) @router.post("/also/queue/approve", response_model=AlsoApproveResult) async def approve_queue(payload: AlsoQueueApproveRequest, request: Request): return also_service.approve_lines_to_drafts( import_job_id=payload.import_job_id, line_ids=payload.line_ids, approved_by_user_id=_user_id_from_request(request), ) @router.put("/also/mappings/company") async def upsert_company_mapping(payload: AlsoCompanyMappingUpsert): return also_service.upsert_company_mapping(payload) @router.put("/also/mappings/product") async def upsert_product_mapping(payload: AlsoProductMappingUpsert): return also_service.upsert_product_mapping(payload)