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:
@@ -74,7 +74,6 @@ namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
if (Model.DebitosCreditos.Any()) column.Item().Element(ComposeDebCredTable);
|
||||
|
||||
column.Item().Element(ComposeResumenPeriodo);
|
||||
column.Item().Element(ComposeSaldoFinal);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -107,7 +106,11 @@ namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Saldo");
|
||||
});
|
||||
|
||||
decimal saldoAcumulado = 0; // Inicia en CERO
|
||||
// Fila Saldo Inicial al inicio de la primera tabla — ancla del acumulado
|
||||
table.Cell().ColumnSpan(6).Border(1).Padding(2).Text(t => t.Span("Saldo Inicial").SemiBold());
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(t => t.Span(Model.SaldoInicial.ToString("C", CultureAr)).SemiBold());
|
||||
|
||||
decimal saldoAcumulado = Model.SaldoInicial;
|
||||
foreach (var item in Model.Movimientos.OrderBy(m => m.Fecha))
|
||||
{
|
||||
saldoAcumulado += (item.Debe - item.Haber);
|
||||
@@ -157,7 +160,7 @@ namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Detalle");
|
||||
});
|
||||
|
||||
decimal saldoAcumulado = Model.TotalMovimientos;
|
||||
decimal saldoAcumulado = Model.SaldoInicial + Model.TotalMovimientos;
|
||||
foreach (var item in Model.Pagos.OrderBy(p => p.Fecha).ThenBy(p => p.Recibo))
|
||||
{
|
||||
saldoAcumulado += (item.Debe - item.Haber);
|
||||
@@ -204,7 +207,7 @@ namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Saldo");
|
||||
});
|
||||
|
||||
decimal saldoAcumulado = Model.TotalMovimientos + Model.TotalPagos;
|
||||
decimal saldoAcumulado = Model.SaldoInicial + Model.TotalMovimientos + Model.TotalPagos;
|
||||
foreach (var item in Model.DebitosCreditos.OrderBy(dc => dc.Fecha))
|
||||
{
|
||||
saldoAcumulado += (item.Debe - item.Haber);
|
||||
@@ -236,25 +239,17 @@ namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
row.RelativeItem().Text(label);
|
||||
row.ConstantItem(120).AlignRight().Text(value.ToString("C", CultureAr));
|
||||
};
|
||||
col.Item().Row(row => AddResumenRow(row, "Saldo Inicial", Model.SaldoInicial));
|
||||
col.Item().Row(row => AddResumenRow(row, "Movimientos", Model.TotalMovimientos));
|
||||
col.Item().Row(row => AddResumenRow(row, "Débitos/Créditos", Model.TotalDebitosCreditos));
|
||||
col.Item().Row(row => AddResumenRow(row, "Pagos", Model.TotalPagos));
|
||||
col.Item().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(5).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text("Total").SemiBold();
|
||||
row.ConstantItem(120).AlignRight().Text(t => t.Span(Model.TotalPeriodo.ToString("C", CultureAr)).SemiBold());
|
||||
row.RelativeItem().Text("Saldo Final").SemiBold();
|
||||
row.ConstantItem(120).AlignRight().Text(t => t.Span(Model.SaldoFinal.ToString("C", CultureAr)).SemiBold());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeSaldoFinal(IContainer container)
|
||||
{
|
||||
container.PaddingTop(5, Unit.Millimetre).AlignLeft().Text(text =>
|
||||
{
|
||||
text.Span($"Saldo Total del Distribuidor al {Model.FechaReporte} ").SemiBold().FontSize(12);
|
||||
text.Span(Model.SaldoDeCuenta.ToString("C", CultureAr)).SemiBold().FontSize(12);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -894,11 +894,11 @@ namespace GestionIntegral.Api.Controllers
|
||||
{
|
||||
if (!TienePermiso(PermisoVerBalanceCuentas)) return Forbid();
|
||||
|
||||
var (entradasSalidas, debitosCreditos, pagos, saldos, error) =
|
||||
var (entradasSalidas, debitosCreditos, pagos, saldoInicial, error) =
|
||||
await _reportesService.ObtenerReporteCuentasDistribuidorAsync(idDistribuidor, idEmpresa, fechaDesde, fechaHasta);
|
||||
|
||||
if (error != null) return BadRequest(new { message = error });
|
||||
if (!entradasSalidas.Any() && !debitosCreditos.Any() && !pagos.Any() && !saldos.Any())
|
||||
if (!entradasSalidas.Any() && !debitosCreditos.Any() && !pagos.Any() && saldoInicial == 0m)
|
||||
{
|
||||
return NotFound(new { message = "No hay datos para generar el reporte de cuenta del distribuidor." });
|
||||
}
|
||||
@@ -911,7 +911,7 @@ namespace GestionIntegral.Api.Controllers
|
||||
EntradasSalidas = entradasSalidas ?? Enumerable.Empty<BalanceCuentaDistDto>(),
|
||||
DebitosCreditos = debitosCreditos ?? Enumerable.Empty<BalanceCuentaDebCredDto>(),
|
||||
Pagos = pagos ?? Enumerable.Empty<BalanceCuentaPagosDto>(),
|
||||
Saldos = saldos ?? Enumerable.Empty<SaldoDto>(),
|
||||
SaldoInicial = saldoInicial,
|
||||
NombreDistribuidor = distribuidor.Distribuidor?.Nombre,
|
||||
NombreEmpresa = empresa?.Nombre
|
||||
};
|
||||
@@ -932,11 +932,11 @@ namespace GestionIntegral.Api.Controllers
|
||||
{
|
||||
if (!TienePermiso(PermisoVerBalanceCuentas)) return Forbid();
|
||||
|
||||
var (entradasSalidas, debitosCreditos, pagos, saldos, error) =
|
||||
var (entradasSalidas, debitosCreditos, pagos, saldoInicial, error) =
|
||||
await _reportesService.ObtenerReporteCuentasDistribuidorAsync(idDistribuidor, idEmpresa, fechaDesde, fechaHasta);
|
||||
|
||||
if (error != null) return BadRequest(new { message = error });
|
||||
if (!entradasSalidas.Any() && !debitosCreditos.Any() && !pagos.Any())
|
||||
if (!entradasSalidas.Any() && !debitosCreditos.Any() && !pagos.Any() && saldoInicial == 0m)
|
||||
{
|
||||
return NotFound(new { message = "No hay datos para generar el reporte de cuenta del distribuidor." });
|
||||
}
|
||||
@@ -950,7 +950,7 @@ namespace GestionIntegral.Api.Controllers
|
||||
Movimientos = entradasSalidas,
|
||||
Pagos = pagos,
|
||||
DebitosCreditos = debitosCreditos,
|
||||
SaldoDeCuenta = saldos.FirstOrDefault()?.Monto ?? 0, // <-- Se asigna a SaldoDeCuenta
|
||||
SaldoInicial = saldoInicial,
|
||||
NombreDistribuidor = distribuidor.Distribuidor?.Nombre ?? $"Distribuidor ID {idDistribuidor}",
|
||||
FechaDesde = fechaDesde.ToString("dd/MM/yyyy"),
|
||||
FechaHasta = fechaHasta.ToString("dd/MM/yyyy"),
|
||||
|
||||
Reference in New Issue
Block a user