Ya perdí el hilo de los cambios pero ahi van.
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
using GestionIntegral.Api.Dtos.Contables;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GestionIntegral.Api.Services.Contables
|
||||
{
|
||||
public interface INotaCreditoDebitoService
|
||||
{
|
||||
Task<IEnumerable<NotaCreditoDebitoDto>> ObtenerTodosAsync(
|
||||
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||
string? destino, int? idDestino, int? idEmpresa, string? tipoNota);
|
||||
|
||||
Task<NotaCreditoDebitoDto?> ObtenerPorIdAsync(int idNota);
|
||||
Task<(NotaCreditoDebitoDto? Nota, string? Error)> CrearAsync(CreateNotaDto createDto, int idUsuario);
|
||||
Task<(bool Exito, string? Error)> ActualizarAsync(int idNota, UpdateNotaDto updateDto, int idUsuario);
|
||||
Task<(bool Exito, string? Error)> EliminarAsync(int idNota, int idUsuario);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using GestionIntegral.Api.Dtos.Contables;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GestionIntegral.Api.Services.Contables
|
||||
{
|
||||
public interface IPagoDistribuidorService
|
||||
{
|
||||
Task<IEnumerable<PagoDistribuidorDto>> ObtenerTodosAsync(
|
||||
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||
int? idDistribuidor, int? idEmpresa, string? tipoMovimiento);
|
||||
|
||||
Task<PagoDistribuidorDto?> ObtenerPorIdAsync(int idPago);
|
||||
Task<(PagoDistribuidorDto? Pago, string? Error)> CrearAsync(CreatePagoDistribuidorDto createDto, int idUsuario);
|
||||
Task<(bool Exito, string? Error)> ActualizarAsync(int idPago, UpdatePagoDistribuidorDto updateDto, int idUsuario);
|
||||
Task<(bool Exito, string? Error)> EliminarAsync(int idPago, int idUsuario);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
using GestionIntegral.Api.Data;
|
||||
using GestionIntegral.Api.Data.Repositories.Contables;
|
||||
using GestionIntegral.Api.Data.Repositories.Distribucion;
|
||||
using GestionIntegral.Api.Dtos.Contables;
|
||||
using GestionIntegral.Api.Models.Contables;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GestionIntegral.Api.Services.Contables
|
||||
{
|
||||
public class NotaCreditoDebitoService : INotaCreditoDebitoService
|
||||
{
|
||||
private readonly INotaCreditoDebitoRepository _notaRepo;
|
||||
private readonly IDistribuidorRepository _distribuidorRepo;
|
||||
private readonly ICanillaRepository _canillaRepo;
|
||||
private readonly IEmpresaRepository _empresaRepo;
|
||||
private readonly ISaldoRepository _saldoRepo;
|
||||
private readonly DbConnectionFactory _connectionFactory;
|
||||
private readonly ILogger<NotaCreditoDebitoService> _logger;
|
||||
|
||||
public NotaCreditoDebitoService(
|
||||
INotaCreditoDebitoRepository notaRepo,
|
||||
IDistribuidorRepository distribuidorRepo,
|
||||
ICanillaRepository canillaRepo,
|
||||
IEmpresaRepository empresaRepo,
|
||||
ISaldoRepository saldoRepo,
|
||||
DbConnectionFactory connectionFactory,
|
||||
ILogger<NotaCreditoDebitoService> logger)
|
||||
{
|
||||
_notaRepo = notaRepo;
|
||||
_distribuidorRepo = distribuidorRepo;
|
||||
_canillaRepo = canillaRepo;
|
||||
_empresaRepo = empresaRepo;
|
||||
_saldoRepo = saldoRepo;
|
||||
_connectionFactory = connectionFactory;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
private async Task<NotaCreditoDebitoDto> MapToDto(NotaCreditoDebito nota)
|
||||
{
|
||||
if (nota == null) return null!;
|
||||
|
||||
string nombreDestinatario = "N/A";
|
||||
if (nota.Destino == "Distribuidores")
|
||||
{
|
||||
var distData = await _distribuidorRepo.GetByIdAsync(nota.IdDestino);
|
||||
nombreDestinatario = distData.Distribuidor?.Nombre ?? "Distribuidor Desconocido";
|
||||
}
|
||||
else if (nota.Destino == "Canillas")
|
||||
{
|
||||
var canData = await _canillaRepo.GetByIdAsync(nota.IdDestino); // Asumiendo que GetByIdAsync devuelve una tupla
|
||||
nombreDestinatario = canData.Canilla?.NomApe ?? "Canillita Desconocido";
|
||||
}
|
||||
|
||||
var empresa = await _empresaRepo.GetByIdAsync(nota.IdEmpresa);
|
||||
|
||||
return new NotaCreditoDebitoDto
|
||||
{
|
||||
IdNota = nota.IdNota,
|
||||
Destino = nota.Destino,
|
||||
IdDestino = nota.IdDestino,
|
||||
NombreDestinatario = nombreDestinatario,
|
||||
Referencia = nota.Referencia,
|
||||
Tipo = nota.Tipo,
|
||||
Fecha = nota.Fecha.ToString("yyyy-MM-dd"),
|
||||
Monto = nota.Monto,
|
||||
Observaciones = nota.Observaciones,
|
||||
IdEmpresa = nota.IdEmpresa,
|
||||
NombreEmpresa = empresa?.Nombre ?? "Empresa Desconocida"
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<NotaCreditoDebitoDto>> ObtenerTodosAsync(
|
||||
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||
string? destino, int? idDestino, int? idEmpresa, string? tipoNota)
|
||||
{
|
||||
var notas = await _notaRepo.GetAllAsync(fechaDesde, fechaHasta, destino, idDestino, idEmpresa, tipoNota);
|
||||
var dtos = new List<NotaCreditoDebitoDto>();
|
||||
foreach (var nota in notas)
|
||||
{
|
||||
dtos.Add(await MapToDto(nota));
|
||||
}
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<NotaCreditoDebitoDto?> ObtenerPorIdAsync(int idNota)
|
||||
{
|
||||
var nota = await _notaRepo.GetByIdAsync(idNota);
|
||||
return nota == null ? null : await MapToDto(nota);
|
||||
}
|
||||
|
||||
public async Task<(NotaCreditoDebitoDto? Nota, string? Error)> CrearAsync(CreateNotaDto createDto, int idUsuario)
|
||||
{
|
||||
// Validar Destinatario
|
||||
if (createDto.Destino == "Distribuidores")
|
||||
{
|
||||
if (await _distribuidorRepo.GetByIdSimpleAsync(createDto.IdDestino) == null)
|
||||
return (null, "El distribuidor especificado no existe.");
|
||||
}
|
||||
else if (createDto.Destino == "Canillas")
|
||||
{
|
||||
if (await _canillaRepo.GetByIdSimpleAsync(createDto.IdDestino) == null) // Asumiendo GetByIdSimpleAsync en ICanillaRepository
|
||||
return (null, "El canillita especificado no existe.");
|
||||
}
|
||||
else { return (null, "Tipo de destino inválido."); }
|
||||
|
||||
if (await _empresaRepo.GetByIdAsync(createDto.IdEmpresa) == null)
|
||||
return (null, "La empresa especificada no existe.");
|
||||
|
||||
var nuevaNota = new NotaCreditoDebito
|
||||
{
|
||||
Destino = createDto.Destino,
|
||||
IdDestino = createDto.IdDestino,
|
||||
Referencia = createDto.Referencia,
|
||||
Tipo = createDto.Tipo,
|
||||
Fecha = createDto.Fecha.Date,
|
||||
Monto = createDto.Monto,
|
||||
Observaciones = createDto.Observaciones,
|
||||
IdEmpresa = createDto.IdEmpresa
|
||||
};
|
||||
|
||||
using var connection = _connectionFactory.CreateConnection();
|
||||
if (connection is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else connection.Open();
|
||||
using var transaction = connection.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var notaCreada = await _notaRepo.CreateAsync(nuevaNota, idUsuario, transaction);
|
||||
if (notaCreada == null) throw new DataException("Error al registrar la nota.");
|
||||
|
||||
// Afectar Saldo
|
||||
// Nota de Crédito: Disminuye la deuda del destinatario (monto positivo para el servicio de saldo)
|
||||
// Nota de Débito: Aumenta la deuda del destinatario (monto negativo para el servicio de saldo)
|
||||
decimal montoAjusteSaldo = createDto.Tipo == "Credito" ? createDto.Monto : -createDto.Monto;
|
||||
|
||||
bool saldoActualizado = await _saldoRepo.ModificarSaldoAsync(notaCreada.Destino, notaCreada.IdDestino, notaCreada.IdEmpresa, montoAjusteSaldo, transaction);
|
||||
if (!saldoActualizado) throw new DataException($"Error al actualizar el saldo para {notaCreada.Destino} ID {notaCreada.IdDestino}.");
|
||||
|
||||
transaction.Commit();
|
||||
_logger.LogInformation("NotaC/D ID {Id} creada y saldo afectado por Usuario ID {UserId}.", notaCreada.IdNota, idUsuario);
|
||||
return (await MapToDto(notaCreada), null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { transaction.Rollback(); } catch { }
|
||||
_logger.LogError(ex, "Error CrearAsync NotaCreditoDebito.");
|
||||
return (null, $"Error interno: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<(bool Exito, string? Error)> ActualizarAsync(int idNota, UpdateNotaDto updateDto, int idUsuario)
|
||||
{
|
||||
using var connection = _connectionFactory.CreateConnection();
|
||||
if (connection is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else connection.Open();
|
||||
using var transaction = connection.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var notaExistente = await _notaRepo.GetByIdAsync(idNota);
|
||||
if (notaExistente == null) return (false, "Nota no encontrada.");
|
||||
|
||||
// Calcular diferencia de monto para ajustar saldo
|
||||
decimal montoOriginal = notaExistente.Tipo == "Credito" ? notaExistente.Monto : -notaExistente.Monto;
|
||||
decimal montoNuevo = notaExistente.Tipo == "Credito" ? updateDto.Monto : -updateDto.Monto; // Tipo no cambia
|
||||
decimal diferenciaAjusteSaldo = montoNuevo - montoOriginal;
|
||||
|
||||
notaExistente.Monto = updateDto.Monto;
|
||||
notaExistente.Observaciones = updateDto.Observaciones;
|
||||
|
||||
var actualizado = await _notaRepo.UpdateAsync(notaExistente, idUsuario, transaction);
|
||||
if (!actualizado) throw new DataException("Error al actualizar la nota.");
|
||||
|
||||
if (diferenciaAjusteSaldo != 0)
|
||||
{
|
||||
bool saldoActualizado = await _saldoRepo.ModificarSaldoAsync(notaExistente.Destino, notaExistente.IdDestino, notaExistente.IdEmpresa, diferenciaAjusteSaldo, transaction);
|
||||
if (!saldoActualizado) throw new DataException("Error al ajustar el saldo tras la actualización de la nota.");
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
_logger.LogInformation("NotaC/D ID {Id} actualizada por Usuario ID {UserId}.", idNota, idUsuario);
|
||||
return (true, null);
|
||||
}
|
||||
catch (KeyNotFoundException) { try { transaction.Rollback(); } catch { } return (false, "Nota no encontrada."); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { transaction.Rollback(); } catch { }
|
||||
_logger.LogError(ex, "Error ActualizarAsync NotaC/D ID: {Id}", idNota);
|
||||
return (false, $"Error interno: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<(bool Exito, string? Error)> EliminarAsync(int idNota, int idUsuario)
|
||||
{
|
||||
using var connection = _connectionFactory.CreateConnection();
|
||||
if (connection is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else connection.Open();
|
||||
using var transaction = connection.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var notaExistente = await _notaRepo.GetByIdAsync(idNota);
|
||||
if (notaExistente == null) return (false, "Nota no encontrada.");
|
||||
|
||||
// Revertir el efecto en el saldo
|
||||
decimal montoReversion = notaExistente.Tipo == "Credito" ? -notaExistente.Monto : notaExistente.Monto;
|
||||
|
||||
var eliminado = await _notaRepo.DeleteAsync(idNota, idUsuario, transaction);
|
||||
if (!eliminado) throw new DataException("Error al eliminar la nota.");
|
||||
|
||||
bool saldoActualizado = await _saldoRepo.ModificarSaldoAsync(notaExistente.Destino, notaExistente.IdDestino, notaExistente.IdEmpresa, montoReversion, transaction);
|
||||
if (!saldoActualizado) throw new DataException("Error al revertir el saldo tras la eliminación de la nota.");
|
||||
|
||||
transaction.Commit();
|
||||
_logger.LogInformation("NotaC/D ID {Id} eliminada y saldo revertido por Usuario ID {UserId}.", idNota, idUsuario);
|
||||
return (true, null);
|
||||
}
|
||||
catch (KeyNotFoundException) { try { transaction.Rollback(); } catch { } return (false, "Nota no encontrada."); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { transaction.Rollback(); } catch { }
|
||||
_logger.LogError(ex, "Error EliminarAsync NotaC/D ID: {Id}", idNota);
|
||||
return (false, $"Error interno: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
using GestionIntegral.Api.Data;
|
||||
using GestionIntegral.Api.Data.Repositories.Contables;
|
||||
using GestionIntegral.Api.Data.Repositories.Distribucion;
|
||||
using GestionIntegral.Api.Dtos.Contables;
|
||||
using GestionIntegral.Api.Models.Contables;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GestionIntegral.Api.Services.Contables
|
||||
{
|
||||
public class PagoDistribuidorService : IPagoDistribuidorService
|
||||
{
|
||||
private readonly IPagoDistribuidorRepository _pagoRepo;
|
||||
private readonly IDistribuidorRepository _distribuidorRepo;
|
||||
private readonly ITipoPagoRepository _tipoPagoRepo;
|
||||
private readonly IEmpresaRepository _empresaRepo;
|
||||
private readonly ISaldoRepository _saldoRepo;
|
||||
private readonly DbConnectionFactory _connectionFactory;
|
||||
private readonly ILogger<PagoDistribuidorService> _logger;
|
||||
|
||||
public PagoDistribuidorService(
|
||||
IPagoDistribuidorRepository pagoRepo,
|
||||
IDistribuidorRepository distribuidorRepo,
|
||||
ITipoPagoRepository tipoPagoRepo,
|
||||
IEmpresaRepository empresaRepo,
|
||||
ISaldoRepository saldoRepo,
|
||||
DbConnectionFactory connectionFactory,
|
||||
ILogger<PagoDistribuidorService> logger)
|
||||
{
|
||||
_pagoRepo = pagoRepo;
|
||||
_distribuidorRepo = distribuidorRepo;
|
||||
_tipoPagoRepo = tipoPagoRepo;
|
||||
_empresaRepo = empresaRepo;
|
||||
_saldoRepo = saldoRepo;
|
||||
_connectionFactory = connectionFactory;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
private async Task<PagoDistribuidorDto> MapToDto(PagoDistribuidor pago)
|
||||
{
|
||||
if (pago == null) return null!;
|
||||
|
||||
var distribuidorData = await _distribuidorRepo.GetByIdAsync(pago.IdDistribuidor);
|
||||
var tipoPago = await _tipoPagoRepo.GetByIdAsync(pago.IdTipoPago);
|
||||
var empresa = await _empresaRepo.GetByIdAsync(pago.IdEmpresa);
|
||||
|
||||
return new PagoDistribuidorDto
|
||||
{
|
||||
IdPago = pago.IdPago,
|
||||
IdDistribuidor = pago.IdDistribuidor,
|
||||
NombreDistribuidor = distribuidorData.Distribuidor?.Nombre ?? "N/A",
|
||||
Fecha = pago.Fecha.ToString("yyyy-MM-dd"),
|
||||
TipoMovimiento = pago.TipoMovimiento,
|
||||
Recibo = pago.Recibo,
|
||||
Monto = pago.Monto,
|
||||
IdTipoPago = pago.IdTipoPago,
|
||||
NombreTipoPago = tipoPago?.Nombre ?? "N/A",
|
||||
Detalle = pago.Detalle,
|
||||
IdEmpresa = pago.IdEmpresa,
|
||||
NombreEmpresa = empresa?.Nombre ?? "N/A"
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PagoDistribuidorDto>> ObtenerTodosAsync(
|
||||
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||
int? idDistribuidor, int? idEmpresa, string? tipoMovimiento)
|
||||
{
|
||||
var pagos = await _pagoRepo.GetAllAsync(fechaDesde, fechaHasta, idDistribuidor, idEmpresa, tipoMovimiento);
|
||||
var dtos = new List<PagoDistribuidorDto>();
|
||||
foreach (var pago in pagos)
|
||||
{
|
||||
dtos.Add(await MapToDto(pago));
|
||||
}
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<PagoDistribuidorDto?> ObtenerPorIdAsync(int idPago)
|
||||
{
|
||||
var pago = await _pagoRepo.GetByIdAsync(idPago);
|
||||
return pago == null ? null : await MapToDto(pago);
|
||||
}
|
||||
|
||||
public async Task<(PagoDistribuidorDto? Pago, string? Error)> CrearAsync(CreatePagoDistribuidorDto createDto, int idUsuario)
|
||||
{
|
||||
if (await _distribuidorRepo.GetByIdSimpleAsync(createDto.IdDistribuidor) == null)
|
||||
return (null, "Distribuidor no válido.");
|
||||
if (await _tipoPagoRepo.GetByIdAsync(createDto.IdTipoPago) == null)
|
||||
return (null, "Tipo de pago no válido.");
|
||||
if (await _empresaRepo.GetByIdAsync(createDto.IdEmpresa) == null)
|
||||
return (null, "Empresa no válida.");
|
||||
if (await _pagoRepo.ExistsByReciboAndTipoMovimientoAsync(createDto.Recibo, createDto.TipoMovimiento))
|
||||
return (null, $"Ya existe un pago '{createDto.TipoMovimiento}' con el número de recibo '{createDto.Recibo}'.");
|
||||
|
||||
|
||||
var nuevoPago = new PagoDistribuidor
|
||||
{
|
||||
IdDistribuidor = createDto.IdDistribuidor,
|
||||
Fecha = createDto.Fecha.Date,
|
||||
TipoMovimiento = createDto.TipoMovimiento,
|
||||
Recibo = createDto.Recibo,
|
||||
Monto = createDto.Monto,
|
||||
IdTipoPago = createDto.IdTipoPago,
|
||||
Detalle = createDto.Detalle,
|
||||
IdEmpresa = createDto.IdEmpresa
|
||||
};
|
||||
|
||||
using var connection = _connectionFactory.CreateConnection();
|
||||
if (connection is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else connection.Open();
|
||||
using var transaction = connection.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var pagoCreado = await _pagoRepo.CreateAsync(nuevoPago, idUsuario, transaction);
|
||||
if (pagoCreado == null) throw new DataException("Error al registrar el pago.");
|
||||
|
||||
// Afectar Saldo
|
||||
// Si TipoMovimiento es "Recibido", el monto DISMINUYE la deuda del distribuidor (monto positivo para el servicio de saldo).
|
||||
// Si TipoMovimiento es "Realizado" (empresa paga a distribuidor), el monto AUMENTA la deuda (monto negativo para el servicio de saldo).
|
||||
decimal montoAjusteSaldo = createDto.TipoMovimiento == "Recibido" ? createDto.Monto : -createDto.Monto;
|
||||
|
||||
bool saldoActualizado = await _saldoRepo.ModificarSaldoAsync("Distribuidores", pagoCreado.IdDistribuidor, pagoCreado.IdEmpresa, montoAjusteSaldo, transaction);
|
||||
if (!saldoActualizado) throw new DataException("Error al actualizar el saldo del distribuidor.");
|
||||
|
||||
transaction.Commit();
|
||||
_logger.LogInformation("PagoDistribuidor ID {Id} creado y saldo afectado por Usuario ID {UserId}.", pagoCreado.IdPago, idUsuario);
|
||||
return (await MapToDto(pagoCreado), null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { transaction.Rollback(); } catch { }
|
||||
_logger.LogError(ex, "Error CrearAsync PagoDistribuidor.");
|
||||
return (null, $"Error interno: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<(bool Exito, string? Error)> ActualizarAsync(int idPago, UpdatePagoDistribuidorDto updateDto, int idUsuario)
|
||||
{
|
||||
using var connection = _connectionFactory.CreateConnection();
|
||||
if (connection is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else connection.Open();
|
||||
using var transaction = connection.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var pagoExistente = await _pagoRepo.GetByIdAsync(idPago);
|
||||
if (pagoExistente == null) return (false, "Pago no encontrado.");
|
||||
|
||||
if (await _tipoPagoRepo.GetByIdAsync(updateDto.IdTipoPago) == null)
|
||||
return (false, "Tipo de pago no válido.");
|
||||
|
||||
// Calcular la diferencia de monto para ajustar el saldo
|
||||
decimal montoOriginal = pagoExistente.TipoMovimiento == "Recibido" ? pagoExistente.Monto : -pagoExistente.Monto;
|
||||
decimal montoNuevo = pagoExistente.TipoMovimiento == "Recibido" ? updateDto.Monto : -updateDto.Monto;
|
||||
decimal diferenciaAjusteSaldo = montoNuevo - montoOriginal;
|
||||
|
||||
// Actualizar campos permitidos
|
||||
pagoExistente.Monto = updateDto.Monto;
|
||||
pagoExistente.IdTipoPago = updateDto.IdTipoPago;
|
||||
pagoExistente.Detalle = updateDto.Detalle;
|
||||
|
||||
var actualizado = await _pagoRepo.UpdateAsync(pagoExistente, idUsuario, transaction);
|
||||
if (!actualizado) throw new DataException("Error al actualizar el pago.");
|
||||
|
||||
if (diferenciaAjusteSaldo != 0)
|
||||
{
|
||||
bool saldoActualizado = await _saldoRepo.ModificarSaldoAsync("Distribuidores", pagoExistente.IdDistribuidor, pagoExistente.IdEmpresa, diferenciaAjusteSaldo, transaction);
|
||||
if (!saldoActualizado) throw new DataException("Error al ajustar el saldo del distribuidor tras la actualización del pago.");
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
_logger.LogInformation("PagoDistribuidor ID {Id} actualizado por Usuario ID {UserId}.", idPago, idUsuario);
|
||||
return (true, null);
|
||||
}
|
||||
catch (KeyNotFoundException) { try { transaction.Rollback(); } catch { } return (false, "Pago no encontrado."); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { transaction.Rollback(); } catch { }
|
||||
_logger.LogError(ex, "Error ActualizarAsync PagoDistribuidor ID: {Id}", idPago);
|
||||
return (false, $"Error interno: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<(bool Exito, string? Error)> EliminarAsync(int idPago, int idUsuario)
|
||||
{
|
||||
using var connection = _connectionFactory.CreateConnection();
|
||||
if (connection is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else connection.Open();
|
||||
using var transaction = connection.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var pagoExistente = await _pagoRepo.GetByIdAsync(idPago);
|
||||
if (pagoExistente == null) return (false, "Pago no encontrado.");
|
||||
|
||||
// Revertir el efecto en el saldo
|
||||
// Si fue "Recibido", el saldo disminuyó (montoAjusteSaldo fue +Monto). Al eliminar, revertimos sumando -Monto (o restando +Monto).
|
||||
// Si fue "Realizado", el saldo aumentó (montoAjusteSaldo fue -Monto). Al eliminar, revertimos sumando +Monto (o restando -Monto).
|
||||
decimal montoReversion = pagoExistente.TipoMovimiento == "Recibido" ? -pagoExistente.Monto : pagoExistente.Monto;
|
||||
|
||||
var eliminado = await _pagoRepo.DeleteAsync(idPago, idUsuario, transaction);
|
||||
if (!eliminado) throw new DataException("Error al eliminar el pago.");
|
||||
|
||||
bool saldoActualizado = await _saldoRepo.ModificarSaldoAsync("Distribuidores", pagoExistente.IdDistribuidor, pagoExistente.IdEmpresa, montoReversion, transaction);
|
||||
if (!saldoActualizado) throw new DataException("Error al revertir el saldo del distribuidor tras la eliminación del pago.");
|
||||
|
||||
transaction.Commit();
|
||||
_logger.LogInformation("PagoDistribuidor ID {Id} eliminado por Usuario ID {UserId}.", idPago, idUsuario);
|
||||
return (true, null);
|
||||
}
|
||||
catch (KeyNotFoundException) { try { transaction.Rollback(); } catch { } return (false, "Pago no encontrado."); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { transaction.Rollback(); } catch { }
|
||||
_logger.LogError(ex, "Error EliminarAsync PagoDistribuidor ID: {Id}", idPago);
|
||||
return (false, $"Error interno: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user