2025-05-23 15:47:39 -03:00
using Dapper ;
using GestionIntegral.Api.Models.Contables ;
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.Contables
{
public class PagoDistribuidorRepository : IPagoDistribuidorRepository
{
private readonly DbConnectionFactory _cf ;
private readonly ILogger < PagoDistribuidorRepository > _log ;
public PagoDistribuidorRepository ( DbConnectionFactory cf , ILogger < PagoDistribuidorRepository > log )
{
_cf = cf ;
_log = log ;
}
private string SelectQueryBase ( ) = > @ "
SELECT
Id_Pago AS IdPago , Id_Distribuidor AS IdDistribuidor , Fecha , TipoMovimiento , Recibo , Monto ,
Id_TipoPago AS IdTipoPago , Detalle , Id_Empresa AS IdEmpresa
FROM dbo . cue_PagosDistribuidor ";
public async Task < IEnumerable < PagoDistribuidor > > GetAllAsync (
DateTime ? fechaDesde , DateTime ? fechaHasta ,
int? idDistribuidor , int? idEmpresa , string? tipoMovimiento )
{
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 ( idDistribuidor . HasValue ) { sqlBuilder . Append ( " AND Id_Distribuidor = @IdDistribuidorParam" ) ; parameters . Add ( "IdDistribuidorParam" , idDistribuidor . Value ) ; }
if ( idEmpresa . HasValue ) { sqlBuilder . Append ( " AND Id_Empresa = @IdEmpresaParam" ) ; parameters . Add ( "IdEmpresaParam" , idEmpresa . Value ) ; }
if ( ! string . IsNullOrWhiteSpace ( tipoMovimiento ) ) { sqlBuilder . Append ( " AND TipoMovimiento = @TipoMovParam" ) ; parameters . Add ( "TipoMovParam" , tipoMovimiento ) ; }
2025-06-09 19:37:07 -03:00
2025-05-23 15:47:39 -03:00
sqlBuilder . Append ( " ORDER BY Fecha DESC, Id_Pago DESC;" ) ;
try
{
using var connection = _cf . CreateConnection ( ) ;
return await connection . QueryAsync < PagoDistribuidor > ( sqlBuilder . ToString ( ) , parameters ) ;
}
catch ( Exception ex )
{
_log . LogError ( ex , "Error al obtener todos los Pagos de Distribuidores." ) ;
return Enumerable . Empty < PagoDistribuidor > ( ) ;
}
}
public async Task < PagoDistribuidor ? > GetByIdAsync ( int idPago )
{
var sql = SelectQueryBase ( ) + " WHERE Id_Pago = @IdPagoParam" ;
try
{
using var connection = _cf . CreateConnection ( ) ;
return await connection . QuerySingleOrDefaultAsync < PagoDistribuidor > ( sql , new { IdPagoParam = idPago } ) ;
}
catch ( Exception ex )
{
_log . LogError ( ex , "Error al obtener PagoDistribuidor por ID: {IdPago}" , idPago ) ;
return null ;
}
}
2025-06-09 19:37:07 -03:00
2025-05-23 15:47:39 -03:00
public async Task < bool > ExistsByReciboAndTipoMovimientoAsync ( int recibo , string tipoMovimiento , int? excludeIdPago = null )
{
var sqlBuilder = new StringBuilder ( "SELECT COUNT(1) FROM dbo.cue_PagosDistribuidor WHERE Recibo = @ReciboParam AND TipoMovimiento = @TipoMovParam" ) ;
var parameters = new DynamicParameters ( ) ;
parameters . Add ( "ReciboParam" , recibo ) ;
parameters . Add ( "TipoMovParam" , tipoMovimiento ) ;
if ( excludeIdPago . HasValue )
{
sqlBuilder . Append ( " AND Id_Pago != @ExcludeIdPagoParam" ) ;
parameters . Add ( "ExcludeIdPagoParam" , excludeIdPago . Value ) ;
}
try
{
using var connection = _cf . CreateConnection ( ) ;
return await connection . ExecuteScalarAsync < bool > ( sqlBuilder . ToString ( ) , parameters ) ;
}
catch ( Exception ex )
{
_log . LogError ( ex , "Error en ExistsByReciboAndTipoMovimientoAsync. Recibo: {Recibo}, Tipo: {Tipo}" , recibo , tipoMovimiento ) ;
return true ; // Asumir que existe en caso de error para prevenir duplicados
}
}
public async Task < PagoDistribuidor ? > CreateAsync ( PagoDistribuidor nuevoPago , int idUsuario , IDbTransaction transaction )
{
const string sqlInsert = @ "
INSERT INTO dbo . cue_PagosDistribuidor ( Id_Distribuidor , Fecha , TipoMovimiento , Recibo , Monto , Id_TipoPago , Detalle , Id_Empresa )
OUTPUT INSERTED . Id_Pago AS IdPago , INSERTED . Id_Distribuidor AS IdDistribuidor , INSERTED . Fecha , INSERTED . TipoMovimiento ,
INSERTED . Recibo , INSERTED . Monto , INSERTED . Id_TipoPago AS IdTipoPago , INSERTED . Detalle , INSERTED . Id_Empresa AS IdEmpresa
VALUES ( @IdDistribuidor , @Fecha , @TipoMovimiento , @Recibo , @Monto , @IdTipoPago , @Detalle , @IdEmpresa ) ; ";
const string sqlHistorico = @ "
INSERT INTO dbo . cue_PagosDistribuidor_H
( Id_Pago , Id_Distribuidor , Fecha , TipoMovimiento , Recibo , Monto , Id_TipoPago , Detalle , Id_Empresa , Id_Usuario , FechaMod , TipoMod )
VALUES ( @IdPagoHist , @IdDistribuidorHist , @FechaHist , @TipoMovimientoHist , @ReciboHist , @MontoHist , @IdTipoPagoHist , @DetalleHist , @IdEmpresaHist , @IdUsuarioHist , @FechaModHist , @TipoModHist ) ; ";
var inserted = await transaction . Connection ! . QuerySingleAsync < PagoDistribuidor > ( sqlInsert , nuevoPago , transaction ) ;
if ( inserted = = null | | inserted . IdPago = = 0 ) throw new DataException ( "Error al crear pago o ID no generado." ) ;
2025-06-09 19:37:07 -03:00
await transaction . Connection ! . ExecuteAsync ( sqlHistorico , new
{
IdPagoHist = inserted . IdPago ,
IdDistribuidorHist = inserted . IdDistribuidor ,
FechaHist = inserted . Fecha ,
TipoMovimientoHist = inserted . TipoMovimiento ,
ReciboHist = inserted . Recibo ,
MontoHist = inserted . Monto ,
IdTipoPagoHist = inserted . IdTipoPago ,
DetalleHist = inserted . Detalle ,
IdEmpresaHist = inserted . IdEmpresa ,
IdUsuarioHist = idUsuario ,
FechaModHist = DateTime . Now ,
TipoModHist = "Creado"
2025-05-23 15:47:39 -03:00
} , transaction ) ;
return inserted ;
}
public async Task < bool > UpdateAsync ( PagoDistribuidor pagoAActualizar , int idUsuario , IDbTransaction transaction )
{
var actual = await transaction . Connection ! . QuerySingleOrDefaultAsync < PagoDistribuidor > (
SelectQueryBase ( ) + " WHERE Id_Pago = @IdPagoParam" ,
new { IdPagoParam = pagoAActualizar . IdPago } , transaction ) ;
if ( actual = = null ) throw new KeyNotFoundException ( "Pago no encontrado." ) ;
// Campos que se permiten actualizar: Monto, Id_TipoPago, Detalle
// Otros campos como IdDistribuidor, Fecha, TipoMovimiento, Recibo, IdEmpresa no deberían cambiar
// para un pago ya registrado. Si necesitan cambiar, se debería anular/eliminar y crear uno nuevo.
const string sqlUpdate = @ "
UPDATE dbo . cue_PagosDistribuidor SET
Monto = @Monto , Id_TipoPago = @IdTipoPago , Detalle = @Detalle
WHERE Id_Pago = @IdPago ; ";
const string sqlHistorico = @ "
INSERT INTO dbo . cue_PagosDistribuidor_H
( Id_Pago , Id_Distribuidor , Fecha , TipoMovimiento , Recibo , Monto , Id_TipoPago , Detalle , Id_Empresa , Id_Usuario , FechaMod , TipoMod )
VALUES ( @IdPagoHist , @IdDistribuidorHist , @FechaHist , @TipoMovimientoHist , @ReciboHist , @MontoHist , @IdTipoPagoHist , @DetalleHist , @IdEmpresaHist , @IdUsuarioHist , @FechaModHist , @TipoModHist ) ; ";
2025-06-09 19:37:07 -03:00
await transaction . Connection ! . ExecuteAsync ( sqlHistorico , new
{
IdPagoHist = actual . IdPago ,
IdDistribuidorHist = actual . IdDistribuidor ,
FechaHist = actual . Fecha ,
TipoMovimientoHist = actual . TipoMovimiento ,
ReciboHist = actual . Recibo ,
MontoHist = actual . Monto , // Valor ANTERIOR
IdTipoPagoHist = actual . IdTipoPago ,
DetalleHist = actual . Detalle ,
IdEmpresaHist = actual . IdEmpresa , // Valores ANTERIORES
IdUsuarioHist = idUsuario ,
FechaModHist = DateTime . Now ,
TipoModHist = "Actualizado"
2025-05-23 15:47:39 -03:00
} , transaction ) ;
var rowsAffected = await transaction . Connection ! . ExecuteAsync ( sqlUpdate , pagoAActualizar , transaction ) ;
return rowsAffected = = 1 ;
}
public async Task < bool > DeleteAsync ( int idPago , int idUsuario , IDbTransaction transaction )
{
var actual = await transaction . Connection ! . QuerySingleOrDefaultAsync < PagoDistribuidor > (
SelectQueryBase ( ) + " WHERE Id_Pago = @IdPagoParam" ,
new { IdPagoParam = idPago } , transaction ) ;
if ( actual = = null ) throw new KeyNotFoundException ( "Pago no encontrado para eliminar." ) ;
const string sqlDelete = "DELETE FROM dbo.cue_PagosDistribuidor WHERE Id_Pago = @IdPagoParam" ;
const string sqlHistorico = @ "
INSERT INTO dbo . cue_PagosDistribuidor_H
( Id_Pago , Id_Distribuidor , Fecha , TipoMovimiento , Recibo , Monto , Id_TipoPago , Detalle , Id_Empresa , Id_Usuario , FechaMod , TipoMod )
VALUES ( @IdPagoHist , @IdDistribuidorHist , @FechaHist , @TipoMovimientoHist , @ReciboHist , @MontoHist , @IdTipoPagoHist , @DetalleHist , @IdEmpresaHist , @IdUsuarioHist , @FechaModHist , @TipoModHist ) ; ";
2025-06-09 19:37:07 -03:00
await transaction . Connection ! . ExecuteAsync ( sqlHistorico , new
{
IdPagoHist = actual . IdPago ,
IdDistribuidorHist = actual . IdDistribuidor ,
FechaHist = actual . Fecha ,
TipoMovimientoHist = actual . TipoMovimiento ,
ReciboHist = actual . Recibo ,
MontoHist = actual . Monto ,
IdTipoPagoHist = actual . IdTipoPago ,
DetalleHist = actual . Detalle ,
IdEmpresaHist = actual . IdEmpresa ,
IdUsuarioHist = idUsuario ,
FechaModHist = DateTime . Now ,
TipoModHist = "Eliminado"
2025-05-23 15:47:39 -03:00
} , transaction ) ;
var rowsAffected = await transaction . Connection ! . ExecuteAsync ( sqlDelete , new { IdPagoParam = idPago } , transaction ) ;
return rowsAffected = = 1 ;
}
2025-06-09 19:37:07 -03:00
public async Task < IEnumerable < ( PagoDistribuidorHistorico Historial , string NombreUsuarioModifico ) > > GetHistorialAsync (
DateTime ? fechaDesde , DateTime ? fechaHasta ,
int? idUsuarioModifico , string? tipoModificacion ,
int? idPagoOriginal )
{
using var connection = _cf . CreateConnection ( ) ;
var sqlBuilder = new StringBuilder ( @ "
SELECT
h . Id_Pago , h . Id_Distribuidor , h . Fecha , h . TipoMovimiento , h . Recibo , h . Monto ,
h . Id_TipoPago , h . Detalle , h . Id_Empresa ,
h . Id_Usuario , h . FechaMod , h . TipoMod ,
u . Nombre + ' ' + u . Apellido AS NombreUsuarioModifico
FROM dbo . cue_PagosDistribuidor_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 ( idPagoOriginal . HasValue ) { sqlBuilder . Append ( " AND h.Id_Pago = @IdPagoOriginalParam" ) ; parameters . Add ( "IdPagoOriginalParam" , idPagoOriginal . Value ) ; }
sqlBuilder . Append ( " ORDER BY h.FechaMod DESC;" ) ;
try
{
var result = await connection . QueryAsync < PagoDistribuidorHistorico , string , ( PagoDistribuidorHistorico , string ) > (
sqlBuilder . ToString ( ) ,
( hist , userName ) = > ( hist , userName ) ,
parameters ,
splitOn : "NombreUsuarioModifico"
) ;
return result ;
}
catch ( Exception ex )
{
_log . LogError ( ex , "Error al obtener historial de Pagos de Distribuidores." ) ;
return Enumerable . Empty < ( PagoDistribuidorHistorico , string ) > ( ) ;
}
}
2025-05-23 15:47:39 -03:00
}
}