Finalización de Reportes y arreglos varios de controles y comportamientos...
This commit is contained in:
		| @@ -222,10 +222,10 @@ namespace GestionIntegral.Api.Services.Distribucion | ||||
|             { | ||||
|                 if (connection is System.Data.Common.DbConnection dbConnOpen && connection.State == ConnectionState.Closed) await dbConnOpen.OpenAsync(); | ||||
|                 else if (connection.State == ConnectionState.Closed) connection.Open(); | ||||
|                  | ||||
|  | ||||
|                 transaction = connection.BeginTransaction(); | ||||
|  | ||||
|                 var esExistente = await _esCanillaRepository.GetByIdAsync(idParte); | ||||
|                 var esExistente = await _esCanillaRepository.GetByIdAsync(idParte); // Obtener el estado actual | ||||
|                 if (esExistente == null) | ||||
|                 { | ||||
|                     if (transaction?.Connection != null) transaction.Rollback(); | ||||
| @@ -234,17 +234,16 @@ namespace GestionIntegral.Api.Services.Distribucion | ||||
|  | ||||
|                 if (esExistente.Liquidado) | ||||
|                 { | ||||
|                     // Permiso MC006 es para "Eliminar Movimientos de Canillita Liquidados" | ||||
|                     if (!TienePermisoEspecifico("MC006")) | ||||
|                     if (!TienePermisoEspecifico("MC006")) // <--- AQUÍ ESTÁ LA VERIFICACIÓN | ||||
|                     { | ||||
|                         if (transaction?.Connection != null) transaction.Rollback(); | ||||
|                         return (false, "No tiene permiso para eliminar movimientos ya liquidados. Se requiere permiso especial (MC006) o ser SuperAdmin."); | ||||
|                     } | ||||
|                     _logger.LogWarning("Usuario ID {IdUsuario} está eliminando un movimiento LIQUIDADO (IDParte: {IdParte}). Permiso MC006 verificado.", idUsuario, idParte); | ||||
|                 } | ||||
|                 // Si no está liquidado, el permiso MC004 ya fue verificado en el controlador. | ||||
|                 // Si no está liquidado, el permiso MC004 ya fue verificado en el controlador (o debería serlo). | ||||
|  | ||||
|                 var eliminado = await _esCanillaRepository.DeleteAsync(idParte, idUsuario, transaction); | ||||
|                 var eliminado = await _esCanillaRepository.DeleteAsync(idParte, idUsuario, transaction); // Ahora esto no lanzará la excepción por liquidado | ||||
|                 if (!eliminado) | ||||
|                 { | ||||
|                     // No es necesario hacer rollback aquí si DeleteAsync lanza una excepción, | ||||
| @@ -258,10 +257,10 @@ namespace GestionIntegral.Api.Services.Distribucion | ||||
|                 _logger.LogInformation("Movimiento Canillita ID {IdParte} eliminado por Usuario ID {IdUsuario}.", idParte, idUsuario); | ||||
|                 return (true, null); | ||||
|             } | ||||
|             catch (KeyNotFoundException)  | ||||
|             {  | ||||
|             catch (KeyNotFoundException) | ||||
|             { | ||||
|                 if (transaction?.Connection != null) try { transaction.Rollback(); } catch (Exception exR) { _logger.LogError(exR, "Rollback fallido KeyNotFoundException."); } | ||||
|                 return (false, "Movimiento no encontrado.");  | ||||
|                 return (false, "Movimiento no encontrado."); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|   | ||||
| @@ -11,5 +11,8 @@ namespace GestionIntegral.Api.Services.Distribucion | ||||
|         Task<(PublicacionDto? Publicacion, string? Error)> CrearAsync(CreatePublicacionDto createDto, int idUsuario); | ||||
|         Task<(bool Exito, string? Error)> ActualizarAsync(int id, UpdatePublicacionDto updateDto, int idUsuario); | ||||
|         Task<(bool Exito, string? Error)> EliminarAsync(int id, int idUsuario); | ||||
|         Task<IEnumerable<PublicacionDiaSemanaDto>> ObtenerConfiguracionDiasAsync(int idPublicacion); | ||||
|         Task<IEnumerable<PublicacionDto>> ObtenerPublicacionesPorDiaSemanaAsync(byte diaSemana); // Devolvemos el DTO completo | ||||
|         Task<(bool Exito, string? Error)> ActualizarConfiguracionDiasAsync(int idPublicacion, UpdatePublicacionDiasSemanaRequestDto requestDto, int idUsuario); | ||||
|     } | ||||
| } | ||||
| @@ -202,5 +202,71 @@ namespace GestionIntegral.Api.Services.Distribucion | ||||
|                 return (false, $"Error interno al eliminar la publicación y sus dependencias: {ex.Message}"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async Task<IEnumerable<PublicacionDiaSemanaDto>> ObtenerConfiguracionDiasAsync(int idPublicacion) | ||||
|         { | ||||
|             var configs = await _publicacionRepository.GetConfiguracionDiasAsync(idPublicacion); | ||||
|             return configs.Select(c => new PublicacionDiaSemanaDto | ||||
|             { | ||||
|                 IdPublicacionDia = c.IdPublicacionDia, | ||||
|                 IdPublicacion = c.IdPublicacion, | ||||
|                 DiaSemana = c.DiaSemana, | ||||
|                 Activo = c.Activo | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         public async Task<IEnumerable<PublicacionDto>> ObtenerPublicacionesPorDiaSemanaAsync(byte diaSemana) | ||||
|         { | ||||
|             // Obtener IDs de las publicaciones configuradas para ese día | ||||
|             var idsPublicaciones = await _publicacionRepository.GetPublicacionesIdsPorDiaSemanaAsync(diaSemana); | ||||
|  | ||||
|             if (!idsPublicaciones.Any()) | ||||
|             { | ||||
|                 return Enumerable.Empty<PublicacionDto>(); | ||||
|             } | ||||
|  | ||||
|             // Obtener los detalles completos de esas publicaciones | ||||
|             // Podríamos optimizar esto si GetByIdAsync es eficiente o crear un GetByIdsAsync | ||||
|             var publicacionesTasks = idsPublicaciones.Select(id => ObtenerPorIdAsync(id)); | ||||
|             var publicacionesResult = await Task.WhenAll(publicacionesTasks); | ||||
|  | ||||
|             return publicacionesResult.Where(p => p != null).Select(p => p!); // Filtrar nulos y asegurar no nulabilidad | ||||
|         } | ||||
|  | ||||
|  | ||||
|         public async Task<(bool Exito, string? Error)> ActualizarConfiguracionDiasAsync(int idPublicacion, UpdatePublicacionDiasSemanaRequestDto requestDto, int idUsuario) | ||||
|         { | ||||
|             var publicacionExistente = await _publicacionRepository.GetByIdSimpleAsync(idPublicacion); | ||||
|             if (publicacionExistente == null) | ||||
|             { | ||||
|                 return (false, "Publicación no encontrada."); | ||||
|             } | ||||
|  | ||||
|             // Validar que los días de la semana estén en el rango correcto (0-6) | ||||
|             if (requestDto.DiasActivos.Any(d => d > 6)) // byte no puede ser < 0 | ||||
|             { | ||||
|                 return (false, "Día de la semana inválido. Debe estar entre 0 (Domingo) y 6 (Sábado)."); | ||||
|             } | ||||
|  | ||||
|             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 | ||||
|             { | ||||
|                 await _publicacionRepository.UpdateConfiguracionDiasAsync(idPublicacion, requestDto.DiasActivos.Distinct(), transaction); | ||||
|                 // No se está implementando historial para PublicacionDiaSemana por ahora. | ||||
|                 // Si se necesitara, se añadiría aquí una llamada al repositorio para insertar en la tabla _H. | ||||
|  | ||||
|                 transaction.Commit(); | ||||
|                 _logger.LogInformation("Configuración de días actualizada para Publicación ID {IdPublicacion} por Usuario ID {UserId}.", idPublicacion, idUsuario); | ||||
|                 return (true, null); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 try { transaction.Rollback(); } catch { } | ||||
|                 _logger.LogError(ex, "Error al actualizar configuración de días para Publicacion ID: {IdPublicacion}", idPublicacion); | ||||
|                 return (false, $"Error interno al actualizar la configuración de días: {ex.Message}"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -63,5 +63,11 @@ namespace GestionIntegral.Api.Services.Reportes | ||||
|         )> ObtenerReporteCuentasDistribuidorAsync(int idDistribuidor, int idEmpresa, DateTime fechaDesde, DateTime fechaHasta); | ||||
|  | ||||
|         Task<(IEnumerable<ListadoDistribucionDistSimpleDto> Simple, IEnumerable<ListadoDistribucionDistPromedioDiaDto> Promedios, string? Error)> ObtenerListadoDistribucionDistribuidoresAsync(int idDistribuidor, int idPublicacion, DateTime fechaDesde, DateTime fechaHasta); | ||||
|  | ||||
|         Task<( | ||||
|             IEnumerable<LiquidacionCanillaDetalleDto> Detalles, | ||||
|             IEnumerable<LiquidacionCanillaGananciaDto> Ganancias, | ||||
|             string? Error | ||||
|         )> ObtenerDatosTicketLiquidacionAsync(DateTime fecha, int idCanilla); | ||||
|     } | ||||
| } | ||||
| @@ -449,5 +449,46 @@ namespace GestionIntegral.Api.Services.Reportes | ||||
|                 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." | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user