from fastapi import APIRouter, Query, Request, UploadFile, File from fastapi.responses import StreamingResponse, HTMLResponse from fastapi.templating import Jinja2Templates from pydantic import BaseModel from pathlib import Path from typing import Optional import io from ..services import mapping_service, sqlite_service router = APIRouter(tags=["mappings"]) templates = Jinja2Templates(directory=str(Path(__file__).parent.parent / "templates")) class MappingCreate(BaseModel): sku: str codmat: str cantitate_roa: float = 1 procent_pret: float = 100 class MappingUpdate(BaseModel): cantitate_roa: Optional[float] = None procent_pret: Optional[float] = None activ: Optional[int] = None # HTML page @router.get("/mappings", response_class=HTMLResponse) async def mappings_page(request: Request): return templates.TemplateResponse("mappings.html", {"request": request}) # API endpoints @router.get("/api/mappings") def list_mappings(search: str = "", page: int = 1, per_page: int = 50): return mapping_service.get_mappings(search=search, page=page, per_page=per_page) @router.post("/api/mappings") async def create_mapping(data: MappingCreate): try: result = mapping_service.create_mapping(data.sku, data.codmat, data.cantitate_roa, data.procent_pret) # Mark SKU as resolved in missing_skus tracking await sqlite_service.resolve_missing_sku(data.sku) return {"success": True, **result} except Exception as e: return {"success": False, "error": str(e)} @router.put("/api/mappings/{sku}/{codmat}") def update_mapping(sku: str, codmat: str, data: MappingUpdate): try: updated = mapping_service.update_mapping(sku, codmat, data.cantitate_roa, data.procent_pret, data.activ) return {"success": updated} except Exception as e: return {"success": False, "error": str(e)} @router.delete("/api/mappings/{sku}/{codmat}") def delete_mapping(sku: str, codmat: str): try: deleted = mapping_service.delete_mapping(sku, codmat) return {"success": deleted} except Exception as e: return {"success": False, "error": str(e)} @router.post("/api/mappings/import-csv") async def import_csv(file: UploadFile = File(...)): content = await file.read() text = content.decode("utf-8-sig") result = mapping_service.import_csv(text) return result @router.get("/api/mappings/export-csv") def export_csv(): csv_content = mapping_service.export_csv() return StreamingResponse( io.BytesIO(csv_content.encode("utf-8-sig")), media_type="text/csv", headers={"Content-Disposition": "attachment; filename=mappings.csv"} ) @router.get("/api/mappings/csv-template") def csv_template(): content = mapping_service.get_csv_template() return StreamingResponse( io.BytesIO(content.encode("utf-8-sig")), media_type="text/csv", headers={"Content-Disposition": "attachment; filename=mappings_template.csv"} )