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

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 

7 

8class ReporteService: 

9 def __init__(self, dbSession): 

10 self.dbSession = dbSession 

11 self.repo = ReporteRepository(dbSession) 

12 

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)) 

20 

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)) 

43 

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)) 

67 

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))