Files
GestionIntegralWeb/Backend/GestionIntegral.Api/Services/Distribucion/NovedadCanillaService.cs

276 lines
12 KiB
C#
Raw Permalink Normal View History

// En Services/Distribucion (o donde corresponda)
using GestionIntegral.Api.Data; // Para DbConnectionFactory
using GestionIntegral.Api.Data.Repositories.Distribucion;
using GestionIntegral.Api.Dtos.Auditoria;
using GestionIntegral.Api.Dtos.Distribucion;
using GestionIntegral.Api.Dtos.Reportes;
using GestionIntegral.Api.Models.Distribucion; // Asegúrate que el modelo Canilla tenga NomApe
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Data; // Para IDbTransaction
using System.Linq;
using System.Threading.Tasks;
namespace GestionIntegral.Api.Services.Distribucion
{
public class NovedadCanillaService : INovedadCanillaService
{
private readonly INovedadCanillaRepository _novedadRepository;
private readonly ICanillaRepository _canillaRepository;
private readonly DbConnectionFactory _connectionFactory;
private readonly ILogger<NovedadCanillaService> _logger;
public NovedadCanillaService(
INovedadCanillaRepository novedadRepository,
ICanillaRepository canillaRepository,
DbConnectionFactory connectionFactory,
ILogger<NovedadCanillaService> logger)
{
_novedadRepository = novedadRepository;
_canillaRepository = canillaRepository;
_connectionFactory = connectionFactory;
_logger = logger;
}
private NovedadCanillaDto MapToDto((NovedadCanilla Novedad, string NombreCanilla) data)
{
return new NovedadCanillaDto
{
IdNovedad = data.Novedad.IdNovedad,
IdCanilla = data.Novedad.IdCanilla,
NombreCanilla = data.NombreCanilla, // Viene de la tupla en GetByCanillaAsync
Fecha = data.Novedad.Fecha,
Detalle = data.Novedad.Detalle
};
}
private NovedadCanillaDto MapToDto(NovedadCanilla data, string nombreCanilla)
{
return new NovedadCanillaDto
{
IdNovedad = data.IdNovedad,
IdCanilla = data.IdCanilla,
NombreCanilla = nombreCanilla,
Fecha = data.Fecha,
Detalle = data.Detalle
};
}
public async Task<IEnumerable<NovedadCanillaDto>> ObtenerPorCanillaAsync(int idCanilla, DateTime? fechaDesde, DateTime? fechaHasta)
{
var data = await _novedadRepository.GetByCanillaAsync(idCanilla, fechaDesde, fechaHasta);
return data.Select(MapToDto);
}
public async Task<NovedadCanillaDto?> ObtenerPorIdAsync(int idNovedad)
{
var novedad = await _novedadRepository.GetByIdAsync(idNovedad);
if (novedad == null) return null;
// Asumiendo que _canillaRepository.GetByIdAsync devuelve una tupla (Canilla? Canilla, ...)
// O un DTO CanillaDto que tiene NomApe
var canillaDataResult = await _canillaRepository.GetByIdAsync(novedad.IdCanilla);
// Ajusta esto según lo que realmente devuelva GetByIdAsync
// Si devuelve CanillaDto:
// string nombreCanilla = canillaDataResult?.NomApe ?? "Desconocido";
// Si devuelve la tupla (Canilla? Canilla, string? NombreZona, string? NombreEmpresa):
string nombreCanilla = canillaDataResult.Canilla?.NomApe ?? "Desconocido";
return MapToDto(novedad, nombreCanilla);
}
public async Task<(NovedadCanillaDto? Novedad, string? Error)> CrearAsync(CreateNovedadCanillaDto createDto, int idUsuario)
{
// Asegúrate que GetByIdSimpleAsync devuelva un objeto Canilla o algo con NomApe
var canilla = await _canillaRepository.GetByIdSimpleAsync(createDto.IdCanilla);
if (canilla == null)
{
return (null, "El canillita especificado no existe.");
}
var nuevaNovedad = new NovedadCanilla
{
IdCanilla = createDto.IdCanilla,
Fecha = createDto.Fecha.Date,
Detalle = createDto.Detalle
};
using var connection = _connectionFactory.CreateConnection();
// Abre la conexión explícitamente si no se usa una transacción externa
if (connection is System.Data.Common.DbConnection dbConn && connection.State != ConnectionState.Open)
{
await dbConn.OpenAsync();
}
else if (connection.State != ConnectionState.Open)
{
connection.Open();
}
using var transaction = connection.BeginTransaction();
try
{
var creada = await _novedadRepository.CreateAsync(nuevaNovedad, idUsuario, transaction);
if (creada == null)
{
transaction.Rollback();
return (null, "Error al guardar la novedad en la base de datos.");
}
transaction.Commit();
_logger.LogInformation("Novedad ID {IdNovedad} para Canilla ID {IdCanilla} creada por Usuario ID {UserId}.", creada.IdNovedad, creada.IdCanilla, idUsuario);
// Asegúrate que 'canilla.NomApe' sea accesible. Si GetByIdSimpleAsync devuelve la entidad Canilla, esto está bien.
return (MapToDto(creada, canilla.NomApe ?? "Canilla sin nombre"), null);
}
catch (Exception ex)
{
try { transaction.Rollback(); } catch (Exception rbEx) { _logger.LogError(rbEx, "Error durante Rollback en CrearAsync NovedadCanilla."); }
_logger.LogError(ex, "Error CrearAsync NovedadCanilla para Canilla ID: {IdCanilla}", createDto.IdCanilla);
return (null, $"Error interno al crear la novedad: {ex.Message}");
}
finally
{
if (connection.State == ConnectionState.Open) connection.Close();
}
}
public async Task<(bool Exito, string? Error)> ActualizarAsync(int idNovedad, UpdateNovedadCanillaDto updateDto, int idUsuario)
{
var existente = await _novedadRepository.GetByIdAsync(idNovedad);
if (existente == null)
{
return (false, "Novedad no encontrada.");
}
existente.Detalle = updateDto.Detalle;
using var connection = _connectionFactory.CreateConnection();
if (connection is System.Data.Common.DbConnection dbConn && connection.State != ConnectionState.Open)
{
await dbConn.OpenAsync();
}
else if (connection.State != ConnectionState.Open)
{
connection.Open();
}
using var transaction = connection.BeginTransaction();
try
{
var actualizado = await _novedadRepository.UpdateAsync(existente, idUsuario, transaction);
if (!actualizado)
{
transaction.Rollback();
return (false, "Error al actualizar la novedad en la base de datos.");
}
transaction.Commit();
_logger.LogInformation("Novedad ID {IdNovedad} actualizada por Usuario ID {UserId}.", idNovedad, idUsuario);
return (true, null);
}
catch (Exception ex)
{
try { transaction.Rollback(); } catch (Exception rbEx) { _logger.LogError(rbEx, "Error durante Rollback en ActualizarAsync NovedadCanilla."); }
_logger.LogError(ex, "Error ActualizarAsync NovedadCanilla ID: {IdNovedad}", idNovedad);
return (false, $"Error interno al actualizar la novedad: {ex.Message}");
}
finally
{
if (connection.State == ConnectionState.Open) connection.Close();
}
}
public async Task<(bool Exito, string? Error)> EliminarAsync(int idNovedad, int idUsuario)
{
var existente = await _novedadRepository.GetByIdAsync(idNovedad);
if (existente == null)
{
return (false, "Novedad no encontrada.");
}
using var connection = _connectionFactory.CreateConnection();
if (connection is System.Data.Common.DbConnection dbConn && connection.State != ConnectionState.Open)
{
await dbConn.OpenAsync();
}
else if (connection.State != ConnectionState.Open)
{
connection.Open();
}
using var transaction = connection.BeginTransaction();
try
{
var eliminado = await _novedadRepository.DeleteAsync(idNovedad, idUsuario, transaction);
if (!eliminado)
{
transaction.Rollback();
return (false, "Error al eliminar la novedad de la base de datos.");
}
transaction.Commit();
_logger.LogInformation("Novedad ID {IdNovedad} eliminada por Usuario ID {UserId}.", idNovedad, idUsuario);
return (true, null);
}
catch (Exception ex)
{
try { transaction.Rollback(); } catch (Exception rbEx) { _logger.LogError(rbEx, "Error durante Rollback en EliminarAsync NovedadCanilla."); }
_logger.LogError(ex, "Error EliminarAsync NovedadCanilla ID: {IdNovedad}", idNovedad);
return (false, $"Error interno al eliminar la novedad: {ex.Message}");
}
finally
{
if (connection.State == ConnectionState.Open) connection.Close();
}
}
public async Task<IEnumerable<NovedadesCanillasReporteDto>> ObtenerReporteNovedadesAsync(int idEmpresa, DateTime fechaDesde, DateTime fechaHasta)
{
// Podría añadir validaciones o lógica de negocio adicional si fuera necesario
// antes de llamar al repositorio. Por ahora, es una llamada directa.
try
{
return await _novedadRepository.GetReporteNovedadesAsync(idEmpresa, fechaDesde, fechaHasta);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener datos para el reporte de novedades de canillitas. Empresa: {IdEmpresa}, Desde: {FechaDesde}, Hasta: {FechaHasta}", idEmpresa, fechaDesde, fechaHasta);
// Podría relanzar o devolver una lista vacía con un mensaje de error,
// dependiendo de cómo quiera manejar los errores en la capa de servicio.
// Por simplicidad, relanzamos para que el controlador lo maneje.
throw;
}
}
public async Task<IEnumerable<CanillaGananciaReporteDto>> ObtenerReporteGananciasAsync(int idEmpresa, DateTime fechaDesde, DateTime fechaHasta)
{
try
{
return await _novedadRepository.GetReporteGananciasAsync(idEmpresa, fechaDesde, fechaHasta);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener datos para el reporte de ganancias de canillitas. Empresa: {IdEmpresa}, Desde: {FechaDesde}, Hasta: {FechaHasta}", idEmpresa, fechaDesde, fechaHasta);
throw;
}
}
public async Task<IEnumerable<NovedadCanillaHistorialDto>> ObtenerHistorialAsync(
DateTime? fechaDesde, DateTime? fechaHasta,
int? idUsuarioModifico, string? tipoModificacion,
int? idNovedadAfectada)
{
var historialData = await _novedadRepository.GetHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idNovedadAfectada);
return historialData.Select(h => new NovedadCanillaHistorialDto
{
Id_Novedad = h.Historial.Id_Novedad,
Id_Canilla = h.Historial.Id_Canilla,
Fecha = h.Historial.Fecha,
Detalle = h.Historial.Detalle,
Id_Usuario = h.Historial.Id_Usuario,
NombreUsuarioModifico = h.NombreUsuarioModifico,
FechaMod = h.Historial.FechaMod,
TipoMod = h.Historial.TipoMod
// Si decides traer NombreCanilla desde el repo, mapealo aquí.
}).ToList();
}
}
}