from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form from prisma import Prisma from typing import List, Optional from datetime import datetime from pathlib import Path from app.models.albaran import AlbaranCreate, AlbaranUpdate, AlbaranResponse from app.api.dependencies import get_prisma from app.config import settings from app.services.albaran_processor import AlbaranProcessor router = APIRouter(prefix="/albaranes", tags=["albaranes"]) @router.get("/", response_model=List[AlbaranResponse]) async def listar_albaranes( skip: int = 0, limit: int = 100, estado_procesado: Optional[str] = None, db: Prisma = Depends(get_prisma) ): """Listar todos los albaranes""" where = {} if estado_procesado: where["estadoProcesado"] = estado_procesado albaranes = await db.albaran.find_many( where=where, skip=skip, take=limit, include={"proveedor": True, "referencias": True}, order_by={"createdAt": "desc"} ) return albaranes @router.get("/{albaran_id}", response_model=AlbaranResponse) async def obtener_albaran( albaran_id: int, db: Prisma = Depends(get_prisma) ): """Obtener un albarán por ID""" albaran = await db.albaran.find_unique( where={"id": albaran_id}, include={"proveedor": True, "referencias": True} ) if not albaran: raise HTTPException(status_code=404, detail="Albarán no encontrado") return albaran @router.post("/upload", response_model=AlbaranResponse, status_code=201) async def subir_albaran( archivo: UploadFile = File(...), db: Prisma = Depends(get_prisma) ): """Subir un albarán desde móvil o web""" # Guardar archivo upload_dir = settings.ALBARANES_ESCANEADOS_DIR file_path = upload_dir / archivo.filename with open(file_path, "wb") as f: content = await archivo.read() f.write(content) # Procesar try: processor = AlbaranProcessor(db) albaran = await processor.process_albaran_file(file_path) return albaran except Exception as e: raise HTTPException(status_code=400, detail=str(e)) @router.post("/{albaran_id}/vincular-proveedor", response_model=AlbaranResponse) async def vincular_proveedor( albaran_id: int, proveedor_id: int = Query(...), db: Prisma = Depends(get_prisma) ): """Vincula un albarán a un proveedor manualmente""" albaran = await db.albaran.find_unique(where={"id": albaran_id}) if not albaran: raise HTTPException(status_code=404, detail="Albarán no encontrado") proveedor = await db.proveedor.find_unique(where={"id": proveedor_id}) if not proveedor: raise HTTPException(status_code=404, detail="Proveedor no encontrado") albaran_actualizado = await db.albaran.update( where={"id": albaran_id}, data={ "proveedorId": proveedor_id, "estadoProcesado": "procesado", "fechaProcesado": datetime.now() }, include={"proveedor": True, "referencias": True} ) # Reprocesar para vincular referencias processor = AlbaranProcessor(db) await processor.match_and_update_referencias(albaran_actualizado) return albaran_actualizado