224 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			224 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using GestionIntegral.Api.Data; | ||
|  | using GestionIntegral.Api.Data.Repositories.Distribucion; | ||
|  | using GestionIntegral.Api.Data.Repositories.Impresion; | ||
|  | using GestionIntegral.Api.Dtos.Impresion; | ||
|  | using GestionIntegral.Api.Models.Distribucion; // Para Publicacion, PubliSeccion | ||
|  | using GestionIntegral.Api.Models.Impresion;   // Para RegTirada, RegPublicacionSeccion | ||
|  | using Microsoft.Extensions.Logging; | ||
|  | using System; | ||
|  | using System.Collections.Generic; | ||
|  | using System.Data; | ||
|  | using System.Linq; | ||
|  | using System.Threading.Tasks; | ||
|  | 
 | ||
|  | namespace GestionIntegral.Api.Services.Impresion | ||
|  | { | ||
|  |     public class TiradaService : ITiradaService | ||
|  |     { | ||
|  |         private readonly IRegTiradaRepository _regTiradaRepository; | ||
|  |         private readonly IRegPublicacionSeccionRepository _regPublicacionSeccionRepository; | ||
|  |         private readonly IPublicacionRepository _publicacionRepository; | ||
|  |         private readonly IPlantaRepository _plantaRepository; | ||
|  |         private readonly IPubliSeccionRepository _publiSeccionRepository; // Para validar IDs de sección | ||
|  |         private readonly DbConnectionFactory _connectionFactory; | ||
|  |         private readonly ILogger<TiradaService> _logger; | ||
|  | 
 | ||
|  |         public TiradaService( | ||
|  |             IRegTiradaRepository regTiradaRepository, | ||
|  |             IRegPublicacionSeccionRepository regPublicacionSeccionRepository, | ||
|  |             IPublicacionRepository publicacionRepository, | ||
|  |             IPlantaRepository plantaRepository, | ||
|  |             IPubliSeccionRepository publiSeccionRepository, | ||
|  |             DbConnectionFactory connectionFactory, | ||
|  |             ILogger<TiradaService> logger) | ||
|  |         { | ||
|  |             _regTiradaRepository = regTiradaRepository; | ||
|  |             _regPublicacionSeccionRepository = regPublicacionSeccionRepository; | ||
|  |             _publicacionRepository = publicacionRepository; | ||
|  |             _plantaRepository = plantaRepository; | ||
|  |             _publiSeccionRepository = publiSeccionRepository; | ||
|  |             _connectionFactory = connectionFactory; | ||
|  |             _logger = logger; | ||
|  |         } | ||
|  | 
 | ||
|  |         public async Task<IEnumerable<TiradaDto>> ObtenerTiradasAsync(DateTime? fecha, int? idPublicacion, int? idPlanta) | ||
|  |         { | ||
|  |             var tiradasPrincipales = await _regTiradaRepository.GetByCriteriaAsync(fecha, idPublicacion, idPlanta); | ||
|  |             var resultado = new List<TiradaDto>(); | ||
|  | 
 | ||
|  |             foreach (var tiradaP in tiradasPrincipales) | ||
|  |             { | ||
|  |                 var publicacion = await _publicacionRepository.GetByIdSimpleAsync(tiradaP.IdPublicacion); | ||
|  |                 var planta = await _plantaRepository.GetByIdAsync(tiradaP.IdPlanta); | ||
|  |                 var seccionesImpresas = await _regPublicacionSeccionRepository.GetByFechaPublicacionPlantaAsync(tiradaP.Fecha, tiradaP.IdPublicacion, tiradaP.IdPlanta); | ||
|  | 
 | ||
|  |                 var detallesSeccionDto = new List<DetalleSeccionEnListadoDto>(); | ||
|  |                 int totalPaginas = 0; | ||
|  |                 foreach (var seccionImp in seccionesImpresas) | ||
|  |                 { | ||
|  |                     var seccionInfo = await _publiSeccionRepository.GetByIdAsync(seccionImp.IdSeccion); | ||
|  |                     detallesSeccionDto.Add(new DetalleSeccionEnListadoDto | ||
|  |                     { | ||
|  |                         IdSeccion = seccionImp.IdSeccion, | ||
|  |                         NombreSeccion = seccionInfo?.Nombre ?? "Sección Desconocida", | ||
|  |                         CantPag = seccionImp.CantPag, | ||
|  |                         IdRegPublicacionSeccion = seccionImp.IdTirada // Este es el PK de bob_RegPublicaciones | ||
|  |                     }); | ||
|  |                     totalPaginas += seccionImp.CantPag; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 resultado.Add(new TiradaDto | ||
|  |                 { | ||
|  |                     IdRegistroTirada = tiradaP.IdRegistro, | ||
|  |                     IdPublicacion = tiradaP.IdPublicacion, | ||
|  |                     NombrePublicacion = publicacion?.Nombre ?? "Publicación Desconocida", | ||
|  |                     Fecha = tiradaP.Fecha.ToString("yyyy-MM-dd"), | ||
|  |                     IdPlanta = tiradaP.IdPlanta, | ||
|  |                     NombrePlanta = planta?.Nombre ?? "Planta Desconocida", | ||
|  |                     Ejemplares = tiradaP.Ejemplares, | ||
|  |                     SeccionesImpresas = detallesSeccionDto, | ||
|  |                     TotalPaginasSumadas = totalPaginas | ||
|  |                 }); | ||
|  |             } | ||
|  |             return resultado; | ||
|  |         } | ||
|  | 
 | ||
|  | 
 | ||
|  |         public async Task<(TiradaDto? TiradaCreada, string? Error)> RegistrarTiradaCompletaAsync(CreateTiradaRequestDto createDto, int idUsuario) | ||
|  |         { | ||
|  |             // Validaciones previas | ||
|  |             var publicacion = await _publicacionRepository.GetByIdSimpleAsync(createDto.IdPublicacion); | ||
|  |             if (publicacion == null) return (null, "La publicación especificada no existe."); | ||
|  |             var planta = await _plantaRepository.GetByIdAsync(createDto.IdPlanta); | ||
|  |             if (planta == null) return (null, "La planta especificada no existe."); | ||
|  | 
 | ||
|  |             // Validar que no exista ya una tirada para esa Publicación, Fecha y Planta | ||
|  |             // (bob_RegTiradas debería ser único por estos campos) | ||
|  |             if (await _regTiradaRepository.GetByFechaPublicacionPlantaAsync(createDto.Fecha.Date, createDto.IdPublicacion, createDto.IdPlanta) != null) | ||
|  |             { | ||
|  |                 return (null, $"Ya existe una tirada registrada para la publicación '{publicacion.Nombre}' en la planta '{planta.Nombre}' para la fecha {createDto.Fecha:dd/MM/yyyy}."); | ||
|  |             } | ||
|  | 
 | ||
|  | 
 | ||
|  |             // Validar secciones | ||
|  |             foreach (var seccionDto in createDto.Secciones) | ||
|  |             { | ||
|  |                 var seccionDb = await _publiSeccionRepository.GetByIdAsync(seccionDto.IdSeccion); | ||
|  |                 if (seccionDb == null || seccionDb.IdPublicacion != createDto.IdPublicacion) | ||
|  |                     return (null, $"La sección con ID {seccionDto.IdSeccion} no es válida o no pertenece a la publicación seleccionada."); | ||
|  |                 if (!seccionDb.Estado) // Asumiendo que solo se pueden tirar secciones activas | ||
|  |                     return (null, $"La sección '{seccionDb.Nombre}' no está activa y no puede incluirse en la tirada."); | ||
|  |             } | ||
|  | 
 | ||
|  | 
 | ||
|  |             using var connection = _connectionFactory.CreateConnection(); | ||
|  |             if (connection is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else connection.Open(); | ||
|  |             using var transaction = connection.BeginTransaction(); | ||
|  | 
 | ||
|  |             try | ||
|  |             { | ||
|  |                 // 1. Crear registro en bob_RegTiradas (total de ejemplares) | ||
|  |                 var nuevaRegTirada = new RegTirada | ||
|  |                 { | ||
|  |                     IdPublicacion = createDto.IdPublicacion, | ||
|  |                     Fecha = createDto.Fecha.Date, | ||
|  |                     IdPlanta = createDto.IdPlanta, | ||
|  |                     Ejemplares = createDto.Ejemplares | ||
|  |                 }; | ||
|  |                 var regTiradaCreada = await _regTiradaRepository.CreateAsync(nuevaRegTirada, idUsuario, transaction); | ||
|  |                 if (regTiradaCreada == null) throw new DataException("Error al registrar el total de la tirada."); | ||
|  | 
 | ||
|  |                 // 2. Crear registros en bob_RegPublicaciones (detalle de secciones y páginas) | ||
|  |                 var seccionesImpresasDto = new List<DetalleSeccionEnListadoDto>(); | ||
|  |                 int totalPaginasSumadas = 0; | ||
|  | 
 | ||
|  |                 foreach (var seccionDto in createDto.Secciones) | ||
|  |                 { | ||
|  |                     var nuevaRegPubSeccion = new RegPublicacionSeccion | ||
|  |                     { | ||
|  |                         IdPublicacion = createDto.IdPublicacion, | ||
|  |                         IdSeccion = seccionDto.IdSeccion, | ||
|  |                         CantPag = seccionDto.CantPag, | ||
|  |                         Fecha = createDto.Fecha.Date, | ||
|  |                         IdPlanta = createDto.IdPlanta | ||
|  |                     }; | ||
|  |                     var seccionCreadaEnTirada = await _regPublicacionSeccionRepository.CreateAsync(nuevaRegPubSeccion, idUsuario, transaction); | ||
|  |                     if (seccionCreadaEnTirada == null) throw new DataException($"Error al registrar la sección ID {seccionDto.IdSeccion} en la tirada."); | ||
|  |                      | ||
|  |                     var seccionInfo = await _publiSeccionRepository.GetByIdAsync(seccionDto.IdSeccion); // Para obtener nombre | ||
|  |                     seccionesImpresasDto.Add(new DetalleSeccionEnListadoDto{ | ||
|  |                         IdSeccion = seccionCreadaEnTirada.IdSeccion, | ||
|  |                         NombreSeccion = seccionInfo?.Nombre ?? "N/A", | ||
|  |                         CantPag = seccionCreadaEnTirada.CantPag, | ||
|  |                         IdRegPublicacionSeccion = seccionCreadaEnTirada.IdTirada | ||
|  |                     }); | ||
|  |                     totalPaginasSumadas += seccionCreadaEnTirada.CantPag; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 transaction.Commit(); | ||
|  |                 _logger.LogInformation("Tirada completa registrada para Pub ID {IdPub}, Fecha {Fecha}, Planta ID {IdPlanta} por Usuario ID {UserId}.", | ||
|  |                     createDto.IdPublicacion, createDto.Fecha.Date, createDto.IdPlanta, idUsuario); | ||
|  | 
 | ||
|  |                 return (new TiradaDto { | ||
|  |                     IdRegistroTirada = regTiradaCreada.IdRegistro, | ||
|  |                     IdPublicacion = regTiradaCreada.IdPublicacion, | ||
|  |                     NombrePublicacion = publicacion.Nombre, | ||
|  |                     Fecha = regTiradaCreada.Fecha.ToString("yyyy-MM-dd"), | ||
|  |                     IdPlanta = regTiradaCreada.IdPlanta, | ||
|  |                     NombrePlanta = planta.Nombre, | ||
|  |                     Ejemplares = regTiradaCreada.Ejemplares, | ||
|  |                     SeccionesImpresas = seccionesImpresasDto, | ||
|  |                     TotalPaginasSumadas = totalPaginasSumadas | ||
|  |                 }, null); | ||
|  |             } | ||
|  |             catch (Exception ex) | ||
|  |             { | ||
|  |                 try { transaction.Rollback(); } catch { } | ||
|  |                 _logger.LogError(ex, "Error RegistrarTiradaCompletaAsync para Pub ID {IdPub}, Fecha {Fecha}", createDto.IdPublicacion, createDto.Fecha); | ||
|  |                 return (null, $"Error interno: {ex.Message}"); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public async Task<(bool Exito, string? Error)> EliminarTiradaCompletaAsync(DateTime fecha, int idPublicacion, int idPlanta, int idUsuario) | ||
|  |         { | ||
|  |             // Verificar que la tirada principal exista | ||
|  |             var tiradaPrincipal = await _regTiradaRepository.GetByFechaPublicacionPlantaAsync(fecha.Date, idPublicacion, idPlanta); | ||
|  |             if (tiradaPrincipal == null) | ||
|  |             { | ||
|  |                 return (false, "No se encontró una tirada principal para los criterios especificados."); | ||
|  |             } | ||
|  | 
 | ||
|  |             using var connection = _connectionFactory.CreateConnection(); | ||
|  |             if (connection is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else connection.Open(); | ||
|  |             using var transaction = connection.BeginTransaction(); | ||
|  |             try | ||
|  |             { | ||
|  |                 // 1. Eliminar detalles de secciones de bob_RegPublicaciones | ||
|  |                 // El método ya guarda en historial | ||
|  |                 await _regPublicacionSeccionRepository.DeleteByFechaPublicacionPlantaAsync(fecha.Date, idPublicacion, idPlanta, idUsuario, transaction); | ||
|  |                 _logger.LogInformation("Secciones de tirada eliminadas para Fecha: {Fecha}, PubID: {IdPublicacion}, PlantaID: {IdPlanta}", fecha.Date, idPublicacion, idPlanta); | ||
|  | 
 | ||
|  |                 // 2. Eliminar el registro principal de bob_RegTiradas | ||
|  |                 // El método ya guarda en historial | ||
|  |                 bool principalEliminado = await _regTiradaRepository.DeleteByFechaPublicacionPlantaAsync(fecha.Date, idPublicacion, idPlanta, idUsuario, transaction); | ||
|  |                 // bool principalEliminado = await _regTiradaRepository.DeleteAsync(tiradaPrincipal.IdRegistro, idUsuario, transaction); // Alternativa si ya tienes el IdRegistro | ||
|  |                 if (!principalEliminado && tiradaPrincipal != null) // Si DeleteByFechaPublicacionPlantaAsync devuelve false porque no encontró nada (raro si pasó la validación) | ||
|  |                 { | ||
|  |                      _logger.LogWarning("No se eliminó el registro principal de tirada (bob_RegTiradas) para Fecha: {Fecha}, PubID: {IdPublicacion}, PlantaID: {IdPlanta}. Pudo haber sido eliminado concurrentemente.", fecha.Date, idPublicacion, idPlanta); | ||
|  |                      // Decidir si esto es un error que debe hacer rollback | ||
|  |                 } | ||
|  |                  _logger.LogInformation("Registro principal de tirada eliminado para Fecha: {Fecha}, PubID: {IdPublicacion}, PlantaID: {IdPlanta}", fecha.Date, idPublicacion, idPlanta); | ||
|  | 
 | ||
|  | 
 | ||
|  |                 transaction.Commit(); | ||
|  |                 return (true, null); | ||
|  |             } | ||
|  |             catch (Exception ex) | ||
|  |             { | ||
|  |                 try { transaction.Rollback(); } catch { } | ||
|  |                 _logger.LogError(ex, "Error EliminarTiradaCompletaAsync para Fecha {Fecha}, PubID {IdPub}, PlantaID {IdPlanta}", fecha.Date, idPublicacion, idPlanta); | ||
|  |                 return (false, $"Error interno al eliminar la tirada: {ex.Message}"); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | } |