Files
GestionIntegralWeb/Backend/GestionIntegral.Api/Data/Repositories/Contables/NotaCreditoDebitoRepository.cs

153 lines
8.8 KiB
C#

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 NotaCreditoDebitoRepository : INotaCreditoDebitoRepository
{
private readonly DbConnectionFactory _cf;
private readonly ILogger<NotaCreditoDebitoRepository> _log;
public NotaCreditoDebitoRepository(DbConnectionFactory cf, ILogger<NotaCreditoDebitoRepository> log)
{
_cf = cf;
_log = log;
}
private string SelectQueryBase() => @"
SELECT
Id_Nota AS IdNota, Destino, Id_Destino AS IdDestino, Referencia, Tipo, Fecha,
Monto, Observaciones, Id_Empresa AS IdEmpresa
FROM dbo.cue_CreditosDebitos";
public async Task<IEnumerable<NotaCreditoDebito>> GetAllAsync(
DateTime? fechaDesde, DateTime? fechaHasta,
string? destino, int? idDestino, int? idEmpresa, string? tipoNota)
{
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 (!string.IsNullOrWhiteSpace(destino)) { sqlBuilder.Append(" AND Destino = @DestinoParam"); parameters.Add("DestinoParam", destino); }
if (idDestino.HasValue) { sqlBuilder.Append(" AND Id_Destino = @IdDestinoParam"); parameters.Add("IdDestinoParam", idDestino.Value); }
if (idEmpresa.HasValue) { sqlBuilder.Append(" AND Id_Empresa = @IdEmpresaParam"); parameters.Add("IdEmpresaParam", idEmpresa.Value); }
if (!string.IsNullOrWhiteSpace(tipoNota)) { sqlBuilder.Append(" AND Tipo = @TipoParam"); parameters.Add("TipoParam", tipoNota); }
sqlBuilder.Append(" ORDER BY Fecha DESC, Id_Nota DESC;");
try
{
using var connection = _cf.CreateConnection();
return await connection.QueryAsync<NotaCreditoDebito>(sqlBuilder.ToString(), parameters);
}
catch (Exception ex)
{
_log.LogError(ex, "Error al obtener todas las Notas de Crédito/Débito.");
return Enumerable.Empty<NotaCreditoDebito>();
}
}
public async Task<NotaCreditoDebito?> GetByIdAsync(int idNota)
{
var sql = SelectQueryBase() + " WHERE Id_Nota = @IdNotaParam";
try
{
using var connection = _cf.CreateConnection();
return await connection.QuerySingleOrDefaultAsync<NotaCreditoDebito>(sql, new { IdNotaParam = idNota });
}
catch (Exception ex)
{
_log.LogError(ex, "Error al obtener Nota C/D por ID: {IdNota}", idNota);
return null;
}
}
public async Task<NotaCreditoDebito?> CreateAsync(NotaCreditoDebito nuevaNota, int idUsuario, IDbTransaction transaction)
{
const string sqlInsert = @"
INSERT INTO dbo.cue_CreditosDebitos (Destino, Id_Destino, Referencia, Tipo, Fecha, Monto, Observaciones, Id_Empresa)
OUTPUT INSERTED.Id_Nota AS IdNota, INSERTED.Destino, INSERTED.Id_Destino AS IdDestino, INSERTED.Referencia,
INSERTED.Tipo, INSERTED.Fecha, INSERTED.Monto, INSERTED.Observaciones, INSERTED.Id_Empresa AS IdEmpresa
VALUES (@Destino, @IdDestino, @Referencia, @Tipo, @Fecha, @Monto, @Observaciones, @IdEmpresa);";
const string sqlHistorico = @"
INSERT INTO dbo.cue_CreditosDebitos_H
(Id_Nota, Destino, Id_Destino, Referencia, Tipo, Fecha, Monto, Observaciones, Id_Empresa, Id_Usuario, FechaMod, TipoMod)
VALUES (@IdNotaHist, @DestinoHist, @IdDestinoHist, @ReferenciaHist, @TipoHist, @FechaHist, @MontoHist, @ObservacionesHist, @IdEmpresaHist, @IdUsuarioHist, @FechaModHist, @TipoModHist);";
var inserted = await transaction.Connection!.QuerySingleAsync<NotaCreditoDebito>(sqlInsert, nuevaNota, transaction);
if (inserted == null || inserted.IdNota == 0) throw new DataException("Error al crear la nota o ID no generado.");
await transaction.Connection!.ExecuteAsync(sqlHistorico, new {
IdNotaHist = inserted.IdNota, DestinoHist = inserted.Destino, IdDestinoHist = inserted.IdDestino,
ReferenciaHist = inserted.Referencia, TipoHist = inserted.Tipo, FechaHist = inserted.Fecha, MontoHist = inserted.Monto,
ObservacionesHist = inserted.Observaciones, IdEmpresaHist = inserted.IdEmpresa,
IdUsuarioHist = idUsuario, FechaModHist = DateTime.Now, TipoModHist = "Creada"
}, transaction);
return inserted;
}
public async Task<bool> UpdateAsync(NotaCreditoDebito notaAActualizar, int idUsuario, IDbTransaction transaction)
{
var actual = await transaction.Connection!.QuerySingleOrDefaultAsync<NotaCreditoDebito>(
SelectQueryBase() + " WHERE Id_Nota = @IdNotaParam",
new { IdNotaParam = notaAActualizar.IdNota }, transaction);
if (actual == null) throw new KeyNotFoundException("Nota de Crédito/Débito no encontrada.");
// Solo se permite actualizar Monto y Observaciones
const string sqlUpdate = @"
UPDATE dbo.cue_CreditosDebitos SET
Monto = @Monto, Observaciones = @Observaciones
WHERE Id_Nota = @IdNota;";
const string sqlHistorico = @"
INSERT INTO dbo.cue_CreditosDebitos_H
(Id_Nota, Destino, Id_Destino, Referencia, Tipo, Fecha, Monto, Observaciones, Id_Empresa, Id_Usuario, FechaMod, TipoMod)
VALUES (@IdNotaHist, @DestinoHist, @IdDestinoHist, @ReferenciaHist, @TipoHist, @FechaHist, @MontoHist, @ObservacionesHist, @IdEmpresaHist, @IdUsuarioHist, @FechaModHist, @TipoModHist);";
await transaction.Connection!.ExecuteAsync(sqlHistorico, new {
IdNotaHist = actual.IdNota, DestinoHist = actual.Destino, IdDestinoHist = actual.IdDestino, ReferenciaHist = actual.Referencia,
TipoHist = actual.Tipo, FechaHist = actual.Fecha, MontoHist = actual.Monto, // Valor ANTERIOR
ObservacionesHist = actual.Observaciones, IdEmpresaHist = actual.IdEmpresa, // Valor ANTERIOR
IdUsuarioHist = idUsuario, FechaModHist = DateTime.Now, TipoModHist = "Actualizada"
}, transaction);
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlUpdate, new {
notaAActualizar.Monto,
notaAActualizar.Observaciones,
notaAActualizar.IdNota
} , transaction);
return rowsAffected == 1;
}
public async Task<bool> DeleteAsync(int idNota, int idUsuario, IDbTransaction transaction)
{
var actual = await transaction.Connection!.QuerySingleOrDefaultAsync<NotaCreditoDebito>(
SelectQueryBase() + " WHERE Id_Nota = @IdNotaParam",
new { IdNotaParam = idNota }, transaction);
if (actual == null) throw new KeyNotFoundException("Nota de Crédito/Débito no encontrada para eliminar.");
const string sqlDelete = "DELETE FROM dbo.cue_CreditosDebitos WHERE Id_Nota = @IdNotaParam";
const string sqlHistorico = @"
INSERT INTO dbo.cue_CreditosDebitos_H
(Id_Nota, Destino, Id_Destino, Referencia, Tipo, Fecha, Monto, Observaciones, Id_Empresa, Id_Usuario, FechaMod, TipoMod)
VALUES (@IdNotaHist, @DestinoHist, @IdDestinoHist, @ReferenciaHist, @TipoHist, @FechaHist, @MontoHist, @ObservacionesHist, @IdEmpresaHist, @IdUsuarioHist, @FechaModHist, @TipoModHist);";
await transaction.Connection!.ExecuteAsync(sqlHistorico, new {
IdNotaHist = actual.IdNota, DestinoHist = actual.Destino, IdDestinoHist = actual.IdDestino, ReferenciaHist = actual.Referencia,
TipoHist = actual.Tipo, FechaHist = actual.Fecha, MontoHist = actual.Monto, ObservacionesHist = actual.Observaciones, IdEmpresaHist = actual.IdEmpresa,
IdUsuarioHist = idUsuario, FechaModHist = DateTime.Now, TipoModHist = "Eliminada"
}, transaction);
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlDelete, new { IdNotaParam = idNota }, transaction);
return rowsAffected == 1;
}
}
}