2025-05-23 15:47:39 -03:00
using Dapper ;
using GestionIntegral.Api.Models.Distribucion ;
using Microsoft.Extensions.Logging ;
using System ;
using System.Collections.Generic ;
using System.Data ;
using System.Linq ;
using System.Text ;
using System.Threading.Tasks ;
namespace GestionIntegral.Api.Data.Repositories.Distribucion
{
public class ControlDevolucionesRepository : IControlDevolucionesRepository
{
private readonly DbConnectionFactory _cf ;
private readonly ILogger < ControlDevolucionesRepository > _log ;
public ControlDevolucionesRepository ( DbConnectionFactory cf , ILogger < ControlDevolucionesRepository > log )
{
_cf = cf ;
_log = log ;
}
private string SelectQueryBase ( ) = > @ "
SELECT
Id_Control AS IdControl , Id_Empresa AS IdEmpresa , Fecha ,
Entrada , Sobrantes , Detalle , SinCargo
FROM dbo . dist_dtCtrlDevoluciones ";
public async Task < IEnumerable < ControlDevoluciones > > GetAllAsync ( DateTime ? fechaDesde , DateTime ? fechaHasta , int? idEmpresa )
{
var sqlBuilder = new StringBuilder ( SelectQueryBase ( ) ) ;
sqlBuilder . Append ( " WHERE 1=1" ) ;
var parameters = new DynamicParameters ( ) ;
if ( fechaDesde . HasValue ) { sqlBuilder . Append ( " AND Fecha >= @FechaDesdeParam" ) ; parameters . Add ( "FechaDesdeParam" , fechaDesde . Value . Date ) ; }
if ( fechaHasta . HasValue ) { sqlBuilder . Append ( " AND Fecha <= @FechaHastaParam" ) ; parameters . Add ( "FechaHastaParam" , fechaHasta . Value . Date ) ; }
if ( idEmpresa . HasValue ) { sqlBuilder . Append ( " AND Id_Empresa = @IdEmpresaParam" ) ; parameters . Add ( "IdEmpresaParam" , idEmpresa . Value ) ; }
2025-06-12 19:36:21 -03:00
2025-05-23 15:47:39 -03:00
sqlBuilder . Append ( " ORDER BY Fecha DESC, Id_Empresa;" ) ;
try
{
using var connection = _cf . CreateConnection ( ) ;
return await connection . QueryAsync < ControlDevoluciones > ( sqlBuilder . ToString ( ) , parameters ) ;
}
catch ( Exception ex )
{
_log . LogError ( ex , "Error al obtener todos los Controles de Devoluciones." ) ;
return Enumerable . Empty < ControlDevoluciones > ( ) ;
}
}
public async Task < ControlDevoluciones ? > GetByIdAsync ( int idControl )
{
var sql = SelectQueryBase ( ) + " WHERE Id_Control = @IdControlParam" ;
try
{
using var connection = _cf . CreateConnection ( ) ;
return await connection . QuerySingleOrDefaultAsync < ControlDevoluciones > ( sql , new { IdControlParam = idControl } ) ;
}
catch ( Exception ex )
{
_log . LogError ( ex , "Error al obtener ControlDevoluciones por ID: {IdControl}" , idControl ) ;
return null ;
}
}
public async Task < ControlDevoluciones ? > GetByEmpresaAndFechaAsync ( int idEmpresa , DateTime fecha , IDbTransaction ? transaction = null )
{
var sql = SelectQueryBase ( ) + " WHERE Id_Empresa = @IdEmpresaParam AND Fecha = @FechaParam" ;
var cn = transaction ? . Connection ? ? _cf . CreateConnection ( ) ;
bool ownConnection = transaction = = null ;
ControlDevoluciones ? result = null ;
try
{
if ( ownConnection & & cn . State = = ConnectionState . Closed & & cn is System . Data . Common . DbConnection dbConn ) await dbConn . OpenAsync ( ) ;
result = await cn . QuerySingleOrDefaultAsync < ControlDevoluciones > ( sql , new { IdEmpresaParam = idEmpresa , FechaParam = fecha . Date } , transaction ) ;
}
finally
{
if ( ownConnection & & cn . State = = ConnectionState . Open & & cn is System . Data . Common . DbConnection dbConnClose ) await dbConnClose . CloseAsync ( ) ;
if ( ownConnection ) ( cn as IDisposable ) ? . Dispose ( ) ;
}
return result ;
}
public async Task < ControlDevoluciones ? > CreateAsync ( ControlDevoluciones nuevoControl , int idUsuario , IDbTransaction transaction )
{
const string sqlInsert = @ "
INSERT INTO dbo . dist_dtCtrlDevoluciones ( Id_Empresa , Fecha , Entrada , Sobrantes , Detalle , SinCargo )
OUTPUT INSERTED . Id_Control AS IdControl , INSERTED . Id_Empresa AS IdEmpresa , INSERTED . Fecha ,
INSERTED . Entrada , INSERTED . Sobrantes , INSERTED . Detalle , INSERTED . SinCargo
VALUES ( @IdEmpresa , @Fecha , @Entrada , @Sobrantes , @Detalle , @SinCargo ) ; ";
const string sqlHistorico = @ "
INSERT INTO dbo . dist_dtCtrlDevoluciones_H
( Id_Control , Id_Empresa , Fecha , Entrada , Sobrantes , Detalle , SinCargo , Id_Usuario , FechaMod , TipoMod )
VALUES ( @IdControlParam , @IdEmpresaParam , @FechaParam , @EntradaParam , @SobrantesParam , @DetalleParam , @SinCargoParam , @IdUsuarioParam , @FechaModParam , @TipoModParam ) ; ";
var inserted = await transaction . Connection ! . QuerySingleAsync < ControlDevoluciones > ( sqlInsert , nuevoControl , transaction ) ;
if ( inserted = = null | | inserted . IdControl = = 0 ) throw new DataException ( "Error al crear control de devoluciones o ID no generado." ) ;
2025-06-12 19:36:21 -03:00
await transaction . Connection ! . ExecuteAsync ( sqlHistorico , new
{
IdControlParam = inserted . IdControl ,
IdEmpresaParam = inserted . IdEmpresa ,
FechaParam = inserted . Fecha ,
EntradaParam = inserted . Entrada ,
SobrantesParam = inserted . Sobrantes ,
DetalleParam = inserted . Detalle ,
SinCargoParam = inserted . SinCargo ,
IdUsuarioParam = idUsuario ,
FechaModParam = DateTime . Now ,
TipoModParam = "Creado"
2025-05-23 15:47:39 -03:00
} , transaction ) ;
return inserted ;
}
public async Task < bool > UpdateAsync ( ControlDevoluciones controlAActualizar , int idUsuario , IDbTransaction transaction )
{
var actual = await transaction . Connection ! . QuerySingleOrDefaultAsync < ControlDevoluciones > (
SelectQueryBase ( ) + " WHERE Id_Control = @IdControlParam" ,
new { IdControlParam = controlAActualizar . IdControl } , transaction ) ;
if ( actual = = null ) throw new KeyNotFoundException ( "Control de devoluciones no encontrado." ) ;
// En este caso, Id_Empresa y Fecha no deberían cambiar para un registro existente
const string sqlUpdate = @ "
UPDATE dbo . dist_dtCtrlDevoluciones SET
Entrada = @Entrada , Sobrantes = @Sobrantes , Detalle = @Detalle , SinCargo = @SinCargo
WHERE Id_Control = @IdControl ; ";
2025-06-12 19:36:21 -03:00
const string sqlHistorico = @ "
2025-05-23 15:47:39 -03:00
INSERT INTO dbo . dist_dtCtrlDevoluciones_H
( Id_Control , Id_Empresa , Fecha , Entrada , Sobrantes , Detalle , SinCargo , Id_Usuario , FechaMod , TipoMod )
VALUES ( @IdControlParam , @IdEmpresaParam , @FechaParam , @EntradaParam , @SobrantesParam , @DetalleParam , @SinCargoParam , @IdUsuarioParam , @FechaModParam , @TipoModParam ) ; ";
2025-06-12 19:36:21 -03:00
await transaction . Connection ! . ExecuteAsync ( sqlHistorico , new
{
IdControlParam = actual . IdControl ,
IdEmpresaParam = actual . IdEmpresa ,
FechaParam = actual . Fecha , // Datos originales
EntradaParam = actual . Entrada ,
SobrantesParam = actual . Sobrantes ,
DetalleParam = actual . Detalle ,
SinCargoParam = actual . SinCargo , // Valores ANTERIORES
IdUsuarioParam = idUsuario ,
FechaModParam = DateTime . Now ,
TipoModParam = "Actualizado"
2025-05-23 15:47:39 -03:00
} , transaction ) ;
var rowsAffected = await transaction . Connection ! . ExecuteAsync ( sqlUpdate , controlAActualizar , transaction ) ;
return rowsAffected = = 1 ;
}
public async Task < bool > DeleteAsync ( int idControl , int idUsuario , IDbTransaction transaction )
{
var actual = await transaction . Connection ! . QuerySingleOrDefaultAsync < ControlDevoluciones > (
SelectQueryBase ( ) + " WHERE Id_Control = @IdControlParam" ,
new { IdControlParam = idControl } , transaction ) ;
if ( actual = = null ) throw new KeyNotFoundException ( "Control de devoluciones no encontrado para eliminar." ) ;
const string sqlDelete = "DELETE FROM dbo.dist_dtCtrlDevoluciones WHERE Id_Control = @IdControlParam" ;
const string sqlHistorico = @ "
INSERT INTO dbo . dist_dtCtrlDevoluciones_H
( Id_Control , Id_Empresa , Fecha , Entrada , Sobrantes , Detalle , SinCargo , Id_Usuario , FechaMod , TipoMod )
VALUES ( @IdControlParam , @IdEmpresaParam , @FechaParam , @EntradaParam , @SobrantesParam , @DetalleParam , @SinCargoParam , @IdUsuarioParam , @FechaModParam , @TipoModParam ) ; ";
2025-06-12 19:36:21 -03:00
await transaction . Connection ! . ExecuteAsync ( sqlHistorico , new
{
IdControlParam = actual . IdControl ,
IdEmpresaParam = actual . IdEmpresa ,
FechaParam = actual . Fecha ,
EntradaParam = actual . Entrada ,
SobrantesParam = actual . Sobrantes ,
DetalleParam = actual . Detalle ,
SinCargoParam = actual . SinCargo ,
IdUsuarioParam = idUsuario ,
FechaModParam = DateTime . Now ,
TipoModParam = "Eliminado"
2025-05-23 15:47:39 -03:00
} , transaction ) ;
var rowsAffected = await transaction . Connection ! . ExecuteAsync ( sqlDelete , new { IdControlParam = idControl } , transaction ) ;
return rowsAffected = = 1 ;
}
2025-06-12 19:36:21 -03:00
public async Task < IEnumerable < ( ControlDevolucionesHistorico Historial , string NombreUsuarioModifico ) > > GetHistorialAsync (
DateTime ? fechaDesde , DateTime ? fechaHasta ,
int? idUsuarioModifico , string? tipoModificacion ,
int? idControlOriginal , int? idEmpresaOriginal , DateTime ? fechaOriginal )
{
using var connection = _cf . CreateConnection ( ) ;
var sqlBuilder = new StringBuilder ( @ "
SELECT
h . Id_Control , h . Id_Empresa , h . Fecha , h . Entrada , h . Sobrantes , h . Detalle , h . SinCargo ,
h . Id_Usuario , h . FechaMod , h . TipoMod ,
u . Nombre + ' ' + u . Apellido AS NombreUsuarioModifico
FROM dbo . dist_dtCtrlDevoluciones_H h
JOIN dbo . gral_Usuarios u ON h . Id_Usuario = u . Id
WHERE 1 = 1 ");
var parameters = new DynamicParameters ( ) ;
if ( fechaDesde . HasValue ) { sqlBuilder . Append ( " AND h.FechaMod >= @FechaDesdeParam" ) ; parameters . Add ( "FechaDesdeParam" , fechaDesde . Value . Date ) ; }
if ( fechaHasta . HasValue ) { sqlBuilder . Append ( " AND h.FechaMod <= @FechaHastaParam" ) ; parameters . Add ( "FechaHastaParam" , fechaHasta . Value . Date . AddDays ( 1 ) . AddTicks ( - 1 ) ) ; }
if ( idUsuarioModifico . HasValue ) { sqlBuilder . Append ( " AND h.Id_Usuario = @IdUsuarioModificoParam" ) ; parameters . Add ( "IdUsuarioModificoParam" , idUsuarioModifico . Value ) ; }
if ( ! string . IsNullOrWhiteSpace ( tipoModificacion ) ) { sqlBuilder . Append ( " AND h.TipoMod = @TipoModParam" ) ; parameters . Add ( "TipoModParam" , tipoModificacion ) ; }
if ( idControlOriginal . HasValue ) { sqlBuilder . Append ( " AND h.Id_Control = @IdControlOriginalParam" ) ; parameters . Add ( "IdControlOriginalParam" , idControlOriginal . Value ) ; }
if ( idEmpresaOriginal . HasValue ) { sqlBuilder . Append ( " AND h.Id_Empresa = @IdEmpresaOriginalParam" ) ; parameters . Add ( "IdEmpresaOriginalParam" , idEmpresaOriginal . Value ) ; }
if ( fechaOriginal . HasValue ) { sqlBuilder . Append ( " AND h.Fecha = @FechaOriginalParam" ) ; parameters . Add ( "FechaOriginalParam" , fechaOriginal . Value . Date ) ; }
sqlBuilder . Append ( " ORDER BY h.FechaMod DESC;" ) ;
try
{
var result = await connection . QueryAsync < ControlDevolucionesHistorico , string , ( ControlDevolucionesHistorico , string ) > (
sqlBuilder . ToString ( ) ,
( hist , userName ) = > ( hist , userName ) ,
parameters ,
splitOn : "NombreUsuarioModifico"
) ;
return result ;
}
catch ( Exception ex )
{
_log . LogError ( ex , "Error al obtener historial de Control de Devoluciones." ) ;
return Enumerable . Empty < ( ControlDevolucionesHistorico , string ) > ( ) ;
}
}
2025-05-23 15:47:39 -03:00
}
}