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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												Feat: Implementa auditoría de envíos masivos y mejora de procesos
Se introduce un sistema completo para auditar los envíos masivos de correos durante el cierre mensual y se refactoriza la interfaz de usuario de procesos para una mayor claridad y escalabilidad. Además, se mejora la lógica de negocio para la gestión de bajas de suscripciones.
### ✨ Nuevas Características
- **Auditoría de Envíos Masivos (Cierre Mensual):**
    - Se crea una nueva tabla `com_LotesDeEnvio` para registrar cada ejecución del proceso de facturación mensual.
    - El `FacturacionService` ahora crea un "lote" al iniciar el cierre, registra el resultado de cada envío de email individual asociándolo a dicho lote, y actualiza las estadísticas finales (enviados, fallidos) al terminar.
    - Se implementa un nuevo `LotesEnvioController` con un endpoint para consultar los detalles de cualquier lote de envío histórico.
### 🔄 Refactorización y Mejoras
- **Rediseño de la Página de Procesos:**
    - La antigua página "Facturación" se renombra a `CierreYProcesosPage` y se rediseña completamente utilizando una interfaz de Pestañas (Tabs).
    - **Pestaña "Procesos Mensuales":** Aisla las acciones principales (Generar Cierre, Archivo de Débito, Procesar Respuesta), mostrando un resumen del resultado del último envío.
    - **Pestaña "Historial de Cierres":** Muestra una tabla con todos los lotes de envío pasados y permite al usuario ver los detalles de cada uno en un modal.
- **Filtros para el Historial de Cierres:**
    - Se añaden filtros por Mes y Año a la pestaña de "Historial de Cierres", permitiendo al usuario buscar y auditar procesos pasados de manera eficiente. El filtrado se realiza en el backend para un rendimiento óptimo.
- **Lógica de `FechaFin` Obligatoria para Bajas:**
    - Se implementa una regla de negocio crucial: al cambiar el estado de una suscripción a "Pausada" o "Cancelada", ahora es obligatorio establecer una `FechaFin`.
    - **Frontend:** El modal de suscripciones ahora gestiona esto automáticamente, haciendo el campo `FechaFin` requerido y visible según el estado seleccionado.
    - **Backend:** Se añade una validación en `SuscripcionService` como segunda capa de seguridad para garantizar la integridad de los datos.
### 🐛 Corrección de Errores
- **Reporte de Distribución:** Se corrigió un bug en la generación del PDF donde la columna de fecha no mostraba la "Fecha de Baja" para las suscripciones finalizadas. Ahora se muestra la fecha correcta según la sección (Altas o Bajas).
- **Errores de Compilación y Dependencias:** Se solucionaron varios errores de compilación en el backend, principalmente relacionados con la falta de registro de los nuevos repositorios (`ILoteDeEnvioRepository`, `IEmailLogService`, etc.) en el contenedor de inyección de dependencias (`Program.cs`).
- **Errores de Tipado en Frontend:** Se corrigieron múltiples errores de TypeScript en `CierreYProcesosPage` debidos a la inconsistencia entre `PascalCase` (C#) y `camelCase` (JSON/TypeScript), asegurando un mapeo correcto de los datos de la API.
											 
										 
										
											2025-08-11 11:14:03 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        public  async  Task < ( IEnumerable < DistribucionSuscripcionDto >  Altas ,  IEnumerable < DistribucionSuscripcionDto >  Bajas ,  string?  Error ) >  ObtenerReporteDistribucionSuscripcionesAsync ( DateTime  fechaDesde ,  DateTime  fechaHasta ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( fechaDesde  >  fechaHasta ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
									
										
											 
										
											
												Feat: Implementa auditoría de envíos masivos y mejora de procesos
Se introduce un sistema completo para auditar los envíos masivos de correos durante el cierre mensual y se refactoriza la interfaz de usuario de procesos para una mayor claridad y escalabilidad. Además, se mejora la lógica de negocio para la gestión de bajas de suscripciones.
### ✨ Nuevas Características
- **Auditoría de Envíos Masivos (Cierre Mensual):**
    - Se crea una nueva tabla `com_LotesDeEnvio` para registrar cada ejecución del proceso de facturación mensual.
    - El `FacturacionService` ahora crea un "lote" al iniciar el cierre, registra el resultado de cada envío de email individual asociándolo a dicho lote, y actualiza las estadísticas finales (enviados, fallidos) al terminar.
    - Se implementa un nuevo `LotesEnvioController` con un endpoint para consultar los detalles de cualquier lote de envío histórico.
### 🔄 Refactorización y Mejoras
- **Rediseño de la Página de Procesos:**
    - La antigua página "Facturación" se renombra a `CierreYProcesosPage` y se rediseña completamente utilizando una interfaz de Pestañas (Tabs).
    - **Pestaña "Procesos Mensuales":** Aisla las acciones principales (Generar Cierre, Archivo de Débito, Procesar Respuesta), mostrando un resumen del resultado del último envío.
    - **Pestaña "Historial de Cierres":** Muestra una tabla con todos los lotes de envío pasados y permite al usuario ver los detalles de cada uno en un modal.
- **Filtros para el Historial de Cierres:**
    - Se añaden filtros por Mes y Año a la pestaña de "Historial de Cierres", permitiendo al usuario buscar y auditar procesos pasados de manera eficiente. El filtrado se realiza en el backend para un rendimiento óptimo.
- **Lógica de `FechaFin` Obligatoria para Bajas:**
    - Se implementa una regla de negocio crucial: al cambiar el estado de una suscripción a "Pausada" o "Cancelada", ahora es obligatorio establecer una `FechaFin`.
    - **Frontend:** El modal de suscripciones ahora gestiona esto automáticamente, haciendo el campo `FechaFin` requerido y visible según el estado seleccionado.
    - **Backend:** Se añade una validación en `SuscripcionService` como segunda capa de seguridad para garantizar la integridad de los datos.
### 🐛 Corrección de Errores
- **Reporte de Distribución:** Se corrigió un bug en la generación del PDF donde la columna de fecha no mostraba la "Fecha de Baja" para las suscripciones finalizadas. Ahora se muestra la fecha correcta según la sección (Altas o Bajas).
- **Errores de Compilación y Dependencias:** Se solucionaron varios errores de compilación en el backend, principalmente relacionados con la falta de registro de los nuevos repositorios (`ILoteDeEnvioRepository`, `IEmailLogService`, etc.) en el contenedor de inyección de dependencias (`Program.cs`).
- **Errores de Tipado en Frontend:** Se corrigieron múltiples errores de TypeScript en `CierreYProcesosPage` debidos a la inconsistencia entre `PascalCase` (C#) y `camelCase` (JSON/TypeScript), asegurando un mapeo correcto de los datos de la API.
											 
										 
										
											2025-08-11 11:14:03 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  ( Enumerable . Empty < DistribucionSuscripcionDto > ( ) ,  Enumerable . Empty < DistribucionSuscripcionDto > ( ) ,  "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'." ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
											 
										
											
												Feat: Implementa auditoría de envíos masivos y mejora de procesos
Se introduce un sistema completo para auditar los envíos masivos de correos durante el cierre mensual y se refactoriza la interfaz de usuario de procesos para una mayor claridad y escalabilidad. Además, se mejora la lógica de negocio para la gestión de bajas de suscripciones.
### ✨ Nuevas Características
- **Auditoría de Envíos Masivos (Cierre Mensual):**
    - Se crea una nueva tabla `com_LotesDeEnvio` para registrar cada ejecución del proceso de facturación mensual.
    - El `FacturacionService` ahora crea un "lote" al iniciar el cierre, registra el resultado de cada envío de email individual asociándolo a dicho lote, y actualiza las estadísticas finales (enviados, fallidos) al terminar.
    - Se implementa un nuevo `LotesEnvioController` con un endpoint para consultar los detalles de cualquier lote de envío histórico.
### 🔄 Refactorización y Mejoras
- **Rediseño de la Página de Procesos:**
    - La antigua página "Facturación" se renombra a `CierreYProcesosPage` y se rediseña completamente utilizando una interfaz de Pestañas (Tabs).
    - **Pestaña "Procesos Mensuales":** Aisla las acciones principales (Generar Cierre, Archivo de Débito, Procesar Respuesta), mostrando un resumen del resultado del último envío.
    - **Pestaña "Historial de Cierres":** Muestra una tabla con todos los lotes de envío pasados y permite al usuario ver los detalles de cada uno en un modal.
- **Filtros para el Historial de Cierres:**
    - Se añaden filtros por Mes y Año a la pestaña de "Historial de Cierres", permitiendo al usuario buscar y auditar procesos pasados de manera eficiente. El filtrado se realiza en el backend para un rendimiento óptimo.
- **Lógica de `FechaFin` Obligatoria para Bajas:**
    - Se implementa una regla de negocio crucial: al cambiar el estado de una suscripción a "Pausada" o "Cancelada", ahora es obligatorio establecer una `FechaFin`.
    - **Frontend:** El modal de suscripciones ahora gestiona esto automáticamente, haciendo el campo `FechaFin` requerido y visible según el estado seleccionado.
    - **Backend:** Se añade una validación en `SuscripcionService` como segunda capa de seguridad para garantizar la integridad de los datos.
### 🐛 Corrección de Errores
- **Reporte de Distribución:** Se corrigió un bug en la generación del PDF donde la columna de fecha no mostraba la "Fecha de Baja" para las suscripciones finalizadas. Ahora se muestra la fecha correcta según la sección (Altas o Bajas).
- **Errores de Compilación y Dependencias:** Se solucionaron varios errores de compilación en el backend, principalmente relacionados con la falta de registro de los nuevos repositorios (`ILoteDeEnvioRepository`, `IEmailLogService`, etc.) en el contenedor de inyección de dependencias (`Program.cs`).
- **Errores de Tipado en Frontend:** Se corrigieron múltiples errores de TypeScript en `CierreYProcesosPage` debidos a la inconsistencia entre `PascalCase` (C#) y `camelCase` (JSON/TypeScript), asegurando un mapeo correcto de los datos de la API.
											 
										 
										
											2025-08-11 11:14:03 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            try 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
									
										
											 
										
											
												Feat: Implementa auditoría de envíos masivos y mejora de procesos
Se introduce un sistema completo para auditar los envíos masivos de correos durante el cierre mensual y se refactoriza la interfaz de usuario de procesos para una mayor claridad y escalabilidad. Además, se mejora la lógica de negocio para la gestión de bajas de suscripciones.
### ✨ Nuevas Características
- **Auditoría de Envíos Masivos (Cierre Mensual):**
    - Se crea una nueva tabla `com_LotesDeEnvio` para registrar cada ejecución del proceso de facturación mensual.
    - El `FacturacionService` ahora crea un "lote" al iniciar el cierre, registra el resultado de cada envío de email individual asociándolo a dicho lote, y actualiza las estadísticas finales (enviados, fallidos) al terminar.
    - Se implementa un nuevo `LotesEnvioController` con un endpoint para consultar los detalles de cualquier lote de envío histórico.
### 🔄 Refactorización y Mejoras
- **Rediseño de la Página de Procesos:**
    - La antigua página "Facturación" se renombra a `CierreYProcesosPage` y se rediseña completamente utilizando una interfaz de Pestañas (Tabs).
    - **Pestaña "Procesos Mensuales":** Aisla las acciones principales (Generar Cierre, Archivo de Débito, Procesar Respuesta), mostrando un resumen del resultado del último envío.
    - **Pestaña "Historial de Cierres":** Muestra una tabla con todos los lotes de envío pasados y permite al usuario ver los detalles de cada uno en un modal.
- **Filtros para el Historial de Cierres:**
    - Se añaden filtros por Mes y Año a la pestaña de "Historial de Cierres", permitiendo al usuario buscar y auditar procesos pasados de manera eficiente. El filtrado se realiza en el backend para un rendimiento óptimo.
- **Lógica de `FechaFin` Obligatoria para Bajas:**
    - Se implementa una regla de negocio crucial: al cambiar el estado de una suscripción a "Pausada" o "Cancelada", ahora es obligatorio establecer una `FechaFin`.
    - **Frontend:** El modal de suscripciones ahora gestiona esto automáticamente, haciendo el campo `FechaFin` requerido y visible según el estado seleccionado.
    - **Backend:** Se añade una validación en `SuscripcionService` como segunda capa de seguridad para garantizar la integridad de los datos.
### 🐛 Corrección de Errores
- **Reporte de Distribución:** Se corrigió un bug en la generación del PDF donde la columna de fecha no mostraba la "Fecha de Baja" para las suscripciones finalizadas. Ahora se muestra la fecha correcta según la sección (Altas o Bajas).
- **Errores de Compilación y Dependencias:** Se solucionaron varios errores de compilación en el backend, principalmente relacionados con la falta de registro de los nuevos repositorios (`ILoteDeEnvioRepository`, `IEmailLogService`, etc.) en el contenedor de inyección de dependencias (`Program.cs`).
- **Errores de Tipado en Frontend:** Se corrigieron múltiples errores de TypeScript en `CierreYProcesosPage` debidos a la inconsistencia entre `PascalCase` (C#) y `camelCase` (JSON/TypeScript), asegurando un mapeo correcto de los datos de la API.
											 
										 
										
											2025-08-11 11:14:03 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Ejecutamos ambas consultas en paralelo para mayor eficiencia 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                var  altasTask  =  _reportesRepository . GetDistribucionSuscripcionesActivasAsync ( fechaDesde ,  fechaHasta ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                var  bajasTask  =  _reportesRepository . GetDistribucionSuscripcionesBajasAsync ( fechaDesde ,  fechaHasta ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                await  Task . WhenAll ( altasTask ,  bajasTask ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  ( await  altasTask ,  await  bajasTask ,  null ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            catch  ( Exception  ex ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                _logger . LogError ( ex ,  "Error en servicio al obtener datos para reporte de distribución de suscripciones." ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Feat: Implementa auditoría de envíos masivos y mejora de procesos
Se introduce un sistema completo para auditar los envíos masivos de correos durante el cierre mensual y se refactoriza la interfaz de usuario de procesos para una mayor claridad y escalabilidad. Además, se mejora la lógica de negocio para la gestión de bajas de suscripciones.
### ✨ Nuevas Características
- **Auditoría de Envíos Masivos (Cierre Mensual):**
    - Se crea una nueva tabla `com_LotesDeEnvio` para registrar cada ejecución del proceso de facturación mensual.
    - El `FacturacionService` ahora crea un "lote" al iniciar el cierre, registra el resultado de cada envío de email individual asociándolo a dicho lote, y actualiza las estadísticas finales (enviados, fallidos) al terminar.
    - Se implementa un nuevo `LotesEnvioController` con un endpoint para consultar los detalles de cualquier lote de envío histórico.
### 🔄 Refactorización y Mejoras
- **Rediseño de la Página de Procesos:**
    - La antigua página "Facturación" se renombra a `CierreYProcesosPage` y se rediseña completamente utilizando una interfaz de Pestañas (Tabs).
    - **Pestaña "Procesos Mensuales":** Aisla las acciones principales (Generar Cierre, Archivo de Débito, Procesar Respuesta), mostrando un resumen del resultado del último envío.
    - **Pestaña "Historial de Cierres":** Muestra una tabla con todos los lotes de envío pasados y permite al usuario ver los detalles de cada uno en un modal.
- **Filtros para el Historial de Cierres:**
    - Se añaden filtros por Mes y Año a la pestaña de "Historial de Cierres", permitiendo al usuario buscar y auditar procesos pasados de manera eficiente. El filtrado se realiza en el backend para un rendimiento óptimo.
- **Lógica de `FechaFin` Obligatoria para Bajas:**
    - Se implementa una regla de negocio crucial: al cambiar el estado de una suscripción a "Pausada" o "Cancelada", ahora es obligatorio establecer una `FechaFin`.
    - **Frontend:** El modal de suscripciones ahora gestiona esto automáticamente, haciendo el campo `FechaFin` requerido y visible según el estado seleccionado.
    - **Backend:** Se añade una validación en `SuscripcionService` como segunda capa de seguridad para garantizar la integridad de los datos.
### 🐛 Corrección de Errores
- **Reporte de Distribución:** Se corrigió un bug en la generación del PDF donde la columna de fecha no mostraba la "Fecha de Baja" para las suscripciones finalizadas. Ahora se muestra la fecha correcta según la sección (Altas o Bajas).
- **Errores de Compilación y Dependencias:** Se solucionaron varios errores de compilación en el backend, principalmente relacionados con la falta de registro de los nuevos repositorios (`ILoteDeEnvioRepository`, `IEmailLogService`, etc.) en el contenedor de inyección de dependencias (`Program.cs`).
- **Errores de Tipado en Frontend:** Se corrigieron múltiples errores de TypeScript en `CierreYProcesosPage` debidos a la inconsistencia entre `PascalCase` (C#) y `camelCase` (JSON/TypeScript), asegurando un mapeo correcto de los datos de la API.
											 
										 
										
											2025-08-11 11:14:03 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  ( Enumerable . Empty < DistribucionSuscripcionDto > ( ) ,  Enumerable . Empty < DistribucionSuscripcionDto > ( ) ,  "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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-27 11:21:00 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}