Coverage for backend \ app \ Reportes \ services \ reporteService.py: 100.00%
51 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-29 16:13 -0500
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-29 16:13 -0500
1from app.Reportes.repositories.reporteRepository import ReporteRepository
2from app.Reportes.schemas.reporteSchemas import *
3from app.configuracionGeneral.schemasGenerales import respuestaApi
4from fastapi import HTTPException
5from datetime import datetime
6from app.Inventario.schemas.inventarioSchemas import InventarioRespuestaSchema
8class ReporteService:
9 def __init__(self, dbSession):
10 self.dbSession = dbSession
11 self.repo = ReporteRepository(dbSession)
13 def reporteInventario(self, filtro: InventarioFiltro, usuario: dict):
14 rol = usuario.get('rol')
15 if rol not in ["Administrador", "Bodeguero"]:
16 raise HTTPException(status_code=403, detail="No tienes permiso para generar este reporte")
17 invs = self.repo.reporte_inventario(idProducto=filtro.idProducto, idCategoria=filtro.idCategoria, nombreProducto=filtro.nombreProducto)
18 items = [InventarioRespuestaSchema.from_orm(inv) for inv in invs]
19 return respuestaApi(success=True, message="Reporte de inventario generado", data=InventarioReporteRespuesta(items=items))
21 def reporteVentasProductoCategoria(self, filtro: VentasFiltro, usuario: dict):
22 rol = usuario.get('rol')
23 if rol != "Administrador":
24 raise HTTPException(status_code=403, detail="Solo Administrador puede generar este reporte")
25 # Validar fechas obligatorias
26 if not filtro.fechaInicio or not filtro.fechaFin:
27 raise HTTPException(status_code=400, detail="fechaInicio y fechaFin son obligatorias")
28 # Requerir idProducto o idCategoria
29 if filtro.idProducto is None and filtro.idCategoria is None:
30 raise HTTPException(status_code=400, detail="Debe proporcionar idProducto o idCategoria")
31 rows = self.repo.reporte_ventas_por_producto_categoria(filtro.fechaInicio, filtro.fechaFin, filtro.idProducto, filtro.idCategoria)
32 items = []
33 for r in rows:
34 items.append(VentasPorProductoItem(
35 idProducto=r.idProducto,
36 nombreProducto=r.nombreProducto,
37 idCategoria=r.idCategoriaProducto,
38 nombreCategoria=r.nombreCategoria,
39 cantidadVendida=int(r.cantidadVendida or 0),
40 ingresos=float(round(r.ingresos or 0.0,2))
41 ))
42 return respuestaApi(success=True, message="Reporte de ventas por producto/categoría generado", data=VentasReporteRespuesta(items=items))
44 def resumenCajaDiaria(self, fecha: datetime.date, idUsuarioCaja: int | None, usuario: dict):
45 rol = usuario.get('rol')
46 if rol != "Administrador":
47 raise HTTPException(status_code=403, detail="Solo Administrador puede generar este reporte")
48 if idUsuarioCaja is None:
49 raise HTTPException(status_code=400, detail="idUsuarioCaja es obligatorio")
50 cajas = self.repo.resumen_caja_diaria(fecha, idUsuarioCaja)
51 items = []
52 for c in cajas:
53 ventas = getattr(c, 'ventas', []) or []
54 items.append(ResumenCajaItem(
55 idCaja=c.idCaja,
56 usuario=(UsuarioPublicoSchema.from_orm(c.usuario) if getattr(c, 'usuario', None) else None),
57 fechaAperturaCaja=c.fechaAperturaCaja,
58 fechaCierreCaja=c.fechaCierreCaja,
59 montoInicialDeclarado=c.montoInicialDeclarado or 0.0,
60 montoCierreDeclarado=c.montoCierreDeclarado,
61 montoCierreSistema=c.montoCierreSistema,
62 diferenciaCaja=c.diferenciaCaja,
63 estadoCaja=c.estadoCaja,
64 ventas=[VentaRespuestaSchema.from_orm(v) for v in ventas]
65 ))
66 return respuestaApi(success=True, message="Resumen de caja generado", data=ResumenCajaRespuesta(items=items))
68 def clientesFrecuentes(self, filtro: ClientesFiltro, usuario: dict):
69 rol = usuario.get('rol')
70 if rol != "Administrador":
71 raise HTTPException(status_code=403, detail="Solo Administrador puede generar este reporte")
72 rows = self.repo.clientes_frecuentes(dias=filtro.dias, minVentas=filtro.minVentas, minGasto=filtro.minGasto)
73 items = []
74 for r in rows:
75 items.append(ClienteFrecuenteItem(
76 cliente=ClienteRespuestaSchema.from_orm(r['cliente']),
77 ventasCount=int(r['ventasCount']),
78 totalGastado=float(round(r['totalGastado'] or 0.0,2)),
79 historialVentas=[VentaRespuestaSchema.from_orm(v) for v in r['historial']]
80 ))
81 return respuestaApi(success=True, message="Reporte de clientes frecuentes generado", data=ClientesFrecuentesRespuesta(items=items))