2025-06-06 18:33:09 -03:00
// En Services/Distribucion (o donde corresponda)
using GestionIntegral.Api.Data ; // Para DbConnectionFactory
using GestionIntegral.Api.Data.Repositories.Distribucion ;
2025-06-09 19:37:07 -03:00
using GestionIntegral.Api.Dtos.Auditoria ;
2025-06-06 18:33:09 -03:00
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 ;
}
}
2025-06-09 19:37:07 -03:00
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 ( ) ;
}
2025-06-06 18:33:09 -03:00
}
}