from fastapi import APIRouter, Depends, HTTPException from fastapi.responses import Response from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.db.models.order import Order from app.db.models.order_line import OrderLine from app.db.models.tenant import Tenant from app.db.models.vehicle import Vehicle from app.db.session import get_db from app.deps import get_tenant_id from app.orders import schemas, service from app.pdf.service import generate_deviz router = APIRouter() @router.get("") async def list_orders( tenant_id: str = Depends(get_tenant_id), db: AsyncSession = Depends(get_db), ): return await service.list_orders(db, tenant_id) @router.post("") async def create_order( data: schemas.CreateOrderRequest, tenant_id: str = Depends(get_tenant_id), db: AsyncSession = Depends(get_db), ): order = await service.create_order( db, tenant_id, data.vehicle_id, data.tip_deviz_id, data.km_intrare, data.observatii, ) return {"id": order.id} @router.get("/{order_id}") async def get_order( order_id: str, tenant_id: str = Depends(get_tenant_id), db: AsyncSession = Depends(get_db), ): result = await service.get_order(db, tenant_id, order_id) if not result: raise HTTPException(status_code=404, detail="Order not found") return result @router.post("/{order_id}/lines") async def add_line( order_id: str, data: schemas.AddLineRequest, tenant_id: str = Depends(get_tenant_id), db: AsyncSession = Depends(get_db), ): try: line = await service.add_line( db, tenant_id, order_id, data.tip, data.descriere, data.ore, data.pret_ora, data.cantitate, data.pret_unitar, data.um, ) return {"id": line.id} except ValueError as e: raise HTTPException(status_code=422, detail=str(e)) @router.post("/{order_id}/validate") async def validate_order( order_id: str, tenant_id: str = Depends(get_tenant_id), db: AsyncSession = Depends(get_db), ): try: order = await service.validate_order(db, tenant_id, order_id) return {"status": order.status} except ValueError as e: raise HTTPException(status_code=422, detail=str(e)) @router.get("/{order_id}/pdf/deviz") async def get_deviz_pdf( order_id: str, tenant_id: str = Depends(get_tenant_id), db: AsyncSession = Depends(get_db), ): r = await db.execute( select(Order).where(Order.id == order_id, Order.tenant_id == tenant_id) ) order = r.scalar_one_or_none() if not order: raise HTTPException(status_code=404, detail="Order not found") r = await db.execute(select(Vehicle).where(Vehicle.id == order.vehicle_id)) vehicle = r.scalar_one_or_none() r = await db.execute(select(Tenant).where(Tenant.id == tenant_id)) tenant = r.scalar_one() r = await db.execute( select(OrderLine).where(OrderLine.order_id == order.id) ) lines = r.scalars().all() order_data = { "id": order.id, "data_comanda": order.data_comanda, "nr_auto": vehicle.nr_inmatriculare if vehicle else "", "client_nume": vehicle.client_nume if vehicle else "", "marca_denumire": "", "model_denumire": "", "total_manopera": order.total_manopera, "total_materiale": order.total_materiale, "total_general": order.total_general, } tenant_data = { "nume": tenant.nume, "cui": tenant.cui, "adresa": tenant.adresa, "telefon": tenant.telefon, } lines_data = [ { "tip": l.tip, "descriere": l.descriere, "ore": l.ore, "pret_ora": l.pret_ora, "cantitate": l.cantitate, "pret_unitar": l.pret_unitar, "um": l.um, "total": l.total, } for l in lines ] pdf_bytes = generate_deviz(order_data, lines_data, tenant_data) return Response( content=pdf_bytes, media_type="application/pdf", headers={ "Content-Disposition": f'inline; filename="deviz-{order.id[:8]}.pdf"' }, )