gemcap-be-common 1.3.181 → 1.3.183
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/package.json
CHANGED
|
@@ -241,12 +241,12 @@ class LoanStatementService {
|
|
|
241
241
|
const dailyPercent = new decimal_js_1.default(percentFee).div(daysPerYear).toNumber();
|
|
242
242
|
switch (charge.calculationBasis) {
|
|
243
243
|
case loan_types_enum_1.EChargeCalculationBasis.DAILY_BALANCE:
|
|
244
|
-
if ((0, dayjs_1.default)(statementDate).isAfter((0, dayjs_1.default)(charge.applyFrom))) {
|
|
244
|
+
if ((0, dayjs_1.default)(statementDate).isAfter((0, dayjs_1.default)(charge.applyFrom)) || (0, dayjs_1.default)(statementDate).isSame((0, dayjs_1.default)(charge.applyFrom))) {
|
|
245
245
|
fee = new decimal_js_1.default(getBalance()).mul(dailyPercent).toDP(2).toNumber();
|
|
246
246
|
}
|
|
247
247
|
break;
|
|
248
248
|
case loan_types_enum_1.EChargeCalculationBasis.AVERAGE_MONTHLY_BALANCE:
|
|
249
|
-
if ((0, dayjs_1.default)(statementDate).isAfter((0, dayjs_1.default)(charge.applyFrom))) {
|
|
249
|
+
if ((0, dayjs_1.default)(statementDate).isAfter((0, dayjs_1.default)(charge.applyFrom)) || (0, dayjs_1.default)(statementDate).isSame((0, dayjs_1.default)(charge.applyFrom))) {
|
|
250
250
|
fee = new decimal_js_1.default(getBalance()).mul(percentFee).div(dayInMonth).toDP(2).toNumber();
|
|
251
251
|
}
|
|
252
252
|
if (!percentFee && charge.minimumAmount) {
|
|
@@ -254,7 +254,7 @@ class LoanStatementService {
|
|
|
254
254
|
}
|
|
255
255
|
break;
|
|
256
256
|
case loan_types_enum_1.EChargeCalculationBasis.UNUSED_AMOUNT:
|
|
257
|
-
if ((0, dayjs_1.default)(statementDate).isAfter((0, dayjs_1.default)(charge.applyFrom))) {
|
|
257
|
+
if ((0, dayjs_1.default)(statementDate).isAfter((0, dayjs_1.default)(charge.applyFrom)) || (0, dayjs_1.default)(statementDate).isSame((0, dayjs_1.default)(charge.applyFrom))) {
|
|
258
258
|
calculatedFee = new decimal_js_1.default(product.commitment).sub(getBalance()).mul(charge.percent).div(daysPerYear).toDP(2).toNumber();
|
|
259
259
|
fee = Math.max(calculatedFee, 0);
|
|
260
260
|
}
|
|
@@ -263,12 +263,12 @@ class LoanStatementService {
|
|
|
263
263
|
fee = new decimal_js_1.default(product.commitment).mul(charge.percent).toDP(2).toNumber();
|
|
264
264
|
break;
|
|
265
265
|
case loan_types_enum_1.EChargeCalculationBasis.DISBURSEMENT_AMOUNT:
|
|
266
|
-
if ((0, dayjs_1.default)(statementDate).isAfter((0, dayjs_1.default)(charge.applyFrom))) {
|
|
266
|
+
if ((0, dayjs_1.default)(statementDate).isAfter((0, dayjs_1.default)(charge.applyFrom)) || (0, dayjs_1.default)(statementDate).isSame((0, dayjs_1.default)(charge.applyFrom))) {
|
|
267
267
|
fee = await this.calculateDisbursementFee(product._id.toString(), charge, statementDate);
|
|
268
268
|
}
|
|
269
269
|
break;
|
|
270
270
|
case loan_types_enum_1.EChargeCalculationBasis.FIXED:
|
|
271
|
-
if ((0, dayjs_1.default)(statementDate).isAfter((0, dayjs_1.default)(charge.applyFrom))) {
|
|
271
|
+
if ((0, dayjs_1.default)(statementDate).isAfter((0, dayjs_1.default)(charge.applyFrom)) || (0, dayjs_1.default)(statementDate).isSame((0, dayjs_1.default)(charge.applyFrom))) {
|
|
272
272
|
calculatedFee = new decimal_js_1.default(getBalance()).mul(dailyPercent).toDP(2).toNumber();
|
|
273
273
|
fee = Math.max(calculatedFee, charge.minimumAmount);
|
|
274
274
|
}
|
|
@@ -282,12 +282,12 @@ export class LoanStatementService {
|
|
|
282
282
|
const dailyPercent = new Decimal(percentFee).div(daysPerYear).toNumber();
|
|
283
283
|
switch (charge.calculationBasis) {
|
|
284
284
|
case EChargeCalculationBasis.DAILY_BALANCE:
|
|
285
|
-
if (dayjs(statementDate).isAfter(dayjs(charge.applyFrom))) {
|
|
285
|
+
if (dayjs(statementDate).isAfter(dayjs(charge.applyFrom)) || dayjs(statementDate).isSame(dayjs(charge.applyFrom))) {
|
|
286
286
|
fee = new Decimal(getBalance()).mul(dailyPercent).toDP(2).toNumber();
|
|
287
287
|
}
|
|
288
288
|
break;
|
|
289
289
|
case EChargeCalculationBasis.AVERAGE_MONTHLY_BALANCE:
|
|
290
|
-
if (dayjs(statementDate).isAfter(dayjs(charge.applyFrom))) {
|
|
290
|
+
if (dayjs(statementDate).isAfter(dayjs(charge.applyFrom)) || dayjs(statementDate).isSame(dayjs(charge.applyFrom))) {
|
|
291
291
|
fee = new Decimal(getBalance()).mul(percentFee).div(dayInMonth).toDP(2).toNumber();
|
|
292
292
|
}
|
|
293
293
|
if (!percentFee && charge.minimumAmount) {
|
|
@@ -295,7 +295,7 @@ export class LoanStatementService {
|
|
|
295
295
|
}
|
|
296
296
|
break;
|
|
297
297
|
case EChargeCalculationBasis.UNUSED_AMOUNT:
|
|
298
|
-
if (dayjs(statementDate).isAfter(dayjs(charge.applyFrom))) {
|
|
298
|
+
if (dayjs(statementDate).isAfter(dayjs(charge.applyFrom)) || dayjs(statementDate).isSame(dayjs(charge.applyFrom))) {
|
|
299
299
|
calculatedFee = new Decimal(product.commitment).sub(getBalance()).mul(charge.percent).div(daysPerYear).toDP(2).toNumber();
|
|
300
300
|
fee = Math.max(calculatedFee, 0);
|
|
301
301
|
}
|
|
@@ -304,12 +304,12 @@ export class LoanStatementService {
|
|
|
304
304
|
fee = new Decimal(product.commitment).mul(charge.percent).toDP(2).toNumber();
|
|
305
305
|
break;
|
|
306
306
|
case EChargeCalculationBasis.DISBURSEMENT_AMOUNT:
|
|
307
|
-
if (dayjs(statementDate).isAfter(dayjs(charge.applyFrom))) {
|
|
307
|
+
if (dayjs(statementDate).isAfter(dayjs(charge.applyFrom)) || dayjs(statementDate).isSame(dayjs(charge.applyFrom))) {
|
|
308
308
|
fee = await this.calculateDisbursementFee(product._id.toString(), charge, statementDate);
|
|
309
309
|
}
|
|
310
310
|
break;
|
|
311
311
|
case EChargeCalculationBasis.FIXED:
|
|
312
|
-
if (dayjs(statementDate).isAfter(dayjs(charge.applyFrom))) {
|
|
312
|
+
if (dayjs(statementDate).isAfter(dayjs(charge.applyFrom)) || dayjs(statementDate).isSame(dayjs(charge.applyFrom))) {
|
|
313
313
|
calculatedFee = new Decimal(getBalance()).mul(dailyPercent).toDP(2).toNumber();
|
|
314
314
|
fee = Math.max(calculatedFee, charge.minimumAmount);
|
|
315
315
|
}
|
|
@@ -372,10 +372,10 @@ class TermLoanService {
|
|
|
372
372
|
isLastPeriod = actualMonthlyPayment > monthOpeningBalance || (currentDate.format('YYYY-MM-DD') === endTermMonths.format('YYYY-MM-DD'));
|
|
373
373
|
const isGracePeriod = checkGracePeriodDate(principalDueDay);
|
|
374
374
|
const monthlyPrincipal = (isGracePeriod) ? 0 : (isLastPeriod ? monthOpeningBalance : actualMonthlyPayment);
|
|
375
|
-
const totalPayment = monthPayments.length > 0 ? monthPayments.reduce((acc, p) => acc
|
|
376
|
-
const totalDisbursements = monthDisbursements.length > 0 ? monthDisbursements.reduce((acc, p) =>
|
|
375
|
+
const totalPayment = monthPayments.length > 0 ? monthPayments.reduce((acc, p) => new decimal_js_1.default(acc).add(Math.abs(p.amount)).toDP(2).toNumber(), 0) : lastMonthPrincipal;
|
|
376
|
+
const totalDisbursements = monthDisbursements.length > 0 ? monthDisbursements.reduce((acc, p) => new decimal_js_1.default(acc).add(p.amount).toDP(2).toNumber(), 0) : 0;
|
|
377
377
|
const closingBalance = new decimal_js_1.default(monthOpeningBalance).sub(totalPayment).add(totalDisbursements).toDP(2).toNumber();
|
|
378
|
-
openingBalance = closingBalance;
|
|
378
|
+
// openingBalance = closingBalance;
|
|
379
379
|
const monthlyResult = {
|
|
380
380
|
termLoanId: termLoan._id,
|
|
381
381
|
openingBalance: monthOpeningBalance,
|
|
@@ -390,7 +390,7 @@ class TermLoanService {
|
|
|
390
390
|
amortization: true, // TODO calculate
|
|
391
391
|
paymentDueDate: principalDueDay.date(termLoan.settings.principalDueDay).toDate(),
|
|
392
392
|
payments: null,
|
|
393
|
-
disbursements: totalDisbursements,
|
|
393
|
+
disbursements: Math.abs(totalDisbursements),
|
|
394
394
|
dailyResults: calculatedDailyResults,
|
|
395
395
|
};
|
|
396
396
|
calculatedMonthlyResults.push(monthlyResult);
|
|
@@ -404,7 +404,6 @@ class TermLoanService {
|
|
|
404
404
|
}
|
|
405
405
|
const paymentDates = [...new Set(calculatedMonthlyResults.map((res) => (0, dayjs_1.default)(res.paymentDueDate).format('YYYY-MM-DD')))];
|
|
406
406
|
const mergedResults = paymentDates.reduce((acc, paymentDate) => {
|
|
407
|
-
console.log(paymentDate, 'processing results');
|
|
408
407
|
const filteredDateResults = calculatedMonthlyResults.filter((res) => (0, dayjs_1.default)(res.paymentDueDate).format('YYYY-MM-DD') === paymentDate);
|
|
409
408
|
if (filteredDateResults.length === 1) {
|
|
410
409
|
return [...acc, ...filteredDateResults];
|
|
@@ -480,11 +479,19 @@ class TermLoanService {
|
|
|
480
479
|
}
|
|
481
480
|
const trDate = typeof res.paymentDueDate === 'string' ? new Date(res.paymentDueDate) : res.paymentDueDate;
|
|
482
481
|
const lastTransaction = await loanTransactionsService.getLastTransactionForDate(product._id.toString(), trDate);
|
|
483
|
-
if (lastTransaction && lastTransaction.balance
|
|
482
|
+
if (lastTransaction && lastTransaction.balance >= 0) {
|
|
484
483
|
return res;
|
|
485
484
|
}
|
|
486
485
|
}))).filter((res) => !!res);
|
|
487
|
-
|
|
486
|
+
let balanceIsZero = false;
|
|
487
|
+
const afterClosingBalance = filteredRes.reduce((acc, res) => {
|
|
488
|
+
if (balanceIsZero) {
|
|
489
|
+
return acc;
|
|
490
|
+
}
|
|
491
|
+
balanceIsZero = res.closingBalance === 0;
|
|
492
|
+
return [...acc, res];
|
|
493
|
+
}, []);
|
|
494
|
+
await this.saveCalculatedTermLoan(afterClosingBalance, productId);
|
|
488
495
|
await this.updateTermLoanStatus(termLoan._id.toString(), TermLoan_model_1.ETermLoanStatus.CALCULATED, new Date());
|
|
489
496
|
return await this.getTermLoan(productId, actual);
|
|
490
497
|
}
|
|
@@ -450,10 +450,10 @@ export class TermLoanService {
|
|
|
450
450
|
isLastPeriod = actualMonthlyPayment > monthOpeningBalance || (currentDate.format('YYYY-MM-DD') === endTermMonths.format('YYYY-MM-DD'));
|
|
451
451
|
const isGracePeriod = checkGracePeriodDate(principalDueDay);
|
|
452
452
|
const monthlyPrincipal = (isGracePeriod) ? 0 : (isLastPeriod ? monthOpeningBalance : actualMonthlyPayment);
|
|
453
|
-
const totalPayment = monthPayments.length > 0 ? monthPayments.reduce((acc, p) => acc
|
|
454
|
-
const totalDisbursements = monthDisbursements.length > 0 ? monthDisbursements.reduce((acc, p) => acc
|
|
453
|
+
const totalPayment = monthPayments.length > 0 ? monthPayments.reduce((acc, p) => new Decimal(acc).add(Math.abs(p.amount)).toDP(2).toNumber(), 0) : lastMonthPrincipal;
|
|
454
|
+
const totalDisbursements = monthDisbursements.length > 0 ? monthDisbursements.reduce((acc, p) => new Decimal(acc).add(p.amount).toDP(2).toNumber(), 0) : 0;
|
|
455
455
|
const closingBalance = new Decimal(monthOpeningBalance).sub(totalPayment).add(totalDisbursements).toDP(2).toNumber();
|
|
456
|
-
openingBalance = closingBalance;
|
|
456
|
+
// openingBalance = closingBalance;
|
|
457
457
|
const monthlyResult: ITermLoanCalculated = {
|
|
458
458
|
termLoanId: termLoan._id,
|
|
459
459
|
openingBalance: monthOpeningBalance,
|
|
@@ -468,7 +468,7 @@ export class TermLoanService {
|
|
|
468
468
|
amortization: true, // TODO calculate
|
|
469
469
|
paymentDueDate: principalDueDay.date(termLoan.settings.principalDueDay).toDate(),
|
|
470
470
|
payments: null,
|
|
471
|
-
disbursements: totalDisbursements,
|
|
471
|
+
disbursements: Math.abs(totalDisbursements),
|
|
472
472
|
dailyResults: calculatedDailyResults,
|
|
473
473
|
};
|
|
474
474
|
calculatedMonthlyResults.push(monthlyResult);
|
|
@@ -482,7 +482,6 @@ export class TermLoanService {
|
|
|
482
482
|
}
|
|
483
483
|
const paymentDates = [...new Set(calculatedMonthlyResults.map((res) => dayjs(res.paymentDueDate).format('YYYY-MM-DD')))];
|
|
484
484
|
const mergedResults = paymentDates.reduce((acc, paymentDate) => {
|
|
485
|
-
console.log(paymentDate, 'processing results');
|
|
486
485
|
const filteredDateResults = calculatedMonthlyResults.filter((res) => dayjs(res.paymentDueDate).format('YYYY-MM-DD') === paymentDate);
|
|
487
486
|
if (filteredDateResults.length === 1) {
|
|
488
487
|
return [...acc, ...filteredDateResults];
|
|
@@ -558,11 +557,19 @@ export class TermLoanService {
|
|
|
558
557
|
}
|
|
559
558
|
const trDate = typeof res.paymentDueDate === 'string' ? new Date(res.paymentDueDate) : res.paymentDueDate;
|
|
560
559
|
const lastTransaction = await loanTransactionsService.getLastTransactionForDate(product._id.toString(), trDate);
|
|
561
|
-
if (lastTransaction && lastTransaction.balance
|
|
560
|
+
if (lastTransaction && lastTransaction.balance >= 0) {
|
|
562
561
|
return res;
|
|
563
562
|
}
|
|
564
563
|
}))).filter((res) => !!res);
|
|
565
|
-
|
|
564
|
+
let balanceIsZero = false;
|
|
565
|
+
const afterClosingBalance = filteredRes.reduce((acc, res) => {
|
|
566
|
+
if (balanceIsZero) {
|
|
567
|
+
return acc;
|
|
568
|
+
}
|
|
569
|
+
balanceIsZero = res.closingBalance === 0;
|
|
570
|
+
return [...acc, res];
|
|
571
|
+
}, []);
|
|
572
|
+
await this.saveCalculatedTermLoan(afterClosingBalance, productId);
|
|
566
573
|
await this.updateTermLoanStatus(termLoan._id.toString(), ETermLoanStatus.CALCULATED, new Date());
|
|
567
574
|
return await this.getTermLoan(productId, actual);
|
|
568
575
|
}
|