Este commit introduce una refactorización significativa en el módulo de
suscripciones para alinear el sistema con reglas de negocio clave:
facturación consolidada por empresa, cobro a mes adelantado con
imputación de ajustes diferida, y una interfaz de usuario más clara.
Backend:
- **Facturación por Empresa:** Se modifica `FacturacionService` para
agrupar las suscripciones por cliente y empresa, generando una
factura consolidada para cada combinación. Esto asegura la correcta
separación fiscal.
- **Imputación de Ajustes:** Se ajusta la lógica para que la facturación
de un período (ej. Septiembre) aplique únicamente los ajustes
pendientes cuya fecha corresponde al período anterior (Agosto).
- **Cierre Secuencial:** Se implementa una validación en
`GenerarFacturacionMensual` que impide generar la facturación de un
período si el anterior no ha sido cerrado, garantizando el orden
cronológico.
- **Emails Consolidados:** El proceso de notificación automática al
generar el cierre ahora envía un único email consolidado por
suscriptor, detallando los cargos de todas sus facturas/empresas.
- **Envío de PDF Individual:** Se refactoriza el endpoint de envío manual
para que opere sobre una `idFactura` individual y adjunte el PDF
correspondiente si existe.
- **Repositorios Mejorados:** Se optimizan y añaden métodos en
`FacturaRepository` y `AjusteRepository` para soportar los nuevos
requisitos de filtrado y consulta de datos consolidados.
Frontend:
- **Separación de Vistas:** La página de "Facturación" se divide en dos:
- `ProcesosPage`: Para acciones masivas (generar cierre, archivo de
débito, procesar respuesta).
- `ConsultaFacturasPage`: Una nueva página dedicada a buscar,
filtrar y gestionar facturas individuales con una interfaz de doble
acordeón (Suscriptor -> Empresa).
- **Filtros Avanzados:** La página `ConsultaFacturasPage` ahora incluye
filtros por nombre de suscriptor, estado de pago y estado de
facturación.
- **Filtros de Fecha por Defecto:** La página de "Cuenta Corriente"
ahora filtra por el mes actual por defecto para mejorar el rendimiento
y la usabilidad.
- **Validación de Fechas:** Se añade lógica en los filtros de fecha para
impedir la selección de rangos inválidos.
- **Validación de Monto de Pago:** El modal de pago manual ahora impide
registrar un monto superior al saldo pendiente de la factura.
554 lines
31 KiB
C#
554 lines
31 KiB
C#
using GestionIntegral.Api.Data.Repositories.Distribucion;
|
|
using GestionIntegral.Api.Data.Repositories.Reportes;
|
|
using GestionIntegral.Api.Data.Repositories.Suscripciones;
|
|
using GestionIntegral.Api.Dtos.Reportes;
|
|
|
|
namespace GestionIntegral.Api.Services.Reportes
|
|
{
|
|
public class ReportesService : IReportesService
|
|
{
|
|
private readonly IReportesRepository _reportesRepository;
|
|
private readonly IFacturaRepository _facturaRepository;
|
|
private readonly IFacturaDetalleRepository _facturaDetalleRepository;
|
|
private readonly IPublicacionRepository _publicacionRepository;
|
|
private readonly IEmpresaRepository _empresaRepository;
|
|
private readonly ISuscriptorRepository _suscriptorRepository;
|
|
private readonly ISuscripcionRepository _suscripcionRepository;
|
|
private readonly ILogger<ReportesService> _logger;
|
|
|
|
public ReportesService(IReportesRepository reportesRepository, IFacturaRepository facturaRepository, IFacturaDetalleRepository facturaDetalleRepository, IPublicacionRepository publicacionRepository, IEmpresaRepository empresaRepository
|
|
, ISuscriptorRepository suscriptorRepository, ISuscripcionRepository suscripcionRepository, ILogger<ReportesService> logger)
|
|
{
|
|
_reportesRepository = reportesRepository;
|
|
_facturaRepository = facturaRepository;
|
|
_facturaDetalleRepository = facturaDetalleRepository;
|
|
_publicacionRepository = publicacionRepository;
|
|
_empresaRepository = empresaRepository;
|
|
_suscriptorRepository = suscriptorRepository;
|
|
_suscripcionRepository = suscripcionRepository;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task<(IEnumerable<ExistenciaPapelDto> Data, string? Error)> ObtenerExistenciaPapelAsync(
|
|
DateTime fechaDesde, DateTime fechaHasta, int? idPlanta, bool consolidado)
|
|
{
|
|
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);
|
|
}
|
|
catch (ArgumentNullException ex) when (ex.ParamName == "idPlanta")
|
|
{
|
|
_logger.LogWarning(ex, "ArgumentNullException para idPlanta en ObtenerExistenciaPapelAsync.");
|
|
return (Enumerable.Empty<ExistenciaPapelDto>(), ex.Message);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error en ReportesService al obtener Existencia de Papel.");
|
|
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'.");
|
|
}
|
|
int diasPeriodo = (fechaHasta.Date - fechaDesde.Date).Days + 1;
|
|
|
|
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);
|
|
|
|
var detalleUtc = detalle.Select(d =>
|
|
{
|
|
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.");
|
|
}
|
|
}
|
|
|
|
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);
|
|
|
|
var resumenUtc = resumenData.Select(r => { r.Fecha = DateTime.SpecifyKind(r.Fecha, DateTimeKind.Utc); return r; }).ToList();
|
|
|
|
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'.");
|
|
|
|
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.");
|
|
}
|
|
}
|
|
|
|
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.");
|
|
}
|
|
}
|
|
|
|
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.");
|
|
}
|
|
}
|
|
|
|
public async Task<(
|
|
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)
|
|
{
|
|
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);
|
|
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
|
|
);
|
|
|
|
var detallesOriginales = await ctrlDevolucionesParaDistCanTask ?? Enumerable.Empty<ControlDevolucionesReporteDto>();
|
|
var detallesOrdenados = detallesOriginales.OrderBy(d => d.Tipo).ToList();
|
|
|
|
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()
|
|
?? Enumerable.Empty<DetalleDistribucionCanillaDto>();
|
|
|
|
return (
|
|
toUtc(await canillasTask),
|
|
toUtc(await canillasAccTask),
|
|
await canillasAllTask ?? Enumerable.Empty<DetalleDistribucionCanillaAllDto>(),
|
|
toUtc(await canillasFechaLiqTask),
|
|
toUtc(await canillasAccFechaLiqTask),
|
|
await ctrlDevolucionesRemitosTask ?? Enumerable.Empty<ObtenerCtrlDevolucionesDto>(),
|
|
detallesOrdenados,
|
|
await ctrlDevolucionesOtrosDiasTask ?? Enumerable.Empty<DevueltosOtrosDiasDto>(),
|
|
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>(),
|
|
Enumerable.Empty<DevueltosOtrosDiasDto>(),
|
|
"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)
|
|
{
|
|
if (fechaDesde > fechaHasta)
|
|
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);
|
|
|
|
Func<IEnumerable<BalanceCuentaDistDto>, IEnumerable<BalanceCuentaDistDto>> esToUtc =
|
|
items => items?.Select(i => { i.Fecha = DateTime.SpecifyKind(i.Fecha.Date, DateTimeKind.Utc); return i; }).ToList()
|
|
?? Enumerable.Empty<BalanceCuentaDistDto>();
|
|
Func<IEnumerable<BalanceCuentaDebCredDto>, IEnumerable<BalanceCuentaDebCredDto>> dcToUtc =
|
|
items => items?.Select(i => { i.Fecha = DateTime.SpecifyKind(i.Fecha.Date, DateTimeKind.Utc); return i; }).ToList()
|
|
?? Enumerable.Empty<BalanceCuentaDebCredDto>();
|
|
Func<IEnumerable<BalanceCuentaPagosDto>, IEnumerable<BalanceCuentaPagosDto>> paToUtc =
|
|
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."
|
|
);
|
|
}
|
|
}
|
|
|
|
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.");
|
|
}
|
|
}
|
|
|
|
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."
|
|
);
|
|
}
|
|
}
|
|
|
|
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).");
|
|
}
|
|
}
|
|
|
|
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.");
|
|
}
|
|
}
|
|
}
|
|
} |