2025-08-08 09:48:15 -03:00
using GestionIntegral.Api.Data.Repositories.Distribucion ;
2025-05-27 11:21:00 -03:00
using GestionIntegral.Api.Data.Repositories.Reportes ;
2025-08-08 09:48:15 -03:00
using GestionIntegral.Api.Data.Repositories.Suscripciones ;
2025-05-27 11:21:00 -03:00
using GestionIntegral.Api.Dtos.Reportes ;
namespace GestionIntegral.Api.Services.Reportes
{
public class ReportesService : IReportesService
{
private readonly IReportesRepository _reportesRepository ;
2025-08-08 09:48:15 -03:00
private readonly IFacturaRepository _facturaRepository ;
private readonly IFacturaDetalleRepository _facturaDetalleRepository ;
private readonly IPublicacionRepository _publicacionRepository ;
private readonly IEmpresaRepository _empresaRepository ;
private readonly ISuscriptorRepository _suscriptorRepository ;
private readonly ISuscripcionRepository _suscripcionRepository ;
2025-05-27 11:21:00 -03:00
private readonly ILogger < ReportesService > _logger ;
2025-08-08 09:48:15 -03:00
public ReportesService ( IReportesRepository reportesRepository , IFacturaRepository facturaRepository , IFacturaDetalleRepository facturaDetalleRepository , IPublicacionRepository publicacionRepository , IEmpresaRepository empresaRepository
, ISuscriptorRepository suscriptorRepository , ISuscripcionRepository suscripcionRepository , ILogger < ReportesService > logger )
2025-05-27 11:21:00 -03:00
{
_reportesRepository = reportesRepository ;
2025-08-08 09:48:15 -03:00
_facturaRepository = facturaRepository ;
_facturaDetalleRepository = facturaDetalleRepository ;
_publicacionRepository = publicacionRepository ;
_empresaRepository = empresaRepository ;
_suscriptorRepository = suscriptorRepository ;
_suscripcionRepository = suscripcionRepository ;
2025-05-27 11:21:00 -03:00
_logger = logger ;
}
public async Task < ( IEnumerable < ExistenciaPapelDto > Data , string? Error ) > ObtenerExistenciaPapelAsync (
2025-05-27 18:17:56 -03:00
DateTime fechaDesde , DateTime fechaHasta , int? idPlanta , bool consolidado )
2025-05-27 11:21:00 -03:00
{
if ( fechaDesde > fechaHasta )
{
return ( Enumerable . Empty < ExistenciaPapelDto > ( ) , "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'." ) ;
}
if ( ! consolidado & & ! idPlanta . HasValue )
{
return ( Enumerable . Empty < ExistenciaPapelDto > ( ) , "Se requiere un ID de planta para reportes no consolidados." ) ;
}
try
{
var dataFromRepo = await _reportesRepository . GetExistenciaPapelAsync ( fechaDesde , fechaHasta , idPlanta , consolidado ) ;
var dataWithUtcDates = dataFromRepo . Select ( dto = >
{
if ( dto . FechaEstimacionFinStock . HasValue )
{
dto . FechaEstimacionFinStock = DateTime . SpecifyKind ( dto . FechaEstimacionFinStock . Value . Date , DateTimeKind . Utc ) ;
}
return dto ;
} ) . ToList ( ) ;
return ( dataWithUtcDates , null ) ;
}
2025-05-27 18:17:56 -03:00
catch ( ArgumentNullException ex ) when ( ex . ParamName = = "idPlanta" )
2025-05-27 11:21:00 -03:00
{
_logger . LogWarning ( ex , "ArgumentNullException para idPlanta en ObtenerExistenciaPapelAsync." ) ;
2025-05-27 18:17:56 -03:00
return ( Enumerable . Empty < ExistenciaPapelDto > ( ) , ex . Message ) ;
2025-05-27 11:21:00 -03:00
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Existencia de Papel." ) ;
2025-05-27 18:17:56 -03:00
return ( Enumerable . Empty < ExistenciaPapelDto > ( ) , "Error interno al generar el reporte de existencia de papel." ) ;
}
}
public async Task < ( IEnumerable < MovimientoBobinasDto > Data , string? Error ) > ObtenerMovimientoBobinasAsync ( DateTime fechaDesde , DateTime fechaHasta , int idPlanta )
{
if ( fechaDesde > fechaHasta )
{
return ( Enumerable . Empty < MovimientoBobinasDto > ( ) , "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'." ) ;
}
2025-05-28 16:01:59 -03:00
int diasPeriodo = ( fechaHasta . Date - fechaDesde . Date ) . Days + 1 ;
2025-05-27 18:17:56 -03:00
try
{
var data = await _reportesRepository . GetMovimientoBobinasAsync ( fechaDesde . Date , diasPeriodo , idPlanta ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Movimiento de Bobinas." ) ;
return ( Enumerable . Empty < MovimientoBobinasDto > ( ) , "Error interno al generar el reporte de movimiento de bobinas." ) ;
}
}
public async Task < ( IEnumerable < MovimientoBobinaEstadoDetalleDto > Detalle , IEnumerable < MovimientoBobinaEstadoTotalDto > Totales , string? Error ) > ObtenerMovimientoBobinasPorEstadoAsync ( DateTime fechaDesde , DateTime fechaHasta , int idPlanta )
{
if ( fechaDesde > fechaHasta )
{
return ( Enumerable . Empty < MovimientoBobinaEstadoDetalleDto > ( ) , Enumerable . Empty < MovimientoBobinaEstadoTotalDto > ( ) , "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'." ) ;
}
try
{
var detalle = await _reportesRepository . GetMovimientoBobinasEstadoDetalleAsync ( fechaDesde . Date , fechaHasta . Date , idPlanta ) ;
var totales = await _reportesRepository . GetMovimientoBobinasEstadoTotalesAsync ( fechaDesde . Date , fechaHasta . Date , idPlanta ) ;
2025-05-28 16:01:59 -03:00
var detalleUtc = detalle . Select ( d = >
{
2025-05-27 18:17:56 -03:00
d . FechaMovimiento = DateTime . SpecifyKind ( d . FechaMovimiento , DateTimeKind . Utc ) ;
return d ;
} ) . ToList ( ) ;
return ( detalleUtc , totales , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Movimiento de Bobinas por Estado." ) ;
return ( Enumerable . Empty < MovimientoBobinaEstadoDetalleDto > ( ) , Enumerable . Empty < MovimientoBobinaEstadoTotalDto > ( ) , "Error interno al generar el reporte de movimiento de bobinas por estado." ) ;
2025-05-27 11:21:00 -03:00
}
}
2025-05-27 18:17:56 -03:00
public async Task < ( IEnumerable < ListadoDistribucionGeneralResumenDto > Resumen , IEnumerable < ListadoDistribucionGeneralPromedioDiaDto > Promedios , string? Error ) > ObtenerListadoDistribucionGeneralAsync ( int idPublicacion , DateTime fechaDesde , DateTime fechaHasta )
{
if ( fechaDesde > fechaHasta )
return ( Enumerable . Empty < ListadoDistribucionGeneralResumenDto > ( ) , Enumerable . Empty < ListadoDistribucionGeneralPromedioDiaDto > ( ) , "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'." ) ;
try
{
// El SP SP_DistObtenerResumenMensual usa Mes y Año de fechaDesde.
// El SP SP_DistObtenerResumenMensualPorDiaSemana también.
var resumenData = await _reportesRepository . GetListadoDistribucionGeneralResumenAsync ( idPublicacion , fechaDesde , fechaHasta ) ;
var promediosData = await _reportesRepository . GetListadoDistribucionGeneralPromedioDiaAsync ( idPublicacion , fechaDesde , fechaHasta ) ;
2025-05-28 16:01:59 -03:00
2025-05-27 18:17:56 -03:00
var resumenUtc = resumenData . Select ( r = > { r . Fecha = DateTime . SpecifyKind ( r . Fecha , DateTimeKind . Utc ) ; return r ; } ) . ToList ( ) ;
2025-05-27 11:21:00 -03:00
2025-05-27 18:17:56 -03:00
return ( resumenUtc , promediosData , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Listado Distribucion General." ) ;
return ( Enumerable . Empty < ListadoDistribucionGeneralResumenDto > ( ) , Enumerable . Empty < ListadoDistribucionGeneralPromedioDiaDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
public async Task < ( IEnumerable < ListadoDistribucionCanillasSimpleDto > Simple , IEnumerable < ListadoDistribucionCanillasPromedioDiaDto > Promedios , string? Error ) > ObtenerListadoDistribucionCanillasAsync ( int idPublicacion , DateTime fechaDesde , DateTime fechaHasta )
{
if ( fechaDesde > fechaHasta )
return ( Enumerable . Empty < ListadoDistribucionCanillasSimpleDto > ( ) , Enumerable . Empty < ListadoDistribucionCanillasPromedioDiaDto > ( ) , "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'." ) ;
2025-05-28 16:01:59 -03:00
2025-05-27 18:17:56 -03:00
try
{
var simpleData = await _reportesRepository . GetListadoDistribucionCanillasSimpleAsync ( idPublicacion , fechaDesde , fechaHasta ) ;
var promediosData = await _reportesRepository . GetListadoDistribucionCanillasPromedioDiaAsync ( idPublicacion , fechaDesde , fechaHasta ) ;
return ( simpleData , promediosData , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Listado Distribucion Canillas." ) ;
return ( Enumerable . Empty < ListadoDistribucionCanillasSimpleDto > ( ) , Enumerable . Empty < ListadoDistribucionCanillasPromedioDiaDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
2025-05-28 16:01:59 -03:00
2025-05-27 18:17:56 -03:00
public async Task < ( IEnumerable < ListadoDistribucionCanillasImporteDto > Data , string? Error ) > ObtenerListadoDistribucionCanillasConImporteAsync ( int idPublicacion , DateTime fechaDesde , DateTime fechaHasta , bool esAccionista )
{
if ( fechaDesde > fechaHasta )
return ( Enumerable . Empty < ListadoDistribucionCanillasImporteDto > ( ) , "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'." ) ;
try
{
var data = await _reportesRepository . GetListadoDistribucionCanillasImporteAsync ( idPublicacion , fechaDesde , fechaHasta , esAccionista ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Listado Distribucion Canillas con Importe." ) ;
return ( Enumerable . Empty < ListadoDistribucionCanillasImporteDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
public async Task < ( IEnumerable < VentaMensualSecretariaElDiaDto > Data , string? Error ) > ObtenerVentaMensualSecretariaElDiaAsync ( DateTime fechaDesde , DateTime fechaHasta )
{
if ( fechaDesde > fechaHasta ) return ( Enumerable . Empty < VentaMensualSecretariaElDiaDto > ( ) , "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'." ) ;
try
{
var data = await _reportesRepository . GetVentaMensualSecretariaElDiaAsync ( fechaDesde , fechaHasta ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Venta Mensual Secretaria El Dia." ) ;
return ( Enumerable . Empty < VentaMensualSecretariaElDiaDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
public async Task < ( IEnumerable < VentaMensualSecretariaElPlataDto > Data , string? Error ) > ObtenerVentaMensualSecretariaElPlataAsync ( DateTime fechaDesde , DateTime fechaHasta )
{
if ( fechaDesde > fechaHasta ) return ( Enumerable . Empty < VentaMensualSecretariaElPlataDto > ( ) , "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'." ) ;
try
{
var data = await _reportesRepository . GetVentaMensualSecretariaElPlataAsync ( fechaDesde , fechaHasta ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Venta Mensual Secretaria El Plata." ) ;
return ( Enumerable . Empty < VentaMensualSecretariaElPlataDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
2025-05-28 16:01:59 -03:00
2025-05-27 18:17:56 -03:00
public async Task < ( IEnumerable < VentaMensualSecretariaTirDevoDto > Data , string? Error ) > ObtenerVentaMensualSecretariaTirDevoAsync ( DateTime fechaDesde , DateTime fechaHasta )
{
if ( fechaDesde > fechaHasta ) return ( Enumerable . Empty < VentaMensualSecretariaTirDevoDto > ( ) , "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'." ) ;
try
{
var data = await _reportesRepository . GetVentaMensualSecretariaTirDevoAsync ( fechaDesde , fechaHasta ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Venta Mensual Secretaria Tirada/Devolucion." ) ;
return ( Enumerable . Empty < VentaMensualSecretariaTirDevoDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
2025-05-28 16:01:59 -03:00
2025-05-27 18:17:56 -03:00
public async Task < (
2025-06-24 12:52:37 -03:00
IEnumerable < DetalleDistribucionCanillaDto > Canillas ,
IEnumerable < DetalleDistribucionCanillaDto > CanillasAcc ,
IEnumerable < DetalleDistribucionCanillaAllDto > CanillasAll ,
IEnumerable < DetalleDistribucionCanillaDto > CanillasFechaLiq ,
IEnumerable < DetalleDistribucionCanillaDto > CanillasAccFechaLiq ,
IEnumerable < ObtenerCtrlDevolucionesDto > CtrlDevolucionesRemitos ,
IEnumerable < ControlDevolucionesReporteDto > CtrlDevolucionesParaDistCan ,
IEnumerable < DevueltosOtrosDiasDto > CtrlDevolucionesOtrosDias ,
string? Error
) > ObtenerReporteDistribucionCanillasAsync ( DateTime fecha , int idEmpresa )
2025-05-27 18:17:56 -03:00
{
try
{
var canillasTask = _reportesRepository . GetDetalleDistribucionCanillasPubliAsync ( fecha , idEmpresa ) ;
var canillasAccTask = _reportesRepository . GetDetalleDistribucionCanillasAccPubliAsync ( fecha , idEmpresa ) ;
var canillasAllTask = _reportesRepository . GetDetalleDistribucionCanillasAllPubliAsync ( fecha , idEmpresa ) ;
var canillasFechaLiqTask = _reportesRepository . GetDetalleDistribucionCanillasPubliFechaLiqAsync ( fecha , idEmpresa ) ;
var canillasAccFechaLiqTask = _reportesRepository . GetDetalleDistribucionCanillasAccPubliFechaLiqAsync ( fecha , idEmpresa ) ;
2025-05-28 16:01:59 -03:00
var ctrlDevolucionesRemitosTask = _reportesRepository . GetReporteObtenerCtrlDevolucionesAsync ( fecha , idEmpresa ) ; // SP_ObtenerCtrlDevoluciones
var ctrlDevolucionesParaDistCanTask = _reportesRepository . GetReporteCtrlDevolucionesParaDistCanAsync ( fecha , idEmpresa ) ; // SP_DistCanillasCantidadEntradaSalida
var ctrlDevolucionesOtrosDiasTask = _reportesRepository . GetEntradaSalidaOtrosDiasAsync ( fecha , idEmpresa ) ; // SP_DistCanillasCantidadEntradaSalidaOtrosDias
await Task . WhenAll (
canillasTask , canillasAccTask , canillasAllTask ,
canillasFechaLiqTask , canillasAccFechaLiqTask ,
ctrlDevolucionesRemitosTask , ctrlDevolucionesParaDistCanTask ,
ctrlDevolucionesOtrosDiasTask
) ;
2025-05-27 18:17:56 -03:00
2025-06-24 12:52:37 -03:00
var detallesOriginales = await ctrlDevolucionesParaDistCanTask ? ? Enumerable . Empty < ControlDevolucionesReporteDto > ( ) ;
var detallesOrdenados = detallesOriginales . OrderBy ( d = > d . Tipo ) . ToList ( ) ;
2025-05-28 16:01:59 -03:00
Func < IEnumerable < DetalleDistribucionCanillaDto > , IEnumerable < DetalleDistribucionCanillaDto > > toUtc =
items = > items ? . Select ( c = > { if ( c . Fecha . HasValue ) c . Fecha = DateTime . SpecifyKind ( c . Fecha . Value . Date , DateTimeKind . Utc ) ; return c ; } ) . ToList ( )
2025-05-27 18:17:56 -03:00
? ? Enumerable . Empty < DetalleDistribucionCanillaDto > ( ) ;
return (
toUtc ( await canillasTask ) ,
toUtc ( await canillasAccTask ) ,
await canillasAllTask ? ? Enumerable . Empty < DetalleDistribucionCanillaAllDto > ( ) ,
toUtc ( await canillasFechaLiqTask ) ,
toUtc ( await canillasAccFechaLiqTask ) ,
2025-05-28 16:01:59 -03:00
await ctrlDevolucionesRemitosTask ? ? Enumerable . Empty < ObtenerCtrlDevolucionesDto > ( ) ,
2025-06-24 12:52:37 -03:00
detallesOrdenados ,
2025-05-28 16:01:59 -03:00
await ctrlDevolucionesOtrosDiasTask ? ? Enumerable . Empty < DevueltosOtrosDiasDto > ( ) ,
2025-05-27 18:17:56 -03:00
null
) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Reporte Distribucion Canillas para fecha {Fecha} y empresa {IdEmpresa}." , fecha , idEmpresa ) ;
return (
Enumerable . Empty < DetalleDistribucionCanillaDto > ( ) ,
Enumerable . Empty < DetalleDistribucionCanillaDto > ( ) ,
Enumerable . Empty < DetalleDistribucionCanillaAllDto > ( ) ,
Enumerable . Empty < DetalleDistribucionCanillaDto > ( ) ,
Enumerable . Empty < DetalleDistribucionCanillaDto > ( ) ,
Enumerable . Empty < ObtenerCtrlDevolucionesDto > ( ) ,
Enumerable . Empty < ControlDevolucionesReporteDto > ( ) ,
2025-05-28 16:01:59 -03:00
Enumerable . Empty < DevueltosOtrosDiasDto > ( ) ,
2025-05-27 18:17:56 -03:00
"Error interno al generar el reporte de distribución de canillas."
) ;
}
}
public async Task < ( IEnumerable < TiradasPublicacionesSeccionesDto > Data , string? Error ) > ObtenerTiradasPublicacionesSeccionesAsync ( int idPublicacion , DateTime fechaDesde , DateTime fechaHasta , int idPlanta )
{
if ( fechaDesde > fechaHasta ) return ( Enumerable . Empty < TiradasPublicacionesSeccionesDto > ( ) , "Fecha 'Desde' no puede ser mayor que 'Hasta'." ) ;
try
{
var data = await _reportesRepository . GetTiradasPublicacionesSeccionesAsync ( idPublicacion , fechaDesde , fechaHasta , idPlanta ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Tiradas por Publicación y Secciones." ) ;
return ( Enumerable . Empty < TiradasPublicacionesSeccionesDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
public async Task < ( IEnumerable < TiradasPublicacionesSeccionesDto > Data , string? Error ) > ObtenerTiradasPublicacionesSeccionesConsolidadoAsync ( int idPublicacion , DateTime fechaDesde , DateTime fechaHasta )
{
if ( fechaDesde > fechaHasta ) return ( Enumerable . Empty < TiradasPublicacionesSeccionesDto > ( ) , "Fecha 'Desde' no puede ser mayor que 'Hasta'." ) ;
try
{
var data = await _reportesRepository . GetTiradasPublicacionesSeccionesConsolidadoAsync ( idPublicacion , fechaDesde , fechaHasta ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Tiradas por Publicación y Secciones (Consolidado)." ) ;
return ( Enumerable . Empty < TiradasPublicacionesSeccionesDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
public async Task < ( IEnumerable < ConsumoBobinasSeccionDto > Data , string? Error ) > ObtenerConsumoBobinasPorSeccionAsync ( DateTime fechaDesde , DateTime fechaHasta , int idPlanta )
{
if ( fechaDesde > fechaHasta ) return ( Enumerable . Empty < ConsumoBobinasSeccionDto > ( ) , "Fecha 'Desde' no puede ser mayor que 'Hasta'." ) ;
try
{
var data = await _reportesRepository . GetConsumoBobinasPorSeccionAsync ( fechaDesde , fechaHasta , idPlanta ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Consumo de Bobinas por Sección." ) ;
return ( Enumerable . Empty < ConsumoBobinasSeccionDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
public async Task < ( IEnumerable < ConsumoBobinasSeccionDto > Data , string? Error ) > ObtenerConsumoBobinasPorSeccionConsolidadoAsync ( DateTime fechaDesde , DateTime fechaHasta )
{
if ( fechaDesde > fechaHasta ) return ( Enumerable . Empty < ConsumoBobinasSeccionDto > ( ) , "Fecha 'Desde' no puede ser mayor que 'Hasta'." ) ;
try
{
var data = await _reportesRepository . GetConsumoBobinasPorSeccionConsolidadoAsync ( fechaDesde , fechaHasta ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Consumo de Bobinas por Sección (Consolidado)." ) ;
return ( Enumerable . Empty < ConsumoBobinasSeccionDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
public async Task < ( IEnumerable < ConsumoBobinasPublicacionDto > Data , string? Error ) > ObtenerConsumoBobinasPorPublicacionAsync ( DateTime fechaDesde , DateTime fechaHasta )
{
if ( fechaDesde > fechaHasta ) return ( Enumerable . Empty < ConsumoBobinasPublicacionDto > ( ) , "Fecha 'Desde' no puede ser mayor que 'Hasta'." ) ;
try
{
var data = await _reportesRepository . GetConsumoBobinasPorPublicacionAsync ( fechaDesde , fechaHasta ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Consumo de Bobinas por Publicación." ) ;
return ( Enumerable . Empty < ConsumoBobinasPublicacionDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
public async Task < ( IEnumerable < ComparativaConsumoBobinasDto > Data , string? Error ) > ObtenerComparativaConsumoBobinasAsync ( DateTime fechaInicioMesA , DateTime fechaFinMesA , DateTime fechaInicioMesB , DateTime fechaFinMesB , int idPlanta )
{
if ( fechaInicioMesA > fechaFinMesA | | fechaInicioMesB > fechaFinMesB ) return ( Enumerable . Empty < ComparativaConsumoBobinasDto > ( ) , "Fechas de inicio no pueden ser mayores que las de fin para los meses." ) ;
try
{
var data = await _reportesRepository . GetComparativaConsumoBobinasAsync ( fechaInicioMesA , fechaFinMesA , fechaInicioMesB , fechaFinMesB , idPlanta ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Comparativa de Consumo de Bobinas." ) ;
return ( Enumerable . Empty < ComparativaConsumoBobinasDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
public async Task < ( IEnumerable < ComparativaConsumoBobinasDto > Data , string? Error ) > ObtenerComparativaConsumoBobinasConsolidadoAsync ( DateTime fechaInicioMesA , DateTime fechaFinMesA , DateTime fechaInicioMesB , DateTime fechaFinMesB )
{
if ( fechaInicioMesA > fechaFinMesA | | fechaInicioMesB > fechaFinMesB ) return ( Enumerable . Empty < ComparativaConsumoBobinasDto > ( ) , "Fechas de inicio no pueden ser mayores que las de fin para los meses." ) ;
try
{
var data = await _reportesRepository . GetComparativaConsumoBobinasConsolidadoAsync ( fechaInicioMesA , fechaFinMesA , fechaInicioMesB , fechaFinMesB ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Comparativa de Consumo de Bobinas (Consolidado)." ) ;
return ( Enumerable . Empty < ComparativaConsumoBobinasDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
// Implementación para ReporteCuentasDistribuidores
public async Task < (
IEnumerable < BalanceCuentaDistDto > EntradasSalidas ,
IEnumerable < BalanceCuentaDebCredDto > DebitosCreditos ,
IEnumerable < BalanceCuentaPagosDto > Pagos ,
IEnumerable < SaldoDto > Saldos ,
string? Error
) > ObtenerReporteCuentasDistribuidorAsync ( int idDistribuidor , int idEmpresa , DateTime fechaDesde , DateTime fechaHasta )
{
2025-05-28 16:01:59 -03:00
if ( fechaDesde > fechaHasta )
2025-05-27 18:17:56 -03:00
return ( Enumerable . Empty < BalanceCuentaDistDto > ( ) , Enumerable . Empty < BalanceCuentaDebCredDto > ( ) , Enumerable . Empty < BalanceCuentaPagosDto > ( ) , Enumerable . Empty < SaldoDto > ( ) , "Fecha 'Desde' no puede ser mayor que 'Hasta'." ) ;
try
{
var esTask = _reportesRepository . GetBalanceCuentaDistEntradaSalidaPorEmpresaAsync ( idDistribuidor , idEmpresa , fechaDesde , fechaHasta ) ;
var dcTask = _reportesRepository . GetBalanceCuentDistDebCredEmpresaAsync ( idDistribuidor , idEmpresa , fechaDesde , fechaHasta ) ;
var paTask = _reportesRepository . GetBalanceCuentDistPagosEmpresaAsync ( idDistribuidor , idEmpresa , fechaDesde , fechaHasta ) ;
var saTask = _reportesRepository . GetBalanceCuentSaldosEmpresasAsync ( "Distribuidores" , idDistribuidor , idEmpresa ) ;
await Task . WhenAll ( esTask , dcTask , paTask , saTask ) ;
2025-05-28 16:01:59 -03:00
Func < IEnumerable < BalanceCuentaDistDto > , IEnumerable < BalanceCuentaDistDto > > esToUtc =
items = > items ? . Select ( i = > { i . Fecha = DateTime . SpecifyKind ( i . Fecha . Date , DateTimeKind . Utc ) ; return i ; } ) . ToList ( )
2025-05-27 18:17:56 -03:00
? ? Enumerable . Empty < BalanceCuentaDistDto > ( ) ;
2025-05-28 16:01:59 -03:00
Func < IEnumerable < BalanceCuentaDebCredDto > , IEnumerable < BalanceCuentaDebCredDto > > dcToUtc =
2025-05-27 18:17:56 -03:00
items = > items ? . Select ( i = > { i . Fecha = DateTime . SpecifyKind ( i . Fecha . Date , DateTimeKind . Utc ) ; return i ; } ) . ToList ( )
? ? Enumerable . Empty < BalanceCuentaDebCredDto > ( ) ;
2025-05-28 16:01:59 -03:00
Func < IEnumerable < BalanceCuentaPagosDto > , IEnumerable < BalanceCuentaPagosDto > > paToUtc =
2025-05-27 18:17:56 -03:00
items = > items ? . Select ( i = > { i . Fecha = DateTime . SpecifyKind ( i . Fecha . Date , DateTimeKind . Utc ) ; return i ; } ) . ToList ( )
? ? Enumerable . Empty < BalanceCuentaPagosDto > ( ) ;
return (
esToUtc ( await esTask ) ,
dcToUtc ( await dcTask ) ,
paToUtc ( await paTask ) ,
await saTask ? ? Enumerable . Empty < SaldoDto > ( ) ,
null
) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Reporte Cuentas Distribuidor." ) ;
return (
Enumerable . Empty < BalanceCuentaDistDto > ( ) ,
Enumerable . Empty < BalanceCuentaDebCredDto > ( ) ,
Enumerable . Empty < BalanceCuentaPagosDto > ( ) ,
Enumerable . Empty < SaldoDto > ( ) ,
"Error interno al generar el reporte."
) ;
}
}
2025-05-31 23:48:42 -03:00
public async Task < ( IEnumerable < ListadoDistribucionDistSimpleDto > Simple , IEnumerable < ListadoDistribucionDistPromedioDiaDto > Promedios , string? Error ) > ObtenerListadoDistribucionDistribuidoresAsync ( int idDistribuidor , int idPublicacion , DateTime fechaDesde , DateTime fechaHasta )
{
if ( fechaDesde > fechaHasta )
return ( Enumerable . Empty < ListadoDistribucionDistSimpleDto > ( ) , Enumerable . Empty < ListadoDistribucionDistPromedioDiaDto > ( ) , "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'." ) ;
try
{
// Llamar a los métodos específicos del repositorio
var simpleDataTask = _reportesRepository . GetListadoDistribucionDistSimpleAsync ( idDistribuidor , idPublicacion , fechaDesde , fechaHasta ) ;
var promediosDataTask = _reportesRepository . GetListadoDistribucionDistPromedioDiaAsync ( idDistribuidor , idPublicacion , fechaDesde , fechaHasta ) ;
await Task . WhenAll ( simpleDataTask , promediosDataTask ) ;
return ( await simpleDataTask , await promediosDataTask , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener Listado Distribucion (Distribuidores). Params: Dist={idDistribuidor}, Pub={idPublicacion}, Desde={fechaDesde}, Hasta={fechaHasta}" , idDistribuidor , idPublicacion , fechaDesde , fechaHasta ) ;
return ( Enumerable . Empty < ListadoDistribucionDistSimpleDto > ( ) , Enumerable . Empty < ListadoDistribucionDistPromedioDiaDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
2025-06-03 13:45:20 -03:00
public async Task < (
IEnumerable < LiquidacionCanillaDetalleDto > Detalles ,
IEnumerable < LiquidacionCanillaGananciaDto > Ganancias ,
string? Error
) > ObtenerDatosTicketLiquidacionAsync ( DateTime fecha , int idCanilla )
{
try
{
var detallesTask = _reportesRepository . GetLiquidacionCanillaDetalleAsync ( fecha , idCanilla ) ;
var gananciasTask = _reportesRepository . GetLiquidacionCanillaGananciasAsync ( fecha , idCanilla ) ;
await Task . WhenAll ( detallesTask , gananciasTask ) ;
var detalles = await detallesTask ;
var ganancias = await gananciasTask ;
if ( ( detalles = = null | | ! detalles . Any ( ) ) & & ( ganancias = = null | | ! ganancias . Any ( ) ) )
{
// Podrías optar por no devolver error aquí si es válido que uno de los dos esté vacío
// y manejarlo en el controlador o el RDLC.
}
// Convertir fechas a UTC si es necesario para el RDLC (aunque estos DTOs no tienen fechas)
return (
detalles ? ? Enumerable . Empty < LiquidacionCanillaDetalleDto > ( ) ,
ganancias ? ? Enumerable . Empty < LiquidacionCanillaGananciaDto > ( ) ,
null
) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ReportesService al obtener datos para Ticket Liquidación Canilla. Fecha: {Fecha}, Canilla: {IdCanilla}" , fecha , idCanilla ) ;
return (
Enumerable . Empty < LiquidacionCanillaDetalleDto > ( ) ,
Enumerable . Empty < LiquidacionCanillaGananciaDto > ( ) ,
"Error interno al obtener los datos para el ticket de liquidación."
) ;
}
}
2025-06-06 18:33:09 -03:00
public async Task < ( IEnumerable < ListadoDistCanMensualDiariosDto > Data , string? Error ) > ObtenerReporteMensualDiariosAsync ( DateTime fechaDesde , DateTime fechaHasta , bool esAccionista )
{
try
{
var data = await _reportesRepository . GetReporteMensualDiariosAsync ( fechaDesde , fechaHasta , esAccionista ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error al obtener reporte mensual canillitas (diarios)." ) ;
return ( Enumerable . Empty < ListadoDistCanMensualDiariosDto > ( ) , "Error al obtener datos del reporte (diarios)." ) ;
}
}
public async Task < ( IEnumerable < ListadoDistCanMensualPubDto > Data , string? Error ) > ObtenerReporteMensualPorPublicacionAsync ( DateTime fechaDesde , DateTime fechaHasta , bool esAccionista )
{
try
{
var data = await _reportesRepository . GetReporteMensualPorPublicacionAsync ( fechaDesde , fechaHasta , esAccionista ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error al obtener reporte mensual canillitas (por publicación)." ) ;
return ( Enumerable . Empty < ListadoDistCanMensualPubDto > ( ) , "Error al obtener datos del reporte (por publicación)." ) ;
}
}
2025-08-08 09:48:15 -03:00
public async Task < ( IEnumerable < FacturasParaReporteDto > Data , string? Error ) > ObtenerFacturasParaReportePublicidad ( int anio , int mes )
{
if ( anio < 2020 | | mes < 1 | | mes > 12 )
{
return ( Enumerable . Empty < FacturasParaReporteDto > ( ) , "Período no válido." ) ;
}
var periodo = $"{anio}-{mes:D2}" ;
try
{
// Llamada directa al nuevo método del repositorio
var data = await _reportesRepository . GetDatosReportePublicidadAsync ( periodo ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en servicio al obtener datos para reporte de publicidad para el período {Periodo}" , periodo ) ;
return ( new List < FacturasParaReporteDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
Feat: Implementa Reporte de Distribución de Suscripciones y Refactoriza Gestión de Ajustes
Se introduce una nueva funcionalidad de reporte crucial para la logística y se realiza una refactorización mayor del sistema de ajustes para garantizar la correcta imputación contable.
### ✨ Nuevas Características
- **Nuevo Reporte de Distribución de Suscripciones (RR011):**
- Se añade un nuevo reporte en PDF que genera un listado de todas las suscripciones activas en un rango de fechas.
- El reporte está diseñado para el equipo de reparto, incluyendo datos clave como nombre del suscriptor, dirección, teléfono, días de entrega y observaciones.
- Se implementa el endpoint, la lógica de servicio, la consulta a la base de datos y el template de QuestPDF en el backend.
- Se crea la página correspondiente en el frontend (React) con su selector de fechas y se añade la ruta y el enlace en el menú de reportes.
### 🔄 Refactorización Mayor
- **Asociación de Ajustes a Empresas:**
- Se refactoriza por completo la entidad `Ajuste` para incluir una referencia obligatoria a una `IdEmpresa`.
- **Motivo:** Corregir un error crítico en la lógica de negocio donde los ajustes de un suscriptor se aplicaban a la primera factura generada, sin importar a qué empresa correspondía el ajuste.
- Se provee un script de migración SQL para actualizar el esquema de la base de datos (`susc_Ajustes`).
- Se actualizan todos los DTOs, repositorios y servicios (backend) para manejar la nueva relación.
- Se modifica el `FacturacionService` para que ahora aplique los ajustes pendientes correspondientes a cada empresa dentro de su bucle de facturación.
- Se actualiza el formulario de creación/edición de ajustes en el frontend (React) para incluir un selector de empresa obligatorio.
### ⚡️ Optimizaciones de Rendimiento
- **Solución de N+1 Queries:**
- Se optimiza el método `ObtenerTodos` en `SuscriptorService` para obtener todas las formas de pago en una única consulta en lugar de una por cada suscriptor.
- Se optimiza el método `ObtenerAjustesPorSuscriptor` en `AjusteService` para obtener todos los nombres de usuarios y empresas en dos consultas masivas, en lugar de N consultas individuales.
- Se añade el método `GetByIdsAsync` al `IUsuarioRepository` y su implementación para soportar esta optimización.
### 🐛 Corrección de Errores
- Se corrigen múltiples errores en el script de migración de base de datos (uso de `GO` dentro de transacciones, error de "columna inválida").
- Se soluciona un error de SQL (`INSERT` statement) en `AjusteRepository` que impedía la creación de nuevos ajustes.
- Se corrige un bug en el `AjusteService` que causaba que el nombre de la empresa apareciera como "N/A" en la UI debido a un mapeo incompleto en el método optimizado.
- Se corrige la lógica de generación de emails en `FacturacionService` para mostrar correctamente el nombre de la empresa en cada sección del resumen de cuenta.
2025-08-09 17:39:21 -03:00
public async Task < ( IEnumerable < DistribucionSuscripcionDto > Data , string? Error ) > ObtenerReporteDistribucionSuscripcionesAsync ( DateTime fechaDesde , DateTime fechaHasta )
{
if ( fechaDesde > fechaHasta )
{
return ( Enumerable . Empty < DistribucionSuscripcionDto > ( ) , "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'." ) ;
}
try
{
var data = await _reportesRepository . GetDistribucionSuscripcionesAsync ( fechaDesde , fechaHasta ) ;
return ( data , null ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en servicio al obtener datos para reporte de distribución de suscripciones." ) ;
return ( new List < DistribucionSuscripcionDto > ( ) , "Error interno al generar el reporte." ) ;
}
}
2025-05-27 11:21:00 -03:00
}
}