2025-06-06 18:33:09 -03:00
using Dapper ;
using GestionIntegral.Api.Models.Distribucion ;
using Microsoft.Extensions.Configuration ; // Para IConfiguration
using Microsoft.Extensions.Logging ;
using System ;
using System.Collections.Generic ;
using System.Data ;
using Microsoft.Data.SqlClient ; // O el proveedor de tu BD
using System.Linq ;
using System.Threading.Tasks ;
using GestionIntegral.Api.Dtos.Reportes ;
2025-06-09 19:37:07 -03:00
using System.Text ;
2025-06-06 18:33:09 -03:00
namespace GestionIntegral.Api.Data.Repositories.Distribucion
{
public class NovedadCanillaRepository : INovedadCanillaRepository
{
private readonly DbConnectionFactory _connectionFactory ; // Inyecta tu DbConnectionFactory
private readonly ILogger < NovedadCanillaRepository > _logger ;
public NovedadCanillaRepository ( DbConnectionFactory connectionFactory , ILogger < NovedadCanillaRepository > logger )
{
_connectionFactory = connectionFactory ;
_logger = logger ;
}
private async Task LogHistorialAsync ( NovedadCanilla novedadOriginal , int idUsuario , string tipoMod , IDbConnection connection , IDbTransaction ? transaction )
{
var historial = new NovedadCanillaHistorial
{
IdNovedad = novedadOriginal . IdNovedad ,
IdCanilla = novedadOriginal . IdCanilla ,
Fecha = novedadOriginal . Fecha ,
Detalle = novedadOriginal . Detalle ,
IdUsuario = idUsuario ,
FechaMod = DateTime . Now ,
TipoMod = tipoMod
} ;
var sqlHistorial = @ "
INSERT INTO dbo . dist_dtNovedadesCanillas_H
( Id_Novedad , Id_Canilla , Fecha , Detalle , Id_Usuario , FechaMod , TipoMod )
VALUES
( @IdNovedad , @IdCanilla , @Fecha , @Detalle , @IdUsuario , @FechaMod , @TipoMod ) ; ";
await connection . ExecuteAsync ( sqlHistorial , historial , transaction ) ;
}
public async Task < IEnumerable < ( NovedadCanilla Novedad , string NombreCanilla ) > > GetByCanillaAsync ( int idCanilla , DateTime ? fechaDesde , DateTime ? fechaHasta )
{
using var connection = _connectionFactory . CreateConnection ( ) ;
var sqlBuilder = new System . Text . StringBuilder ( @ "
SELECT
n . Id_Novedad AS IdNovedad ,
n . Id_Canilla AS IdCanilla ,
n . Fecha ,
n . Detalle ,
c . NomApe AS NombreCanilla
FROM dbo . dist_dtNovedadesCanillas n
JOIN dbo . dist_dtCanillas c ON n . Id_Canilla = c . Id_Canilla
WHERE n . Id_Canilla = @IdCanilla ");
var parameters = new DynamicParameters ( ) ;
parameters . Add ( "IdCanilla" , idCanilla ) ;
if ( fechaDesde . HasValue )
{
sqlBuilder . Append ( " AND n.Fecha >= @FechaDesde" ) ;
parameters . Add ( "FechaDesde" , fechaDesde . Value . Date ) ; // Solo fecha, sin hora
}
if ( fechaHasta . HasValue )
{
sqlBuilder . Append ( " AND n.Fecha <= @FechaHasta" ) ;
// Para incluir todo el día de fechaHasta
parameters . Add ( "FechaHasta" , fechaHasta . Value . Date . AddDays ( 1 ) . AddTicks ( - 1 ) ) ;
}
sqlBuilder . Append ( " ORDER BY n.Fecha DESC, n.Id_Novedad DESC;" ) ;
var result = await connection . QueryAsync < NovedadCanilla , string , ( NovedadCanilla , string ) > (
sqlBuilder . ToString ( ) ,
( novedad , nombreCanilla ) = > ( novedad , nombreCanilla ) ,
parameters ,
splitOn : "NombreCanilla"
) ;
return result ;
}
public async Task < NovedadCanilla ? > GetByIdAsync ( int idNovedad )
{
using var connection = _connectionFactory . CreateConnection ( ) ;
var sql = "SELECT Id_Novedad AS IdNovedad, Id_Canilla AS IdCanilla, Fecha, Detalle FROM dbo.dist_dtNovedadesCanillas WHERE Id_Novedad = @IdNovedad;" ;
return await connection . QuerySingleOrDefaultAsync < NovedadCanilla > ( sql , new { IdNovedad = idNovedad } ) ;
}
public async Task < bool > ExistsByCanillaAndFechaAsync ( int idCanilla , DateTime fecha , int? excludeIdNovedad = null )
{
using var connection = _connectionFactory . CreateConnection ( ) ;
var sqlBuilder = new System . Text . StringBuilder ( "SELECT COUNT(1) FROM dbo.dist_dtNovedadesCanillas WHERE Id_Canilla = @IdCanilla AND Fecha = @Fecha" ) ;
var parameters = new DynamicParameters ( ) ;
parameters . Add ( "IdCanilla" , idCanilla ) ;
parameters . Add ( "Fecha" , fecha . Date ) ; // Comparar solo la fecha
if ( excludeIdNovedad . HasValue )
{
sqlBuilder . Append ( " AND Id_Novedad != @ExcludeIdNovedad" ) ;
parameters . Add ( "ExcludeIdNovedad" , excludeIdNovedad . Value ) ;
}
var count = await connection . ExecuteScalarAsync < int > ( sqlBuilder . ToString ( ) , parameters ) ;
return count > 0 ;
}
public async Task < NovedadCanilla ? > CreateAsync ( NovedadCanilla novedad , int idUsuario , IDbTransaction ? transaction = null )
{
var sql = @ "
INSERT INTO dbo . dist_dtNovedadesCanillas ( Id_Canilla , Fecha , Detalle )
VALUES ( @IdCanilla , @Fecha , @Detalle ) ;
SELECT CAST ( SCOPE_IDENTITY ( ) as int ) ; ";
IDbConnection conn = transaction ? . Connection ? ? _connectionFactory . CreateConnection ( ) ;
bool manageConnection = transaction = = null ; // Solo gestionar si no hay transacción externa
try
{
if ( manageConnection & & conn . State ! = ConnectionState . Open ) await ( conn as SqlConnection ) ! . OpenAsync ( ) ;
var newId = await conn . QuerySingleAsync < int > ( sql , novedad , transaction ) ;
novedad . IdNovedad = newId ;
await LogHistorialAsync ( novedad , idUsuario , "Insertada" , conn , transaction ) ;
return novedad ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error al crear NovedadCanilla para Canilla ID: {IdCanilla}" , novedad . IdCanilla ) ;
return null ;
}
finally
{
if ( manageConnection & & conn . State = = ConnectionState . Open ) conn . Close ( ) ;
}
}
public async Task < bool > UpdateAsync ( NovedadCanilla novedad , int idUsuario , IDbTransaction ? transaction = null )
{
var novedadOriginal = await GetByIdAsync ( novedad . IdNovedad ) ; // Necesitamos el estado original para el log
if ( novedadOriginal = = null ) return false ; // No se encontró
var sql = @ "
UPDATE dbo . dist_dtNovedadesCanillas SET
Detalle = @Detalle
- - No se permite cambiar IdCanilla ni Fecha de una novedad existente
WHERE Id_Novedad = @IdNovedad ; ";
IDbConnection conn = transaction ? . Connection ? ? _connectionFactory . CreateConnection ( ) ;
bool manageConnection = transaction = = null ;
try
{
if ( manageConnection & & conn . State ! = ConnectionState . Open ) await ( conn as SqlConnection ) ! . OpenAsync ( ) ;
await LogHistorialAsync ( novedadOriginal , idUsuario , "Modificada" , conn , transaction ) ; // Log con datos ANTES de actualizar
var affectedRows = await conn . ExecuteAsync ( sql , novedad , transaction ) ;
return affectedRows > 0 ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error al actualizar NovedadCanilla ID: {IdNovedad}" , novedad . IdNovedad ) ;
return false ;
}
finally
{
if ( manageConnection & & conn . State = = ConnectionState . Open ) conn . Close ( ) ;
}
}
public async Task < bool > DeleteAsync ( int idNovedad , int idUsuario , IDbTransaction ? transaction = null )
{
var novedadOriginal = await GetByIdAsync ( idNovedad ) ;
if ( novedadOriginal = = null ) return false ;
var sql = "DELETE FROM dbo.dist_dtNovedadesCanillas WHERE Id_Novedad = @IdNovedad;" ;
IDbConnection conn = transaction ? . Connection ? ? _connectionFactory . CreateConnection ( ) ;
bool manageConnection = transaction = = null ;
try
{
if ( manageConnection & & conn . State ! = ConnectionState . Open ) await ( conn as SqlConnection ) ! . OpenAsync ( ) ;
await LogHistorialAsync ( novedadOriginal , idUsuario , "Eliminada" , conn , transaction ) ;
var affectedRows = await conn . ExecuteAsync ( sql , new { IdNovedad = idNovedad } , transaction ) ;
return affectedRows > 0 ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error al eliminar NovedadCanilla ID: {IdNovedad}" , idNovedad ) ;
return false ;
}
finally
{
if ( manageConnection & & conn . State = = ConnectionState . Open ) conn . Close ( ) ;
}
}
public async Task < IEnumerable < NovedadesCanillasReporteDto > > GetReporteNovedadesAsync ( int idEmpresa , DateTime fechaDesde , DateTime fechaHasta )
{
using var connection = _connectionFactory . CreateConnection ( ) ;
var parameters = new
{
idEmpresa ,
fechaDesde = fechaDesde . Date , // Enviar solo la fecha
fechaHasta = fechaHasta . Date . AddDays ( 1 ) . AddTicks ( - 1 ) // Para incluir todo el día hasta las 23:59:59.999...
} ;
// El nombre del SP en el archivo es SP_DistCanillasNovedades
return await connection . QueryAsync < NovedadesCanillasReporteDto > (
"dbo.SP_DistCanillasNovedades" , // Asegúrate que el nombre del SP sea exacto
parameters ,
commandType : CommandType . StoredProcedure
) ;
}
public async Task < IEnumerable < CanillaGananciaReporteDto > > GetReporteGananciasAsync ( int idEmpresa , DateTime fechaDesde , DateTime fechaHasta )
{
using var connection = _connectionFactory . CreateConnection ( ) ;
var parameters = new
{
idEmpresa ,
fechaDesde = fechaDesde . Date ,
fechaHasta = fechaHasta . Date // El SP SP_DistCanillasGanancias maneja el rango inclusivo directamente
} ;
return await connection . QueryAsync < CanillaGananciaReporteDto > (
"dbo.SP_DistCanillasGanancias" , // Nombre del SP
parameters ,
commandType : CommandType . StoredProcedure
) ;
}
2025-06-09 19:37:07 -03:00
public async Task < IEnumerable < ( NovedadCanillaHistorico Historial , string NombreUsuarioModifico ) > > GetHistorialAsync (
DateTime ? fechaDesde , DateTime ? fechaHasta ,
int? idUsuarioModifico , string? tipoModificacion ,
int? idNovedadOriginal )
{
using var connection = _connectionFactory . CreateConnection ( ) ;
var sqlBuilder = new StringBuilder ( @ "
SELECT
h . Id_Novedad , h . Id_Canilla , h . Fecha , h . Detalle ,
h . Id_Usuario , h . FechaMod , h . TipoMod ,
u . Nombre + ' ' + u . Apellido AS NombreUsuarioModifico
FROM dbo . dist_dtNovedadesCanillas_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 ( idNovedadOriginal . HasValue ) { sqlBuilder . Append ( " AND h.Id_Novedad = @IdNovedadOriginalParam" ) ; parameters . Add ( "IdNovedadOriginalParam" , idNovedadOriginal . Value ) ; }
sqlBuilder . Append ( " ORDER BY h.FechaMod DESC;" ) ;
try
{
var result = await connection . QueryAsync < NovedadCanillaHistorico , string , ( NovedadCanillaHistorico , string ) > (
sqlBuilder . ToString ( ) ,
( hist , userName ) = > ( hist , userName ) ,
parameters ,
splitOn : "NombreUsuarioModifico"
) ;
return result ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error al obtener historial de Novedades de Canillitas." ) ;
return Enumerable . Empty < ( NovedadCanillaHistorico , string ) > ( ) ;
}
}
2025-06-06 18:33:09 -03:00
}
}