2025-06-09 19:37:07 -03:00
using Dapper ;
using GestionIntegral.Api.Models.Distribucion ;
using Microsoft.Extensions.Logging ; // Para ILogger
using System ;
using System.Collections.Generic ;
using System.Data ;
using System.Linq ;
using System.Text ; // Para StringBuilder
using System.Threading.Tasks ;
namespace GestionIntegral.Api.Data.Repositories.Distribucion
{
public class CambioParadaRepository : ICambioParadaRepository
{
private readonly DbConnectionFactory _cf ;
private readonly ILogger < CambioParadaRepository > _logger ;
public CambioParadaRepository ( DbConnectionFactory cf , ILogger < CambioParadaRepository > logger )
{
_cf = cf ;
_logger = logger ;
}
private async Task LogHistorialAsync ( CambioParadaCanilla paradaOriginal , int idUsuario , string tipoMod , IDbConnection connection , IDbTransaction ? transaction )
{
var historial = new CambioParadaCanillaHistorial
{
Id_Registro = paradaOriginal . IdRegistro ,
Id_Canilla = paradaOriginal . IdCanilla ,
Parada = paradaOriginal . Parada ,
VigenciaD = paradaOriginal . VigenciaD ,
VigenciaH = paradaOriginal . VigenciaH ,
Id_Usuario = idUsuario ,
FechaMod = DateTime . Now ,
TipoMod = tipoMod
} ;
const string sqlHistorial = @ "
INSERT INTO dbo . dist_CambiosParadasCanillas_H
( Id_Registro , Id_Canilla , Parada , VigenciaD , VigenciaH , Id_Usuario , FechaMod , TipoMod )
VALUES
( @Id_Registro , @Id_Canilla , @Parada , @VigenciaD , @VigenciaH , @Id_Usuario , @FechaMod , @TipoMod ) ; ";
await connection . ExecuteAsync ( sqlHistorial , historial , transaction ) ;
}
public async Task < IEnumerable < CambioParadaCanilla > > GetByCanillaAsync ( int idCanilla )
{
using var connection = _cf . CreateConnection ( ) ;
const string sql = @ "
SELECT Id_Registro AS IdRegistro , Id_Canilla AS IdCanilla , Parada , VigenciaD , VigenciaH
FROM dbo . dist_CambiosParadasCanillas
WHERE Id_Canilla = @IdCanilla
ORDER BY VigenciaD DESC , Id_Registro DESC ; ";
return await connection . QueryAsync < CambioParadaCanilla > ( sql , new { IdCanilla = idCanilla } ) ;
}
public async Task < CambioParadaCanilla ? > GetByIdAsync ( int idRegistro )
{
using var connection = _cf . CreateConnection ( ) ;
const string sql = @ "
SELECT Id_Registro AS IdRegistro , Id_Canilla AS IdCanilla , Parada , VigenciaD , VigenciaH
FROM dbo . dist_CambiosParadasCanillas
WHERE Id_Registro = @IdRegistro ; ";
return await connection . QuerySingleOrDefaultAsync < CambioParadaCanilla > ( sql , new { IdRegistro = idRegistro } ) ;
}
public async Task < CambioParadaCanilla ? > GetCurrentParadaAsync ( int idCanilla , IDbTransaction ? transaction = null )
{
const string sql = @ "
SELECT TOP 1 Id_Registro AS IdRegistro , Id_Canilla AS IdCanilla , Parada , VigenciaD , VigenciaH
FROM dbo . dist_CambiosParadasCanillas
WHERE Id_Canilla = @IdCanilla AND VigenciaH IS NULL
ORDER BY VigenciaD DESC , Id_Registro DESC ; "; // Por si hay un error y quedaron varias abiertas
var conn = transaction ? . Connection ? ? _cf . CreateConnection ( ) ;
bool manageConnection = transaction = = null ;
if ( manageConnection & & conn . State ! = ConnectionState . Open ) { if ( conn is System . Data . Common . DbConnection dbConn ) await dbConn . OpenAsync ( ) ; else conn . Open ( ) ; }
try
{
return await conn . QuerySingleOrDefaultAsync < CambioParadaCanilla > ( sql , new { IdCanilla = idCanilla } , transaction ) ;
}
finally
{
if ( manageConnection & & conn . State = = ConnectionState . Open ) { if ( conn is System . Data . Common . DbConnection dbConn ) await dbConn . CloseAsync ( ) ; else conn . Close ( ) ; }
}
}
public async Task < CambioParadaCanilla ? > CreateAsync ( CambioParadaCanilla nuevaParada , int idUsuario , IDbTransaction transaction )
{
const string sqlInsert = @ "
INSERT INTO dbo . dist_CambiosParadasCanillas ( Id_Canilla , Parada , VigenciaD , VigenciaH )
OUTPUT INSERTED . Id_Registro AS IdRegistro , INSERTED . Id_Canilla AS IdCanilla , INSERTED . Parada , INSERTED . VigenciaD , INSERTED . VigenciaH
VALUES ( @IdCanilla , @Parada , @VigenciaD , @VigenciaH ) ; ";
// VigenciaH es null al crear una nueva parada activa
var inserted = await transaction . Connection ! . QuerySingleAsync < CambioParadaCanilla > ( sqlInsert ,
new { nuevaParada . IdCanilla , nuevaParada . Parada , nuevaParada . VigenciaD , VigenciaH = ( DateTime ? ) null } ,
transaction ) ;
if ( inserted = = null | | inserted . IdRegistro = = 0 ) throw new DataException ( "Error al crear cambio de parada o ID no generado." ) ;
await LogHistorialAsync ( inserted , idUsuario , "Creada" , transaction . Connection ! , transaction ) ;
return inserted ;
}
public async Task < bool > UpdateVigenciaHAsync ( int idRegistro , DateTime vigenciaH , int idUsuario , IDbTransaction transaction )
2025-06-12 19:36:21 -03:00
{
var paradaOriginal = await GetByIdAsync ( idRegistro ) ;
if ( paradaOriginal = = null ) throw new KeyNotFoundException ( "Registro de parada no encontrado para actualizar VigenciaH." ) ;
var paradaParaHistorial = new CambioParadaCanilla
2025-06-09 19:37:07 -03:00
{
2025-06-12 19:36:21 -03:00
IdRegistro = paradaOriginal . IdRegistro ,
IdCanilla = paradaOriginal . IdCanilla ,
Parada = paradaOriginal . Parada ,
VigenciaD = paradaOriginal . VigenciaD ,
VigenciaH = vigenciaH . Date
} ;
2025-06-09 19:37:07 -03:00
2025-06-12 19:36:21 -03:00
// Loggear el estado que QUEDARÁ en la tabla principal (con la VigenciaH actualizada)
// El TipoMod debería reflejar la acción. "Cerrada".
await LogHistorialAsync ( paradaParaHistorial , idUsuario , "Cerrada" , transaction . Connection ! , transaction ) ;
2025-06-09 19:37:07 -03:00
2025-06-12 19:36:21 -03:00
const string sqlUpdate = @ "
2025-06-09 19:37:07 -03:00
UPDATE dbo . dist_CambiosParadasCanillas
SET VigenciaH = @VigenciaH
WHERE Id_Registro = @IdRegistro ; ";
2025-06-12 19:36:21 -03:00
var rowsAffected = await transaction . Connection ! . ExecuteAsync ( sqlUpdate ,
2025-06-09 19:37:07 -03:00
new { VigenciaH = vigenciaH . Date , IdRegistro = idRegistro } ,
transaction ) ;
2025-06-12 19:36:21 -03:00
return rowsAffected = = 1 ;
}
2025-06-09 19:37:07 -03:00
public async Task < bool > DeleteAsync ( int idRegistro , int idUsuario , IDbTransaction transaction )
{
var paradaOriginal = await GetByIdAsync ( idRegistro ) ;
if ( paradaOriginal = = null ) throw new KeyNotFoundException ( "Registro de parada no encontrado para eliminar." ) ;
// Loggear ANTES de eliminar
await LogHistorialAsync ( paradaOriginal , idUsuario , "Eliminada" , transaction . Connection ! , transaction ) ;
const string sqlDelete = "DELETE FROM dbo.dist_CambiosParadasCanillas WHERE Id_Registro = @IdRegistro;" ;
var rowsAffected = await transaction . Connection ! . ExecuteAsync ( sqlDelete , new { IdRegistro = idRegistro } , transaction ) ;
return rowsAffected = = 1 ;
}
2025-06-12 19:36:21 -03:00
public async Task < IEnumerable < ( CambioParadaCanillaHistorial Historial , string NombreUsuarioModifico , string NombreCanilla ) > > GetCambiosParadaHistorialAsync (
DateTime ? fechaDesde , DateTime ? fechaHasta ,
int? idUsuarioModifico , string? tipoModificacion ,
int? idCanillaOriginal )
{
using var connection = _cf . CreateConnection ( ) ;
var sqlBuilder = new StringBuilder ( @ "
SELECT
h . Id_Registro , h . Id_Canilla , h . Parada , h . VigenciaD , h . VigenciaH ,
h . Id_Usuario , h . FechaMod , h . TipoMod ,
u . Nombre + ' ' + u . Apellido AS NombreUsuarioModifico ,
c . NomApe AS NombreCanilla
FROM dbo . dist_CambiosParadasCanillas_H h
JOIN dbo . gral_Usuarios u ON h . Id_Usuario = u . Id
JOIN dbo . dist_dtCanillas c ON h . Id_Canilla = c . Id_Canilla
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 ( idCanillaOriginal . HasValue ) { sqlBuilder . Append ( " AND h.Id_Canilla = @IdCanillaOriginalParam" ) ; parameters . Add ( "IdCanillaOriginalParam" , idCanillaOriginal . Value ) ; }
sqlBuilder . Append ( " ORDER BY h.FechaMod DESC;" ) ;
try
{
var result = await connection . QueryAsync < CambioParadaCanillaHistorial , string , string , ( CambioParadaCanillaHistorial , string , string ) > (
sqlBuilder . ToString ( ) ,
( hist , userMod , canillaNombre ) = > ( hist , userMod , canillaNombre ) ,
parameters ,
splitOn : "NombreUsuarioModifico,NombreCanilla"
) ;
return result ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error al obtener historial de Cambios de Parada." ) ;
return Enumerable . Empty < ( CambioParadaCanillaHistorial , string , string ) > ( ) ;
}
}
2025-06-09 19:37:07 -03:00
}
}