254 lines
11 KiB
C#
254 lines
11 KiB
C#
// En Services/Distribucion (o donde corresponda)
|
|
using GestionIntegral.Api.Data; // Para DbConnectionFactory
|
|
using GestionIntegral.Api.Data.Repositories.Distribucion;
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
} |