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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gemcap-be-common",
3
- "version": "1.3.181",
3
+ "version": "1.3.183",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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 + Math.abs(p.amount), 0) : lastMonthPrincipal;
376
- const totalDisbursements = monthDisbursements.length > 0 ? monthDisbursements.reduce((acc, p) => acc + Math.abs(p.amount), 0) : 0;
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 > 0) {
482
+ if (lastTransaction && lastTransaction.balance >= 0) {
484
483
  return res;
485
484
  }
486
485
  }))).filter((res) => !!res);
487
- await this.saveCalculatedTermLoan(filteredRes, productId);
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 + Math.abs(p.amount), 0) : lastMonthPrincipal;
454
- const totalDisbursements = monthDisbursements.length > 0 ? monthDisbursements.reduce((acc, p) => acc + Math.abs(p.amount), 0) : 0;
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 > 0) {
560
+ if (lastTransaction && lastTransaction.balance >= 0) {
562
561
  return res;
563
562
  }
564
563
  }))).filter((res) => !!res);
565
- await this.saveCalculatedTermLoan(filteredRes, productId);
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
  }