creditu-common-library 2.3.14 → 2.3.16
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.
- package/README.md +2 -2
- package/middlewares/app-logger-middleware.d.ts +3 -0
- package/middlewares/app-logger-middleware.js +104 -16
- package/offer/services/installment.service.d.ts +1 -1
- package/offer/services/installment.service.js +1 -1
- package/offer/services/offer.service.d.ts +2 -3
- package/offer/services/offer.service.js +16 -15
- package/package.json +7 -6
- package/test/cl/offer.service.spec.ts +1 -1
- package/test/common/offer-service.spec.ts +11 -12
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Creditú CommonLibrary
|
|
2
2
|
|
|
3
3
|
## Descripción
|
|
4
|
-
Esta librería
|
|
4
|
+
Esta librería contiene los módulos y funciones matemáticas y financieras para el manejo de cálculos en el producto digital.
|
|
5
5
|
|
|
6
6
|
## Instalar en tu repositorio
|
|
7
7
|
|
|
@@ -21,7 +21,7 @@ La librería tiene dos módulos:
|
|
|
21
21
|
|
|
22
22
|
- `Finance`: expone varios servicios orientados a un dominio específico, y cuyas funciones resuelven diversas fórmulas financieras en su ámbito.
|
|
23
23
|
Los services expuestos son:
|
|
24
|
-
- `ConstantsService`: es un servicio auxiliar, que contiene funciones que calculan constantes que, a su vez, agrupan
|
|
24
|
+
- `ConstantsService`: es un servicio auxiliar, que contiene funciones que calculan constantes que, a su vez, agrupan parámetros conocidos para diversos propósitos en cálculos financieros.
|
|
25
25
|
- `CreditInsuranceService`: este servicio tiene funciones de cálculo para el dominio `Seguros`.
|
|
26
26
|
- `FinanceService`: este servicio auxiliar tiene funciones genéricas de funciones financieras, como interés anual, mensual, etc.
|
|
27
27
|
- `PaymentService`: este servicio tiene funciones de cálculo para el dominio `Dividendo`.
|
|
@@ -6,7 +6,10 @@ interface RequestWithStartTime extends Request {
|
|
|
6
6
|
export declare class AppLoggerMiddleware implements NestMiddleware {
|
|
7
7
|
private logger;
|
|
8
8
|
constructor(logger?: Logger);
|
|
9
|
+
private readonly defaultSanitizeOptions;
|
|
9
10
|
private logObject;
|
|
11
|
+
private isBase64;
|
|
12
|
+
private truncateValue;
|
|
10
13
|
private sanitizeObject;
|
|
11
14
|
use(request: RequestWithStartTime, response: Response, next: NextFunction): void;
|
|
12
15
|
}
|
|
@@ -33,35 +33,91 @@ var AppLoggerMiddleware = /** @class */ (function () {
|
|
|
33
33
|
function AppLoggerMiddleware(logger) {
|
|
34
34
|
if (logger === void 0) { logger = new common_1.Logger('HTTP'); }
|
|
35
35
|
this.logger = logger;
|
|
36
|
+
this.defaultSanitizeOptions = {
|
|
37
|
+
maxStringLength: 1000,
|
|
38
|
+
maxArrayLength: 10,
|
|
39
|
+
maxDepth: 5,
|
|
40
|
+
truncateBase64: true,
|
|
41
|
+
base64Preview: 50
|
|
42
|
+
};
|
|
36
43
|
this.logObject = function (obj) { return (0, util_1.inspect)(obj, { showHidden: false, depth: null, colors: true }); };
|
|
37
44
|
}
|
|
38
|
-
AppLoggerMiddleware.prototype.
|
|
45
|
+
AppLoggerMiddleware.prototype.isBase64 = function (str) {
|
|
46
|
+
try {
|
|
47
|
+
// Verifica si es una cadena base64 válida
|
|
48
|
+
return btoa(atob(str)) === str && str.length > 100; // Solo considera base64 si es largo
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
AppLoggerMiddleware.prototype.truncateValue = function (value, options) {
|
|
55
|
+
if (typeof value === 'string') {
|
|
56
|
+
// Detectar y truncar base64
|
|
57
|
+
if (options.truncateBase64 && this.isBase64(value)) {
|
|
58
|
+
var preview = value.substring(0, options.base64Preview);
|
|
59
|
+
return "".concat(preview, "... [BASE64_TRUNCATED - Original length: ").concat(value.length, " chars]");
|
|
60
|
+
}
|
|
61
|
+
// Truncar strings largos
|
|
62
|
+
if (value.length > options.maxStringLength) {
|
|
63
|
+
return "".concat(value.substring(0, options.maxStringLength), "... [TRUNCATED - Original length: ").concat(value.length, " chars]");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return value;
|
|
67
|
+
};
|
|
68
|
+
AppLoggerMiddleware.prototype.sanitizeObject = function (obj, options, currentDepth) {
|
|
39
69
|
var _this = this;
|
|
70
|
+
if (options === void 0) { options = this.defaultSanitizeOptions; }
|
|
71
|
+
if (currentDepth === void 0) { currentDepth = 0; }
|
|
40
72
|
if (!obj)
|
|
41
73
|
return obj;
|
|
42
|
-
//
|
|
43
|
-
if (
|
|
44
|
-
return
|
|
74
|
+
// Limitar profundidad para evitar recursión infinita
|
|
75
|
+
if (currentDepth > options.maxDepth) {
|
|
76
|
+
return '[MAX_DEPTH_REACHED]';
|
|
77
|
+
}
|
|
78
|
+
// Si es string, verificar si necesita truncado
|
|
79
|
+
if (typeof obj === 'string') {
|
|
80
|
+
return this.truncateValue(obj, options);
|
|
81
|
+
}
|
|
45
82
|
// Si no es un objeto (número, booleano, etc.), lo devolvemos directamente
|
|
46
83
|
if (typeof obj !== 'object')
|
|
47
84
|
return obj;
|
|
48
85
|
// Si es un array, sanitizamos cada elemento
|
|
49
86
|
if (Array.isArray(obj)) {
|
|
50
|
-
|
|
87
|
+
var truncatedArray = obj.slice(0, options.maxArrayLength);
|
|
88
|
+
var sanitizedArray = truncatedArray.map(function (item) { return _this.sanitizeObject(item, options, currentDepth + 1); });
|
|
89
|
+
// Si el array fue truncado, añadir información
|
|
90
|
+
if (obj.length > options.maxArrayLength) {
|
|
91
|
+
sanitizedArray.push("[ARRAY_TRUNCATED - Showing ".concat(options.maxArrayLength, " of ").concat(obj.length, " items]"));
|
|
92
|
+
}
|
|
93
|
+
return sanitizedArray;
|
|
51
94
|
}
|
|
52
95
|
// Si es un objeto, hacemos una copia para no modificar el original
|
|
53
96
|
var sanitized = __assign({}, obj);
|
|
54
97
|
// Lista de campos sensibles a ocultar
|
|
55
98
|
var sensitiveFields = ['password', 'token', 'secret', 'apiKey', 'creditCard', 'Authorization'];
|
|
99
|
+
// Lista de campos que típicamente contienen datos grandes
|
|
100
|
+
var largeDataFields = ['file', 'image', 'document', 'attachment', 'data', 'content', 'buffer'];
|
|
56
101
|
var _loop_1 = function (key) {
|
|
57
102
|
// Si es un campo sensible, lo ocultamos
|
|
58
103
|
if (sensitiveFields.some(function (field) { return key.toLowerCase().includes(field.toLowerCase()); })) {
|
|
59
104
|
sanitized[key] = '[REDACTED]';
|
|
60
105
|
// eslint-disable-next-line brace-style
|
|
61
106
|
}
|
|
107
|
+
// Si es un campo que típicamente contiene datos grandes, usar opciones más restrictivas
|
|
108
|
+
else if (largeDataFields.some(function (field) { return key.toLowerCase().includes(field.toLowerCase()); })) {
|
|
109
|
+
var restrictiveOptions = __assign(__assign({}, options), { maxStringLength: 100, base64Preview: 30 });
|
|
110
|
+
sanitized[key] = this_1.sanitizeObject(sanitized[key], restrictiveOptions, currentDepth + 1);
|
|
111
|
+
// eslint-disable-next-line brace-style
|
|
112
|
+
}
|
|
62
113
|
// Si es un objeto anidado, lo procesamos recursivamente
|
|
63
114
|
else if (typeof sanitized[key] === 'object' && sanitized[key] !== null) {
|
|
64
|
-
sanitized[key] = this_1.sanitizeObject(sanitized[key]);
|
|
115
|
+
sanitized[key] = this_1.sanitizeObject(sanitized[key], options, currentDepth + 1);
|
|
116
|
+
// eslint-disable-next-line brace-style
|
|
117
|
+
}
|
|
118
|
+
// Para valores primitivos, aplicar truncado si es necesario
|
|
119
|
+
else {
|
|
120
|
+
sanitized[key] = this_1.truncateValue(sanitized[key], options);
|
|
65
121
|
}
|
|
66
122
|
};
|
|
67
123
|
var this_1 = this;
|
|
@@ -75,8 +131,24 @@ var AppLoggerMiddleware = /** @class */ (function () {
|
|
|
75
131
|
AppLoggerMiddleware.prototype.use = function (request, response, next) {
|
|
76
132
|
// Añadir marca de tiempo al inicio de la petición
|
|
77
133
|
request.startTime = Date.now();
|
|
134
|
+
// Opciones específicas para request (más permisivo)
|
|
135
|
+
var requestSanitizeOptions = {
|
|
136
|
+
maxStringLength: 500,
|
|
137
|
+
maxArrayLength: 5,
|
|
138
|
+
maxDepth: 3,
|
|
139
|
+
truncateBase64: true,
|
|
140
|
+
base64Preview: 30
|
|
141
|
+
};
|
|
142
|
+
// Opciones específicas para response (más restrictivo)
|
|
143
|
+
var responseSanitizeOptions = {
|
|
144
|
+
maxStringLength: 300,
|
|
145
|
+
maxArrayLength: 3,
|
|
146
|
+
maxDepth: 3,
|
|
147
|
+
truncateBase64: true,
|
|
148
|
+
base64Preview: 20
|
|
149
|
+
};
|
|
78
150
|
// Captura del cuerpo de la solicitud (sanitizado)
|
|
79
|
-
var requestBody = this.sanitizeObject(request.body);
|
|
151
|
+
var requestBody = this.sanitizeObject(request.body, requestSanitizeOptions);
|
|
80
152
|
// Interceptar el método write y end para capturar la respuesta
|
|
81
153
|
var originalWrite = response.write;
|
|
82
154
|
var originalEnd = response.end;
|
|
@@ -86,7 +158,7 @@ var AppLoggerMiddleware = /** @class */ (function () {
|
|
|
86
158
|
// eslint-disable-next-line func-names
|
|
87
159
|
response.send = function (body) {
|
|
88
160
|
if (body && typeof body === 'object' && response.statusCode >= 400) {
|
|
89
|
-
var sanitizedBody = this.sanitizeObject(body);
|
|
161
|
+
var sanitizedBody = this.sanitizeObject(body, responseSanitizeOptions);
|
|
90
162
|
var responseTime = Date.now() - request.startTime;
|
|
91
163
|
this.logger.error("Error Response (".concat(response.statusCode, "): ").concat(JSON.stringify({
|
|
92
164
|
method: request.method,
|
|
@@ -107,7 +179,10 @@ var AppLoggerMiddleware = /** @class */ (function () {
|
|
|
107
179
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
108
180
|
args[_i - 1] = arguments[_i];
|
|
109
181
|
}
|
|
110
|
-
chunks
|
|
182
|
+
// Solo capturar chunks si no son demasiado grandes
|
|
183
|
+
if (chunks.length < 10 && chunk.length < 50000) {
|
|
184
|
+
chunks.push(Buffer.from(chunk));
|
|
185
|
+
}
|
|
111
186
|
return originalWrite.apply(response, __spreadArray([chunk], args, true));
|
|
112
187
|
};
|
|
113
188
|
// Interceptar end
|
|
@@ -117,7 +192,7 @@ var AppLoggerMiddleware = /** @class */ (function () {
|
|
|
117
192
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
118
193
|
args[_i - 1] = arguments[_i];
|
|
119
194
|
}
|
|
120
|
-
if (chunk) {
|
|
195
|
+
if (chunk && chunks.length < 10 && chunk.length < 50000) {
|
|
121
196
|
chunks.push(Buffer.from(chunk));
|
|
122
197
|
}
|
|
123
198
|
var method = request.method, originalUrl = request.originalUrl;
|
|
@@ -127,16 +202,29 @@ var AppLoggerMiddleware = /** @class */ (function () {
|
|
|
127
202
|
var responseBody = '';
|
|
128
203
|
var parsedBody;
|
|
129
204
|
if (chunks.length > 0) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
205
|
+
var totalSize = chunks.reduce(function (acc, chunk) { return acc + chunk.length; }, 0);
|
|
206
|
+
// Si el response es muy grande, no lo parseamos completo
|
|
207
|
+
if (totalSize > 100000) {
|
|
208
|
+
parsedBody = "[RESPONSE_TOO_LARGE - Size: ".concat(totalSize, " bytes]");
|
|
133
209
|
}
|
|
134
|
-
|
|
135
|
-
|
|
210
|
+
else {
|
|
211
|
+
responseBody = Buffer.concat(chunks).toString('utf8');
|
|
212
|
+
try {
|
|
213
|
+
parsedBody = JSON.parse(responseBody);
|
|
214
|
+
}
|
|
215
|
+
catch (e) {
|
|
216
|
+
// Si no es JSON válido y es muy largo, truncarlo
|
|
217
|
+
if (responseBody.length > 1000) {
|
|
218
|
+
parsedBody = "".concat(responseBody.substring(0, 1000), "... [TRUNCATED]");
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
parsedBody = responseBody;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
136
224
|
}
|
|
137
225
|
}
|
|
138
226
|
// Sanitizar la respuesta
|
|
139
|
-
var sanitizedResponseBody = this.sanitizeObject(parsedBody);
|
|
227
|
+
var sanitizedResponseBody = this.sanitizeObject(parsedBody, responseSanitizeOptions);
|
|
140
228
|
// Mensaje base con tiempo de respuesta
|
|
141
229
|
var baseMessage = "".concat(method, " ").concat(originalUrl, " ").concat(statusCode, " ").concat(statusMessage !== null && statusMessage !== void 0 ? statusMessage : '', " - ").concat(responseTime, "ms");
|
|
142
230
|
// Mensaje detallado con cuerpos de solicitud y respuesta
|
|
@@ -81,7 +81,7 @@ export declare class InstallmentService {
|
|
|
81
81
|
baseBalance(numberOfGraceMonths: number, graceMonthsInterestMethod: GraceMonthsInterestMethod, monthlyInterestRate: number): number;
|
|
82
82
|
/**
|
|
83
83
|
* Calcula la cuota del crédito (Ccr)
|
|
84
|
-
*
|
|
84
|
+
* Más info en {@link https://creditu-team.gitlab.io/wiki/content/journeys/acquisition/Offer.html#cuota-del-credito}
|
|
85
85
|
* @param monthlyPayment Dividendo (D). Se obtiene amplificando el dividendo unitario (baseMonthlyPayment) por el monto aprobado.
|
|
86
86
|
* @param creditInsuranceFee Cuota del seguro de crédito (C_s^cr)
|
|
87
87
|
* @param lifeInsuranceFee Cuota del seguro de desgravamen (C_s^d)
|
|
@@ -157,7 +157,7 @@ var InstallmentService = /** @class */ (function () {
|
|
|
157
157
|
};
|
|
158
158
|
/**
|
|
159
159
|
* Calcula la cuota del crédito (Ccr)
|
|
160
|
-
*
|
|
160
|
+
* Más info en {@link https://creditu-team.gitlab.io/wiki/content/journeys/acquisition/Offer.html#cuota-del-credito}
|
|
161
161
|
* @param monthlyPayment Dividendo (D). Se obtiene amplificando el dividendo unitario (baseMonthlyPayment) por el monto aprobado.
|
|
162
162
|
* @param creditInsuranceFee Cuota del seguro de crédito (C_s^cr)
|
|
163
163
|
* @param lifeInsuranceFee Cuota del seguro de desgravamen (C_s^d)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { CreditInsurancePercentageFinanced, OperationalExpensesFinancing, CreditAmount, CreditTaxRate, CreditTaxRatePercentage } from '../../shared/models';
|
|
2
1
|
import { MathService } from '../../math';
|
|
3
|
-
import {
|
|
2
|
+
import { CreditAmount, CreditInsurancePercentageFinanced, CreditTaxRate, CreditTaxRatePercentage, OperationalExpensesFinancing } from '../../shared/models';
|
|
4
3
|
import { CreditInsuranceFeeTermDefinition } from '../../shared/models/enum/credit-insurance-fee-term-definition.enum';
|
|
4
|
+
import { OfferInputs, OfferParams, OfferResponse } from '../models/dto';
|
|
5
5
|
/**
|
|
6
6
|
* Servicio que ofrece las funciones necesarias para diversos cálculos financieros.
|
|
7
7
|
*/
|
|
@@ -73,7 +73,6 @@ export declare class OfferService {
|
|
|
73
73
|
* Más info en: {@link https://creditu-team.gitlab.io/wiki/content/journeys/acquisition/Offer.html#carga-financiera}
|
|
74
74
|
* @param totalInstallment Cuota Total (C_tot)
|
|
75
75
|
* @param disposableIncome Ingresos Mensuales (Im)
|
|
76
|
-
* @param maximumBackendRatio Máximo (CF)
|
|
77
76
|
*/
|
|
78
77
|
getBackEndRatio(totalInstallment: number, disposableIncome: number): number;
|
|
79
78
|
/**
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.OfferService = void 0;
|
|
4
|
-
var models_1 = require("../../shared/models");
|
|
5
|
-
var finance_service_1 = require("./finance.service");
|
|
6
4
|
var math_1 = require("../../math");
|
|
5
|
+
var models_1 = require("../../shared/models");
|
|
6
|
+
var credit_insurance_fee_term_definition_enum_1 = require("../../shared/models/enum/credit-insurance-fee-term-definition.enum");
|
|
7
|
+
var product_enum_1 = require("../models/product.enum");
|
|
8
|
+
var constants_service_1 = require("./constants.service");
|
|
7
9
|
var credit_insurance_service_1 = require("./credit-insurance.service");
|
|
10
|
+
var finance_service_1 = require("./finance.service");
|
|
11
|
+
var installment_service_1 = require("./installment.service");
|
|
8
12
|
var loan_to_value_service_1 = require("./loan-to-value.service");
|
|
9
13
|
var maximum_local_service_1 = require("./maximum-local.service");
|
|
10
|
-
var installment_service_1 = require("./installment.service");
|
|
11
|
-
var constants_service_1 = require("./constants.service");
|
|
12
14
|
var operational_expenses_1 = require("./operational-expenses");
|
|
13
|
-
var credit_insurance_fee_term_definition_enum_1 = require("../../shared/models/enum/credit-insurance-fee-term-definition.enum");
|
|
14
|
-
var product_enum_1 = require("../models/product.enum");
|
|
15
15
|
/**
|
|
16
16
|
* Servicio que ofrece las funciones necesarias para diversos cálculos financieros.
|
|
17
17
|
*/
|
|
@@ -158,7 +158,7 @@ var OfferService = /** @class */ (function () {
|
|
|
158
158
|
var debtGuaranteeViv = this.maximumLocal.debtGuaranteeViv(propertyValue, maximumPropertyLTV, k1Fin, k2Fin);
|
|
159
159
|
var approvedAmountLoanToValue = this.maximumLocal.debtGuarantee(debtGuaranteeViv, debtGuaranteeCr);
|
|
160
160
|
var approvedAmount = this.getApprovedAmount(approvedAmountFinanceCharge, maximumLocalIncomeDividend, approvedAmountLoanToValue);
|
|
161
|
-
var credituAmount =
|
|
161
|
+
var credituAmount = Math.floor((this.credituAmount(downPayment, subsidy, propertyValue, creditInsuranceFactor, creditInsurancePercentageFinanced, operationalExpensesWeightedSum, operationalExpensesFinancing, creditTaxRate, creditTaxRatePercentage, amountRequestedByClient) * 100) / 100); // Redondear a dos decimales
|
|
162
162
|
var creditAmount = this.getCreditAmountToOffer(approvedAmount, credituAmount, creditMinAmount, creditMaxAmount);
|
|
163
163
|
var financingAmount = this.financingAmount(creditAmount, k1Fin, k2Fin);
|
|
164
164
|
var installment = this.installment.getMonthlyPayment(baseMonthlyPayment, creditAmount);
|
|
@@ -169,7 +169,7 @@ var OfferService = /** @class */ (function () {
|
|
|
169
169
|
: operationalExpensesFinanceable;
|
|
170
170
|
var loanToValueCredit = this.ltv.credit(financingAmount, creditInsurancePremium, propertyValue, creditInsurancePercentageFinanced, operationalExpensesFinanced, operationalExpensesFinancing);
|
|
171
171
|
var financingRatio = this.math.divide(financingAmount, amountRequestedByClient);
|
|
172
|
-
var loanToValueHome = this.ltv.home(
|
|
172
|
+
var loanToValueHome = this.ltv.home(credituAmount, propertyValue);
|
|
173
173
|
var creditInsuranceInstallment = this.insurance.creditInsurance(financingAmount, creditInsuranceFactor, creditInsurancePercentageFinanced.value(), creditInsuranceNumberOfMonths, isCreditInsuranceAccelerated, creditInsurancePremium, numberOfGraceMonths, installment);
|
|
174
174
|
var lifeInsuranceFee = this.insurance.lifeInsurance(creditAmount, totalLifeInsuranceMonthlyRate);
|
|
175
175
|
var propertyInsuranceFee = this.insurance.propertyInsurance(propertyValue, propertyTypeFactor, propertyInsuranceMonthlyRate);
|
|
@@ -281,7 +281,7 @@ var OfferService = /** @class */ (function () {
|
|
|
281
281
|
var _a = this.math, subtract = _a.subtract, multiply = _a.multiply;
|
|
282
282
|
var calculatedAmount = subtract(multiply(creditAmount, k1Fin), k2Fin);
|
|
283
283
|
// Si el resultado es menor que creditAmount * 0.5, devolver al menos eso
|
|
284
|
-
return calculatedAmount < (creditAmount * 0.
|
|
284
|
+
return calculatedAmount < (creditAmount * 0.25) ? creditAmount * 0.25 : calculatedAmount;
|
|
285
285
|
};
|
|
286
286
|
/**
|
|
287
287
|
* Función que calcula la Cuota Total (C_tot)
|
|
@@ -311,8 +311,7 @@ var OfferService = /** @class */ (function () {
|
|
|
311
311
|
creditInstallmentValue = this.math.subtract(creditInstallment, creditInsuranceInstallment);
|
|
312
312
|
}
|
|
313
313
|
var numerator = this.math.add(creditInstallmentValue, otherMortages);
|
|
314
|
-
|
|
315
|
-
return frontEndRatioCalculated;
|
|
314
|
+
return this.math.divide(numerator, monthlyIncome);
|
|
316
315
|
};
|
|
317
316
|
/**
|
|
318
317
|
* Función que calcula la Carga Financiera (CF), en la teoría financiera
|
|
@@ -320,11 +319,9 @@ var OfferService = /** @class */ (function () {
|
|
|
320
319
|
* Más info en: {@link https://creditu-team.gitlab.io/wiki/content/journeys/acquisition/Offer.html#carga-financiera}
|
|
321
320
|
* @param totalInstallment Cuota Total (C_tot)
|
|
322
321
|
* @param disposableIncome Ingresos Mensuales (Im)
|
|
323
|
-
* @param maximumBackendRatio Máximo (CF)
|
|
324
322
|
*/
|
|
325
323
|
OfferService.prototype.getBackEndRatio = function (totalInstallment, disposableIncome) {
|
|
326
|
-
|
|
327
|
-
return backEndRatioCalculated;
|
|
324
|
+
return this.math.divide(totalInstallment, disposableIncome);
|
|
328
325
|
};
|
|
329
326
|
/**
|
|
330
327
|
* Función que calcula el Monto aprobado es el mínimo entre Máximo local
|
|
@@ -366,12 +363,16 @@ var OfferService = /** @class */ (function () {
|
|
|
366
363
|
*/
|
|
367
364
|
// eslint-disable-next-line class-methods-use-this
|
|
368
365
|
OfferService.prototype.getCreditAmountToOffer = function (approvedAmount, credituAmount, creditMinAmount, creditMaxAmount) {
|
|
366
|
+
if (creditMinAmount.value() > creditMaxAmount.value()) {
|
|
367
|
+
throw new Error('Credit minimum amount cannot be greater than maximum amount');
|
|
368
|
+
}
|
|
369
369
|
models_1.Guarder.defined(creditMinAmount, 'CreditMinAmount');
|
|
370
|
+
models_1.Guarder.defined(creditMaxAmount, 'CreditMaxAmount');
|
|
370
371
|
var minApprovedAmount = Math.min(approvedAmount, credituAmount);
|
|
371
372
|
if (minApprovedAmount > creditMaxAmount.value())
|
|
372
373
|
return creditMaxAmount.value();
|
|
373
374
|
if (minApprovedAmount < creditMinAmount.value())
|
|
374
|
-
return
|
|
375
|
+
return 0;
|
|
375
376
|
return minApprovedAmount;
|
|
376
377
|
};
|
|
377
378
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "creditu-common-library",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.16",
|
|
4
4
|
"description": "Common library for Creditu applications",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
],
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc",
|
|
12
|
+
"build:watch": "tsc --watch",
|
|
12
13
|
"lint": "tsc --noEmit && eslint \"src/**/*.ts\" --no-fix",
|
|
13
14
|
"test:unit": "jest",
|
|
14
15
|
"test:cov": "jest --coverage",
|
|
@@ -25,9 +26,9 @@
|
|
|
25
26
|
},
|
|
26
27
|
"homepage": "https://gitlab.com/creditu-team/creditu-common-library#readme",
|
|
27
28
|
"devDependencies": {
|
|
28
|
-
"@babel/preset-typescript": "^7.27.
|
|
29
|
-
"@nestjs/testing": "^10.4.
|
|
30
|
-
"@types/express": "^5.0.
|
|
29
|
+
"@babel/preset-typescript": "^7.27.1",
|
|
30
|
+
"@nestjs/testing": "^10.4.18",
|
|
31
|
+
"@types/express": "^5.0.2",
|
|
31
32
|
"@types/jest": "^29.5.14",
|
|
32
33
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
33
34
|
"@typescript-eslint/parser": "^5.62.0",
|
|
@@ -35,12 +36,12 @@
|
|
|
35
36
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
36
37
|
"eslint-plugin-import": "^2.31.0",
|
|
37
38
|
"jest": "^29.7.0",
|
|
38
|
-
"ts-jest": "^29.3.
|
|
39
|
+
"ts-jest": "^29.3.4",
|
|
39
40
|
"ts-node": "^10.9.2",
|
|
40
41
|
"typescript": "^4.9.5"
|
|
41
42
|
},
|
|
42
43
|
"dependencies": {
|
|
43
|
-
"@nestjs/common": "^10.4.
|
|
44
|
+
"@nestjs/common": "^10.4.18",
|
|
44
45
|
"creditu-date-model": "^2.9.1",
|
|
45
46
|
"dinero.js": "^1.9.1",
|
|
46
47
|
"express": "^4.21.2",
|
|
@@ -226,7 +226,7 @@ describe('offerService CL', () => {
|
|
|
226
226
|
const math = new MathService(true, 20);
|
|
227
227
|
const offerService = new OfferService(math);
|
|
228
228
|
const result = offerService.calculateCreditAmountToOffer(inputs, params);
|
|
229
|
-
expect(result).toMatchObject(expectedResult);
|
|
229
|
+
expect(result).toMatchObject({ ...expectedResult, approvedAmount: 0 });
|
|
230
230
|
});
|
|
231
231
|
|
|
232
232
|
it('CHILE, SUBSIDY, SUBSIDY_1_2 A', () => {
|
|
@@ -7,28 +7,27 @@ describe('offer service functional tests common', () => {
|
|
|
7
7
|
const math = new MathService(true, 20);
|
|
8
8
|
const offerService = new OfferService(math);
|
|
9
9
|
describe('getCreditAmountToOffer', () => {
|
|
10
|
-
it('getCreditAmountToOffer should return 0 when minApprovedAmount < creditMinAmount', () => {
|
|
10
|
+
it('getCreditAmountToOffer should return 0 when minApprovedAmount < creditMinAmount', async () => {
|
|
11
11
|
// ARRANGE
|
|
12
12
|
const creditMinAmount = new CreditAmount(10);
|
|
13
13
|
const creditMaxAmount = new CreditAmount(0);
|
|
14
14
|
// ACT
|
|
15
|
-
|
|
15
|
+
expect(() => offerService.getCreditAmountToOffer(
|
|
16
16
|
0,
|
|
17
17
|
9,
|
|
18
18
|
creditMinAmount,
|
|
19
19
|
creditMaxAmount
|
|
20
|
-
)
|
|
20
|
+
))
|
|
21
|
+
.toThrow('Credit minimum amount cannot be greater than maximum amount');
|
|
21
22
|
// ASSERT
|
|
22
|
-
expect(result).toBe(0);
|
|
23
23
|
});
|
|
24
|
-
it('
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
expect(result).toBe(10);
|
|
24
|
+
it('should throw error when creditMinAmount > creditMaxAmount', () => {
|
|
25
|
+
const creditMinAmount = new CreditAmount(10);
|
|
26
|
+
const creditMaxAmount = new CreditAmount(0);
|
|
27
|
+
|
|
28
|
+
expect(() => {
|
|
29
|
+
offerService.getCreditAmountToOffer(0, 9, creditMinAmount, creditMaxAmount);
|
|
30
|
+
}).toThrow('Credit minimum amount cannot be greater than maximum amount');
|
|
32
31
|
});
|
|
33
32
|
it('getCreditAmountToOffer should return approvedAmount when ir more than credituAmount and is in range', () => {
|
|
34
33
|
// ARRANGE
|