bdpformulas 1.0.50 → 1.0.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
- import { ProyeccionPrestamo } from "../../../models/eeff/admFinanciera";
2
- export type Frecuencia = "ANUAL" | "BIMENSUAL" | "CUATRIMESTRAL" | "MENSUAL" | "SEMESTRAL" | "TRIMESTRAL";
3
- export type TipoCuota = "FIJA" | "VARIABLE" | "CORTOPLAZO";
1
+ import { DateTime } from 'luxon';
2
+ import { ProyeccionPrestamo } from '../../../models/eeff/admFinanciera';
3
+ export type Frecuencia = 'ANUAL' | 'BIMENSUAL' | 'CUATRIMESTRAL' | 'MENSUAL' | 'SEMESTRAL' | 'TRIMESTRAL';
4
+ export type TipoCuota = 'FIJA' | 'VARIABLE' | 'CORTOPLAZO';
4
5
  export declare const frecuenciaMeses: Record<Frecuencia, number>;
5
6
  interface SimuladorParametros {
6
7
  monto: number;
@@ -20,7 +21,6 @@ interface Cuota {
20
21
  poliza: number;
21
22
  cuotaTotal: number;
22
23
  saldoCapital: number;
23
- tiempoDias: number;
24
24
  }
25
25
  export interface ResumenAnual {
26
26
  anio: number;
@@ -57,7 +57,7 @@ export declare function ourParseFloat(num: any, round?: boolean): number;
57
57
  * @param params.tolerancia - Precisión deseada para el resultado (por defecto: 1e-6).
58
58
  * @returns La tasa de interés periódica como decimal o undefined si no converge.
59
59
  */
60
- export declare function calcularTasaInteres({ meses, montoCuota, montoOriginal, guess, maxIteraciones, tolerancia, }: {
60
+ export declare function calcularTasaInteres({ meses, montoCuota, montoOriginal, guess, maxIteraciones, tolerancia }: {
61
61
  meses: number;
62
62
  montoCuota: number;
63
63
  montoOriginal: number;
@@ -79,18 +79,19 @@ interface GeneratePlazosParams {
79
79
  valor?: number;
80
80
  }
81
81
  export declare function generatePlazos({ inicio, cantidadProyeccion, valor }: GeneratePlazosParams): Partial<ProyeccionPrestamo>;
82
- export declare function calcularPagoPrincipalEntre({ tasaPeriodica, numeroPagos, montoPrestamo, periodoInicial, periodoFinal, }: {
82
+ export declare function calcularPagoPrincipalEntre({ tasaPeriodica, numeroPagos, montoPrestamo, periodoInicial, periodoFinal }: {
83
83
  tasaPeriodica: number;
84
84
  numeroPagos: number;
85
85
  montoPrestamo: number;
86
86
  periodoInicial?: number;
87
87
  periodoFinal: number;
88
88
  }): number;
89
- export declare function calcularPagoInteresEntre({ tasaPeriodica, numeroPagos, montoPrestamo, periodoInicial, periodoFinal, }: {
89
+ export declare function calcularPagoInteresEntre({ tasaPeriodica, numeroPagos, montoPrestamo, periodoInicial, periodoFinal }: {
90
90
  tasaPeriodica: number;
91
91
  numeroPagos: number;
92
92
  montoPrestamo: number;
93
93
  periodoInicial?: number;
94
94
  periodoFinal: number;
95
95
  }): number;
96
+ export declare function getDateTime(date: string | Date): DateTime<true> | DateTime<false>;
96
97
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calcularPagoInteresEntre = exports.calcularPagoPrincipalEntre = exports.generatePlazos = exports.sumCorrelativeKeys = exports.getColumnSum = exports.calcularTasaInteres = exports.ourParseFloat = exports.calcularPorcionCorrientePagada = exports.simuladorCuotas = exports.frecuenciaMeses = void 0;
3
+ exports.getDateTime = exports.calcularPagoInteresEntre = exports.calcularPagoPrincipalEntre = exports.generatePlazos = exports.sumCorrelativeKeys = exports.getColumnSum = exports.calcularTasaInteres = exports.ourParseFloat = exports.calcularPorcionCorrientePagada = exports.simuladorCuotas = exports.frecuenciaMeses = void 0;
4
4
  const luxon_1 = require("luxon");
5
5
  exports.frecuenciaMeses = {
6
6
  MENSUAL: 1,
@@ -8,12 +8,12 @@ exports.frecuenciaMeses = {
8
8
  TRIMESTRAL: 3,
9
9
  CUATRIMESTRAL: 4,
10
10
  SEMESTRAL: 6,
11
- ANUAL: 12,
11
+ ANUAL: 12
12
12
  };
13
13
  function simuladorCuotas({ monto, plazo, frecuencia, tipoCuota, periodoGracia = 0, tasaInteres = 0, polizaSD = 0, plazoMeses = false }) {
14
14
  const mesesPorFrecuencia = exports.frecuenciaMeses[frecuencia];
15
15
  const plazoEnMeses = !plazoMeses ? plazo * 12 : plazo;
16
- const cuotasTotales = Math.ceil(plazoEnMeses / mesesPorFrecuencia);
16
+ const cuotasTotales = plazoEnMeses / mesesPorFrecuencia;
17
17
  const tasaPorPeriodo = tasaInteres / (12 / mesesPorFrecuencia) / 100;
18
18
  let saldoCapital = monto;
19
19
  const cuotas = [];
@@ -22,25 +22,40 @@ function simuladorCuotas({ monto, plazo, frecuencia, tipoCuota, periodoGracia =
22
22
  let interesAnual = 0;
23
23
  let cuotaAnual = 0;
24
24
  let anioActual = 1;
25
- // Calcular cuota fija si aplica
26
- const cuotaFija = tipoCuota === "FIJA"
27
- ? (monto * tasaPorPeriodo) / (1 - Math.pow(1 + tasaPorPeriodo, -cuotasTotales))
28
- : 0;
25
+ const diasFrecuencia = 360 / (mesesPorFrecuencia * 30);
26
+ const diasGracia = periodoGracia / 12;
29
27
  for (let i = 1; i <= cuotasTotales; i++) {
28
+ if (i > 1) {
29
+ const anteriorCuota = cuotas.at(-1);
30
+ saldoCapital =
31
+ ourParseFloat(anteriorCuota?.saldoCapital) -
32
+ ourParseFloat(anteriorCuota?.amortizacion);
33
+ }
34
+ const interes = saldoCapital * tasaPorPeriodo;
30
35
  let amortizacion = 0;
31
- let interes = 0;
32
- let cuotaCredito = 0;
33
- let tiempoDias = mesesPorFrecuencia * 30; // Aproximado.
34
- if (i > Math.ceil(periodoGracia / mesesPorFrecuencia)) {
35
- interes = saldoCapital * tasaPorPeriodo;
36
- if (tipoCuota === "FIJA") {
37
- cuotaCredito = cuotaFija;
38
- amortizacion = cuotaCredito - interes;
36
+ let cuotaCredito;
37
+ if (tipoCuota === 'FIJA') {
38
+ const tasaInteresFrecuencia = tasaInteres / 100 / diasFrecuencia;
39
+ if (i > 1) {
40
+ const anteriorCuota = cuotas.at(-1);
41
+ cuotaCredito = anteriorCuota?.cuotaCredito ?? 0;
39
42
  }
40
43
  else {
41
- amortizacion = monto / (cuotasTotales - Math.ceil(periodoGracia / mesesPorFrecuencia));
42
- cuotaCredito = amortizacion + interes;
44
+ cuotaCredito =
45
+ monto *
46
+ (tasaInteresFrecuencia /
47
+ (1 -
48
+ Math.pow(1 + tasaInteresFrecuencia, -(diasFrecuencia *
49
+ ((plazoEnMeses - periodoGracia) / 12)))));
50
+ }
51
+ amortizacion = cuotaCredito - interes;
52
+ }
53
+ else {
54
+ if (i > diasFrecuencia * diasGracia) {
55
+ amortizacion =
56
+ monto / (diasFrecuencia * (plazoEnMeses / 12 - diasGracia));
43
57
  }
58
+ cuotaCredito = amortizacion + interes;
44
59
  }
45
60
  const cuotaTotal = cuotaCredito + polizaSD;
46
61
  cuotas.push({
@@ -50,10 +65,8 @@ function simuladorCuotas({ monto, plazo, frecuencia, tipoCuota, periodoGracia =
50
65
  cuotaCredito,
51
66
  poliza: polizaSD,
52
67
  cuotaTotal,
53
- saldoCapital,
54
- tiempoDias,
68
+ saldoCapital
55
69
  });
56
- saldoCapital -= amortizacion;
57
70
  // Acumular valores anuales
58
71
  capitalAnual += amortizacion;
59
72
  interesAnual += interes;
@@ -64,7 +77,7 @@ function simuladorCuotas({ monto, plazo, frecuencia, tipoCuota, periodoGracia =
64
77
  anio: anioActual,
65
78
  capitalAnual,
66
79
  interesAnual,
67
- cuotaAnual,
80
+ cuotaAnual
68
81
  });
69
82
  anioActual++;
70
83
  capitalAnual = 0;
@@ -76,8 +89,8 @@ function simuladorCuotas({ monto, plazo, frecuencia, tipoCuota, periodoGracia =
76
89
  }
77
90
  exports.simuladorCuotas = simuladorCuotas;
78
91
  function calcularPorcionCorrientePagada({ fechaDesembolso, fechaInicial, frecuencia, simulador }) {
79
- const inicial = luxon_1.DateTime.fromISO(fechaInicial);
80
- const desembolso = luxon_1.DateTime.fromISO(fechaDesembolso);
92
+ const inicial = getDateTime(fechaInicial).endOf('month');
93
+ const desembolso = getDateTime(fechaDesembolso).endOf('month');
81
94
  const mesesPorFrecuencia = exports.frecuenciaMeses[frecuencia];
82
95
  const mesesTranscurridos = inicial.diff(desembolso, 'months').months;
83
96
  const cuotasPagadas = Math.floor(mesesTranscurridos / mesesPorFrecuencia);
@@ -85,7 +98,7 @@ function calcularPorcionCorrientePagada({ fechaDesembolso, fechaInicial, frecuen
85
98
  const porcionCorrientePagada = cuotasPagadasArray.reduce((acumulado, cuota) => acumulado + cuota.amortizacion, 0);
86
99
  return {
87
100
  cuotasPagadas: cuotasPagadasArray.length,
88
- porcionCorrientePagada,
101
+ porcionCorrientePagada
89
102
  };
90
103
  }
91
104
  exports.calcularPorcionCorrientePagada = calcularPorcionCorrientePagada;
@@ -93,8 +106,7 @@ function ourParseFloat(num, round = true) {
93
106
  let parsed = parseFloat(num);
94
107
  if (isNaN(parsed))
95
108
  parsed = 0;
96
- if (round)
97
- parsed = parseFloat(parsed.toFixed(2));
109
+ //if (round) parsed = parseFloat(parsed.toFixed(2))
98
110
  return parsed;
99
111
  }
100
112
  exports.ourParseFloat = ourParseFloat;
@@ -110,7 +122,7 @@ exports.ourParseFloat = ourParseFloat;
110
122
  * @param params.tolerancia - Precisión deseada para el resultado (por defecto: 1e-6).
111
123
  * @returns La tasa de interés periódica como decimal o undefined si no converge.
112
124
  */
113
- function calcularTasaInteres({ meses, montoCuota, montoOriginal, guess = 0.1, maxIteraciones = 100, tolerancia = 1e-10, }) {
125
+ function calcularTasaInteres({ meses, montoCuota, montoOriginal, guess = 0.1, maxIteraciones = 100, tolerancia = 1e-10 }) {
114
126
  let tasa = guess;
115
127
  for (let i = 0; i < maxIteraciones; i++) {
116
128
  let f = 0; // Función objetivo f(x)
@@ -118,7 +130,7 @@ function calcularTasaInteres({ meses, montoCuota, montoOriginal, guess = 0.1, ma
118
130
  for (let j = 1; j <= meses; j++) {
119
131
  const factor = Math.pow(1 + tasa, -j);
120
132
  f += montoCuota * factor;
121
- fDerivada += -j * montoCuota * factor / (1 + tasa);
133
+ fDerivada += (-j * montoCuota * factor) / (1 + tasa);
122
134
  }
123
135
  // Sumar flujo inicial (monto original)
124
136
  f += montoOriginal;
@@ -140,7 +152,7 @@ exports.getColumnSum = getColumnSum;
140
152
  function sumCorrelativeKeys(params) {
141
153
  const { baseKey, endIndex, startIndex = 1, data } = params;
142
154
  if (endIndex < startIndex) {
143
- throw new Error("El índice final no puede ser menor que el índice inicial.");
155
+ throw new Error('El índice final no puede ser menor que el índice inicial.');
144
156
  }
145
157
  let sum = 0;
146
158
  for (let i = startIndex; i <= endIndex; i++) {
@@ -171,7 +183,7 @@ function generatePlazos({ inicio, cantidadProyeccion, valor }) {
171
183
  return plazos;
172
184
  }
173
185
  exports.generatePlazos = generatePlazos;
174
- function calcularPagoPrincipalEntre({ tasaPeriodica, numeroPagos, montoPrestamo, periodoInicial = 1, periodoFinal, }) {
186
+ function calcularPagoPrincipalEntre({ tasaPeriodica, numeroPagos, montoPrestamo, periodoInicial = 1, periodoFinal }) {
175
187
  // Cálculo de la cuota fija periódica (PMT)
176
188
  const cuota = (tasaPeriodica * montoPrestamo) /
177
189
  (1 - Math.pow(1 + tasaPeriodica, -numeroPagos));
@@ -189,7 +201,7 @@ function calcularPagoPrincipalEntre({ tasaPeriodica, numeroPagos, montoPrestamo,
189
201
  return totalCapitalAmortizado;
190
202
  }
191
203
  exports.calcularPagoPrincipalEntre = calcularPagoPrincipalEntre;
192
- function calcularPagoInteresEntre({ tasaPeriodica, numeroPagos, montoPrestamo, periodoInicial = 1, periodoFinal, }) {
204
+ function calcularPagoInteresEntre({ tasaPeriodica, numeroPagos, montoPrestamo, periodoInicial = 1, periodoFinal }) {
193
205
  // Cálculo de la cuota fija periódica (PMT)
194
206
  const cuota = (tasaPeriodica * montoPrestamo) /
195
207
  (1 - Math.pow(1 + tasaPeriodica, -numeroPagos));
@@ -207,3 +219,9 @@ function calcularPagoInteresEntre({ tasaPeriodica, numeroPagos, montoPrestamo, p
207
219
  return totalInteresesPagados; // Devuelve el valor negativo para igualar el comportamiento de Excel
208
220
  }
209
221
  exports.calcularPagoInteresEntre = calcularPagoInteresEntre;
222
+ function getDateTime(date) {
223
+ return date instanceof Date
224
+ ? luxon_1.DateTime.fromJSDate(date, { zone: 'utc' })
225
+ : luxon_1.DateTime.fromISO(date, { zone: 'utc' });
226
+ }
227
+ exports.getDateTime = getDateTime;
@@ -1,5 +1,5 @@
1
- import { AdministracionFinancieraCalcData, AdministracionFinancieraData } from "../../models/eeff/admFinanciera";
2
- import { Strategy } from "../../strategy.interface";
1
+ import { AdministracionFinancieraCalcData, AdministracionFinancieraData } from '../../models/eeff/admFinanciera';
2
+ import { Strategy } from '../../strategy.interface';
3
3
  export default class AdmFinancieraStrategy implements Strategy {
4
4
  data: AdministracionFinancieraCalcData | null;
5
5
  constructor();
@@ -22,7 +22,7 @@ class AdmFinancieraStrategy {
22
22
  ...cloned,
23
23
  ProyeccionPrestamosDirectos: cloned.ProyeccionPrestamosDirectos ?? [],
24
24
  ProyeccionAplicaciones: [],
25
- ProyeccionPrestamosBajoLineas: [],
25
+ ProyeccionPrestamosBajoLineas: []
26
26
  };
27
27
  this.formatPrestamosDirectos();
28
28
  this.formatPrestamosBajoLinea();
@@ -35,9 +35,10 @@ class AdmFinancieraStrategy {
35
35
  return this.data;
36
36
  }
37
37
  formatPrestamosDirectos() {
38
+ const prestamos = this.data.PrestamoDirecto.filter((pr) => pr.IndicadorABM !== 'B');
38
39
  let totalMontoOriginal = 0;
39
40
  let totalPorcionPagada = 0;
40
- this.data.PrestamoDirecto.forEach(prestamo => {
41
+ prestamos.forEach((prestamo) => {
41
42
  const handled = new prestamoDirectoHandler_1.PrestamoDirectoHandler({
42
43
  prestamo,
43
44
  data: this.data
@@ -45,37 +46,43 @@ class AdmFinancieraStrategy {
45
46
  totalMontoOriginal += (0, utils_1.ourParseFloat)(handled.MontoOriginal);
46
47
  totalPorcionPagada += (0, utils_1.ourParseFloat)(handled.PorcionPagada);
47
48
  });
48
- this.data?.PrestamoDirecto.push({
49
- Descripcion: 'TOTAL PRÉSTAMOS AMORTIZABLES BS',
50
- MontoOriginal: totalMontoOriginal,
51
- PorcionPagada: totalPorcionPagada,
52
- Clasificador: 'T'
53
- });
49
+ if (prestamos.length)
50
+ this.data?.PrestamoDirecto.push({
51
+ Descripcion: 'TOTAL PRÉSTAMOS AMORTIZABLES BS',
52
+ MontoOriginal: totalMontoOriginal,
53
+ PorcionPagada: totalPorcionPagada,
54
+ Clasificador: 'T'
55
+ });
54
56
  }
55
57
  formatPrestamosBajoLinea() {
56
- let totalMonto = this.data.PrestamoBajoLinea.reduce((acc, curr) => acc + (0, utils_1.ourParseFloat)(curr.MontoOriginal), 0);
58
+ const prestamos = this.data.PrestamoBajoLinea.filter((pr) => pr.IndicadorABM !== 'B');
59
+ const totalMonto = prestamos.reduce((acc, curr) => acc + (0, utils_1.ourParseFloat)(curr.MontoOriginal), 0);
57
60
  let totalMontoUtilizado = 0;
58
61
  let totalTasaPonderada = 0;
59
62
  let totalSaldoLinea = 0;
60
- this.data.PrestamoBajoLinea.forEach(prestamo => {
63
+ prestamos.forEach((prestamo) => {
61
64
  const handled = new prestamoBajoLineaHandler_1.PrestamoBajoLineaHandler(prestamo, this.data).handle();
62
65
  totalMontoUtilizado += (0, utils_1.ourParseFloat)(handled.MontoUtilizado);
63
- totalTasaPonderada += (0, utils_1.ourParseFloat)(handled.TasaPonderada);
66
+ totalTasaPonderada += (0, utils_1.ourParseFloat)(handled.TasaPonderada, false);
64
67
  totalSaldoLinea += (0, utils_1.ourParseFloat)(handled.SaldoLineaAplicar);
65
68
  });
66
- this.data?.PrestamoBajoLinea.push({
67
- Descripcion: 'TOTAL LÍNEA DE CRÉDITO BS',
68
- MontoOriginal: totalMonto,
69
- MontoUtilizado: totalMontoUtilizado,
70
- TasaPonderada: totalTasaPonderada,
71
- SaldoLineaAplicar: totalSaldoLinea,
72
- Clasificador: 'T'
73
- });
69
+ if (prestamos.length)
70
+ this.data?.PrestamoBajoLinea.push({
71
+ Descripcion: 'TOTAL LÍNEA DE CRÉDITO BS',
72
+ MontoOriginal: totalMonto,
73
+ MontoUtilizado: totalMontoUtilizado,
74
+ TasaPonderada: totalTasaPonderada,
75
+ SaldoLineaAplicar: totalSaldoLinea,
76
+ Clasificador: 'T'
77
+ });
74
78
  }
75
79
  setProyeccionesBajoLinea() {
76
- const filaTotales = this.data.PrestamoBajoLinea.find(pr => pr.Clasificador == 'T');
77
- const totalTasaPonderada = (0, utils_1.ourParseFloat)(filaTotales?.TasaPonderada) / 100;
78
- const proyecciones = this.data.PrestamoBajoLinea.map(pr => ({
80
+ const prestamos = this.data.PrestamoBajoLinea.filter((pr) => pr.IndicadorABM !== 'B');
81
+ const filaTotales = prestamos.find((pr) => pr.Clasificador == 'T');
82
+ const totalTasaPonderada = (0, utils_1.ourParseFloat)(filaTotales?.TasaPonderada, false) / 100;
83
+ const proyecciones = prestamos
84
+ .filter((pr) => pr.Clasificador !== 'T')
85
+ .map((pr) => ({
79
86
  Descripcion: pr.Descripcion,
80
87
  ...pr.Proyecciones
81
88
  }));
@@ -87,8 +94,10 @@ class AdmFinancieraStrategy {
87
94
  for (let i = 1; i <= this.data.CantidadProyeccion; i++) {
88
95
  let value;
89
96
  if (i == 1) {
90
- const primeraFila = this.data.PrestamoBajoLinea.at(0);
91
- value = (0, utils_1.ourParseFloat)(primeraFila?.MontoUtilizado) * totalTasaPonderada;
97
+ const primeraFila = prestamos.at(0);
98
+ value =
99
+ (0, utils_1.ourParseFloat)(primeraFila?.MontoUtilizado) *
100
+ totalTasaPonderada;
92
101
  }
93
102
  else {
94
103
  const sumaColumnaAnterior = (0, utils_1.getColumnSum)(proyecciones, `Gestion${i - 1}`);
@@ -100,28 +109,33 @@ class AdmFinancieraStrategy {
100
109
  this.data.ProyeccionPrestamosBajoLineas = proyecciones;
101
110
  }
102
111
  formatPrestamosLeasing() {
112
+ const prestamos = this.data.PrestamoLeasing.filter((pr) => pr.IndicadorABM !== 'B');
103
113
  let totalMonto = 0;
104
114
  let totalCuotaPeriodo = 0;
105
115
  let totalAporteInicial = 0;
106
116
  let totalValorResidual = 0;
107
117
  let totalValorBien = 0;
108
- this.data.PrestamoLeasing.forEach(prestamo => {
109
- const handled = new prestamoLeasingHandler_1.PrestamoLeasingHandler({ data: this.data, prestamo }).handle();
118
+ prestamos.forEach((prestamo) => {
119
+ const handled = new prestamoLeasingHandler_1.PrestamoLeasingHandler({
120
+ data: this.data,
121
+ prestamo
122
+ }).handle();
110
123
  totalMonto += (0, utils_1.ourParseFloat)(handled.MontoOriginal);
111
124
  totalCuotaPeriodo += (0, utils_1.ourParseFloat)(handled.MontoCuotaPeriodo);
112
125
  totalAporteInicial += (0, utils_1.ourParseFloat)(handled.MontoAporteInicial);
113
126
  totalValorResidual += (0, utils_1.ourParseFloat)(handled.MontoValorResidual);
114
127
  totalValorBien += (0, utils_1.ourParseFloat)(handled.MontoValorBien);
115
128
  });
116
- this.data?.PrestamoLeasing.push({
117
- Descripcion: 'TOTAL LEASING BS',
118
- MontoOriginal: totalMonto,
119
- MontoCuotaPeriodo: totalCuotaPeriodo,
120
- MontoAporteInicial: totalAporteInicial,
121
- MontoValorResidual: totalValorResidual,
122
- MontoValorBien: totalValorBien,
123
- Clasificador: 'T'
124
- });
129
+ if (prestamos.length)
130
+ this.data?.PrestamoLeasing.push({
131
+ Descripcion: 'TOTAL LEASING BS',
132
+ MontoOriginal: totalMonto,
133
+ MontoCuotaPeriodo: totalCuotaPeriodo,
134
+ MontoAporteInicial: totalAporteInicial,
135
+ MontoValorResidual: totalValorResidual,
136
+ MontoValorBien: totalValorBien,
137
+ Clasificador: 'T'
138
+ });
125
139
  }
126
140
  formatLineasMixtas() {
127
141
  new lineasMixtasHandler_1.LineasMixtasHandler(this.data).handle();
@@ -0,0 +1 @@
1
+ export {};