feat(contables): cierre mensual de cuenta corriente de distribuidor
Permite congelar el saldo de un distribuidor por empresa a una fecha de corte y bloquear modificaciones retroactivas sobre el período cerrado. El saldo se calcula sumando movimientos en rango (sin tocar cue_Saldos). Incluye reapertura controlada exclusivamente por SuperAdmin, reporte con saldo inicial, atajo "Desde último cierre", y auditoría del ciclo de vida _H. Permisos CC001/CC002/CC003. Middleware global mapea bloqueos por período cerrado a HTTP 409.
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
namespace GestionIntegral.Api.Models.Contables
|
||||
{
|
||||
public class CierreCuentaCorriente // Corresponde a cue_CierresCuentaCorriente
|
||||
{
|
||||
public int IdCierre { get; set; }
|
||||
public int IdDistribuidor { get; set; }
|
||||
public int IdEmpresa { get; set; }
|
||||
public DateTime FechaCorte { get; set; }
|
||||
public DateTime FechaCierre { get; set; }
|
||||
public decimal SaldoCierre { get; set; } // money en SQL, decimal en C#
|
||||
public string Estado { get; set; } = "Activo"; // 'Activo' | 'Anulado'
|
||||
public string? Justificacion { get; set; }
|
||||
public int IdUsuarioCierre { get; set; }
|
||||
public int? IdUsuarioAnula { get; set; }
|
||||
public DateTime? FechaAnulacion { get; set; }
|
||||
public string? JustificacionAnulacion { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
namespace GestionIntegral.Api.Models.Contables
|
||||
{
|
||||
public class CierreCuentaCorrienteHistorico // Corresponde a cue_CierresCuentaCorriente_H
|
||||
{
|
||||
public int Id_Historial { get; set; }
|
||||
public int Id_Cierre { get; set; }
|
||||
public int Id_Distribuidor { get; set; }
|
||||
public int Id_Empresa { get; set; }
|
||||
public DateTime FechaCorte { get; set; }
|
||||
public DateTime FechaCierre { get; set; }
|
||||
public decimal SaldoCierre { get; set; }
|
||||
public string Estado { get; set; } = string.Empty;
|
||||
public string? Justificacion { get; set; }
|
||||
public int Id_Usuario_Cierre { get; set; }
|
||||
public int? Id_Usuario_Anula { get; set; }
|
||||
public DateTime? FechaAnulacion { get; set; }
|
||||
public string? Justificacion_Anulacion { get; set; }
|
||||
public string TipoMod { get; set; } = string.Empty; // 'Creacion' | 'Reapertura' | 'Modificacion'
|
||||
public int Id_Usuario_Mod { get; set; }
|
||||
public DateTime FechaMod { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
|
||||
namespace GestionIntegral.Api.Dtos.Auditoria
|
||||
{
|
||||
public class CierreCuentaCorrienteHistorialDto
|
||||
{
|
||||
public int Id_Historial { get; set; }
|
||||
public int Id_Cierre { get; set; }
|
||||
public int Id_Distribuidor { get; set; }
|
||||
public int Id_Empresa { get; set; }
|
||||
public DateTime FechaCorte { get; set; }
|
||||
public DateTime FechaCierre { get; set; }
|
||||
public decimal SaldoCierre { get; set; }
|
||||
public string Estado { get; set; } = string.Empty;
|
||||
public string? Justificacion { get; set; }
|
||||
public int Id_Usuario_Cierre { get; set; }
|
||||
public int? Id_Usuario_Anula { get; set; }
|
||||
public DateTime? FechaAnulacion { get; set; }
|
||||
public string? Justificacion_Anulacion { get; set; }
|
||||
|
||||
public string TipoMod { get; set; } = string.Empty; // 'Creacion' | 'Reapertura' | 'Modificacion'
|
||||
public int Id_Usuario_Mod { get; set; }
|
||||
public string NombreUsuarioModifico { get; set; } = string.Empty;
|
||||
public DateTime FechaMod { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace GestionIntegral.Api.Dtos.Contables
|
||||
@@ -19,10 +20,16 @@ namespace GestionIntegral.Api.Dtos.Contables
|
||||
[Required(ErrorMessage = "El monto del ajuste es obligatorio.")]
|
||||
// Permitir montos negativos para disminuir deuda o positivos para aumentarla
|
||||
// No se usa Range aquí para permitir ambos signos. La validación de que no sea cero se puede hacer en el servicio.
|
||||
public decimal MontoAjuste { get; set; }
|
||||
public decimal MontoAjuste { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "La justificación del ajuste es obligatoria.")]
|
||||
[StringLength(250, MinimumLength = 5, ErrorMessage = "La justificación debe tener entre 5 y 250 caracteres.")]
|
||||
public string Justificacion { get; set; } = string.Empty;
|
||||
|
||||
// Fecha lógica de la operación. Se valida contra el último cierre vigente
|
||||
// del par (Distribuidor + Empresa) para bloquear ajustes en períodos cerrados.
|
||||
// Distinta de FechaAjuste, que es el momento de ejecución del ajuste en el sistema.
|
||||
[Required(ErrorMessage = "La fecha de operación es obligatoria.")]
|
||||
public DateTime FechaOperacion { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
|
||||
namespace GestionIntegral.Api.Dtos.Contables
|
||||
{
|
||||
public class CierreCuentaCorrienteDto
|
||||
{
|
||||
public int IdCierre { get; set; }
|
||||
public int IdDistribuidor { get; set; }
|
||||
public string NombreDistribuidor { get; set; } = string.Empty;
|
||||
public int IdEmpresa { get; set; }
|
||||
public string NombreEmpresa { get; set; } = string.Empty;
|
||||
public string FechaCorte { get; set; } = string.Empty; // yyyy-MM-dd
|
||||
public DateTime FechaCierre { get; set; }
|
||||
public decimal SaldoCierre { get; set; }
|
||||
public string Estado { get; set; } = string.Empty;
|
||||
public string? Justificacion { get; set; }
|
||||
public int IdUsuarioCierre { get; set; }
|
||||
public string NombreUsuarioCierre { get; set; } = string.Empty;
|
||||
public int? IdUsuarioAnula { get; set; }
|
||||
public string? NombreUsuarioAnula { get; set; }
|
||||
public DateTime? FechaAnulacion { get; set; }
|
||||
public string? JustificacionAnulacion { get; set; }
|
||||
public bool EsUltimoVigente { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace GestionIntegral.Api.Dtos.Contables
|
||||
{
|
||||
public class CrearCierreDto
|
||||
{
|
||||
[Required(ErrorMessage = "El distribuidor es obligatorio.")]
|
||||
[Range(1, int.MaxValue, ErrorMessage = "ID de Distribuidor inválido.")]
|
||||
public int IdDistribuidor { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "La empresa es obligatoria.")]
|
||||
[Range(1, int.MaxValue, ErrorMessage = "ID de Empresa inválido.")]
|
||||
public int IdEmpresa { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "La fecha de corte es obligatoria.")]
|
||||
public DateTime FechaCorte { get; set; }
|
||||
|
||||
[StringLength(500, ErrorMessage = "La justificación no puede superar los 500 caracteres.")]
|
||||
public string? Justificacion { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace GestionIntegral.Api.Dtos.Contables
|
||||
{
|
||||
public class ReabrirCierreDto
|
||||
{
|
||||
[Required(ErrorMessage = "La justificación es obligatoria al reabrir un cierre.")]
|
||||
[StringLength(500, MinimumLength = 10, ErrorMessage = "La justificación debe tener entre 10 y 500 caracteres.")]
|
||||
public string Justificacion { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace GestionIntegral.Api.Dtos.Contables
|
||||
{
|
||||
public class UltimoCierreDto
|
||||
{
|
||||
public int IdCierre { get; set; }
|
||||
public string FechaCorte { get; set; } = string.Empty; // yyyy-MM-dd
|
||||
public decimal SaldoCierre { get; set; }
|
||||
public string Estado { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,12 @@ namespace GestionIntegral.Api.Dtos.Reportes
|
||||
public IEnumerable<BalanceCuentaDistDto> EntradasSalidas { get; set; } = new List<BalanceCuentaDistDto>();
|
||||
public IEnumerable<BalanceCuentaDebCredDto> DebitosCreditos { get; set; } = new List<BalanceCuentaDebCredDto>();
|
||||
public IEnumerable<BalanceCuentaPagosDto> Pagos { get; set; } = new List<BalanceCuentaPagosDto>();
|
||||
public IEnumerable<SaldoDto> Saldos { get; set; } = new List<SaldoDto>(); // O podría ser SaldoDto SaldoActual si siempre es uno
|
||||
public string? NombreDistribuidor { get; set; } // Para el título del reporte
|
||||
public string? NombreEmpresa { get; set; } // Para el título del reporte
|
||||
public string? NombreDistribuidor { get; set; }
|
||||
public string? NombreEmpresa { get; set; }
|
||||
|
||||
// Saldo a la fecha desde elegida en el filtro:
|
||||
// - Si existe cierre con FechaCorte < FechaDesde: SaldoCierre + movimientos netos entre fechaCierre+1 y fechaDesde-1.
|
||||
// - Sin cierres previos: 0.
|
||||
public decimal SaldoInicial { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,10 @@ namespace GestionIntegral.Api.Dtos.Reportes.ViewModels
|
||||
public IEnumerable<BalanceCuentaDistDto> Movimientos { get; set; } = new List<BalanceCuentaDistDto>();
|
||||
public IEnumerable<BalanceCuentaPagosDto> Pagos { get; set; } = new List<BalanceCuentaPagosDto>();
|
||||
public IEnumerable<BalanceCuentaDebCredDto> DebitosCreditos { get; set; } = new List<BalanceCuentaDebCredDto>();
|
||||
|
||||
// Saldo real de la cuenta, se muestra al final sin usarse en cálculos intermedios.
|
||||
public decimal SaldoDeCuenta { get; set; }
|
||||
|
||||
// Saldo inicial del período: snapshot del último cierre + movimientos netos hasta fechaDesde.
|
||||
// 0 si no hay cierre previo.
|
||||
public decimal SaldoInicial { get; set; }
|
||||
|
||||
// --- Parámetros del reporte ---
|
||||
public string NombreDistribuidor { get; set; } = string.Empty;
|
||||
@@ -24,6 +25,8 @@ namespace GestionIntegral.Api.Dtos.Reportes.ViewModels
|
||||
public decimal TotalMovimientos => Movimientos.Sum(m => m.Debe - m.Haber);
|
||||
public decimal TotalPagos => Pagos.Sum(p => p.Debe - p.Haber);
|
||||
public decimal TotalDebitosCreditos => DebitosCreditos.Sum(d => d.Debe - d.Haber);
|
||||
public decimal TotalPeriodo => TotalMovimientos + TotalPagos + TotalDebitosCreditos;
|
||||
|
||||
// Saldo Final = Saldo Inicial + suma neta del período (Debe - Haber por sección).
|
||||
public decimal SaldoFinal => SaldoInicial + TotalMovimientos + TotalPagos + TotalDebitosCreditos;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user