gemcap-be-common 1.3.98 → 1.3.100
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
|
@@ -45,7 +45,7 @@ export declare class ComplianceBorrowersService {
|
|
|
45
45
|
};
|
|
46
46
|
};
|
|
47
47
|
getFullComplianceBorrowerById(complianceBorrowerId: any): Promise<any>;
|
|
48
|
-
getAllBorrowersShortened(userAccess: any): Promise<(Pick<IComplianceBorrowerDocument, "
|
|
48
|
+
getAllBorrowersShortened(userAccess: any): Promise<(Pick<IComplianceBorrowerDocument, "borrower" | "fundingStatus" | "items"> | {
|
|
49
49
|
items: {
|
|
50
50
|
instances: any[];
|
|
51
51
|
item: import("../models/ComplianceItem.model").IComplianceItemDocument;
|
|
@@ -110,6 +110,7 @@ export declare class LoanTransactionsService {
|
|
|
110
110
|
updateLoanTransaction(transaction: ILoanTransactionDoc): Promise<void>;
|
|
111
111
|
saveLoanTransaction(transaction: Partial<ILoanTransactionWithId>): Promise<ILoanTransactionDoc>;
|
|
112
112
|
recalculateProduct(productId: string): Promise<void>;
|
|
113
|
+
recalculateBalanceLegacy(transactionId: string): Promise<void>;
|
|
113
114
|
recalculateBalance(transactionId: string): Promise<void>;
|
|
114
115
|
deleteLoanTransaction(transactionId: string, updateLoanPayment: boolean, userId?: any): Promise<void>;
|
|
115
116
|
createPostponedTransaction(transaction: ILoanTransactionDoc): Promise<void>;
|
|
@@ -9,7 +9,6 @@ const mongoose_1 = __importDefault(require("mongoose"));
|
|
|
9
9
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
10
10
|
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
11
11
|
const date_helper_1 = require("../helpers/date.helper");
|
|
12
|
-
const numbers_helper_1 = require("../helpers/numbers.helper");
|
|
13
12
|
const common_helper_1 = require("../helpers/common.helper");
|
|
14
13
|
const BBCDate_model_1 = require("../models/BBCDate.model");
|
|
15
14
|
const loan_types_enum_1 = require("../enums/loan-types.enum");
|
|
@@ -339,132 +338,216 @@ class LoanTransactionsService {
|
|
|
339
338
|
await this.recalculateBalance(firstTransactions[0]._id.toString());
|
|
340
339
|
}
|
|
341
340
|
}
|
|
342
|
-
async
|
|
341
|
+
async recalculateBalanceLegacy(transactionId) {
|
|
343
342
|
const changedTransaction = await LoanTransaction_model_1.LoanTransaction.findById(transactionId);
|
|
344
343
|
if (!changedTransaction) {
|
|
345
344
|
console.error(`no transactions with id ${transactionId}`);
|
|
346
345
|
return;
|
|
347
346
|
}
|
|
348
|
-
|
|
349
|
-
await
|
|
350
|
-
|
|
351
|
-
{
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
347
|
+
const recalcBalance = async () => {
|
|
348
|
+
const session = await mongoose_1.default.startSession();
|
|
349
|
+
try {
|
|
350
|
+
await session.withTransaction(async () => {
|
|
351
|
+
await LoanProducts_model_1.LoanProduct.findByIdAndUpdate(changedTransaction.productId, { isBalanceActual: false });
|
|
352
|
+
const previousTransaction = await LoanTransaction_model_1.LoanTransaction.aggregate([
|
|
353
|
+
{
|
|
354
|
+
$match: {
|
|
355
|
+
'productId': new mongoose_1.default.Types.ObjectId(changedTransaction.productId.toString()),
|
|
356
|
+
'date': { $lt: new Date(changedTransaction.date) },
|
|
357
|
+
},
|
|
358
|
+
}, {
|
|
359
|
+
$sort: {
|
|
360
|
+
'date': -1,
|
|
361
|
+
'order': -1,
|
|
362
|
+
'createdAt': -1,
|
|
363
|
+
},
|
|
364
|
+
}, {
|
|
365
|
+
$limit: 1,
|
|
366
|
+
},
|
|
367
|
+
]);
|
|
368
|
+
let currentBalance = previousTransaction.length
|
|
369
|
+
? previousTransaction[0].balance ?? 0
|
|
370
|
+
: 0;
|
|
371
|
+
const recalculatedTransactions = await LoanTransaction_model_1.LoanTransaction.aggregate([
|
|
372
|
+
{
|
|
373
|
+
$match: {
|
|
374
|
+
'productId': new mongoose_1.default.Types.ObjectId(changedTransaction.productId.toString()),
|
|
375
|
+
'date': { $gte: new Date(changedTransaction.date) },
|
|
376
|
+
},
|
|
377
|
+
}, {
|
|
378
|
+
$sort: {
|
|
379
|
+
'date': 1,
|
|
380
|
+
'order': 1,
|
|
381
|
+
'createdAt': 1,
|
|
382
|
+
},
|
|
383
|
+
},
|
|
384
|
+
]);
|
|
385
|
+
for (const transaction of recalculatedTransactions) {
|
|
386
|
+
currentBalance = new decimal_js_1.default(currentBalance).add(transaction.amount).toNumber();
|
|
387
|
+
await LoanTransaction_model_1.LoanTransaction.findByIdAndUpdate(transaction._id, { balance: currentBalance });
|
|
388
|
+
}
|
|
389
|
+
await LoanProducts_model_1.LoanProduct.findByIdAndUpdate(changedTransaction.productId, { isBalanceActual: true });
|
|
390
|
+
});
|
|
386
391
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
{
|
|
412
|
-
$match: {
|
|
413
|
-
'productId': new mongoose_1.default.Types.ObjectId(previousEqualBalancesTransaction[0].productId.toString()),
|
|
414
|
-
'date': { $lt: new Date(previousEqualBalancesTransaction[0].date) },
|
|
392
|
+
finally {
|
|
393
|
+
await session.endSession();
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
const recalcFloatedBalance = async () => {
|
|
397
|
+
const session = await mongoose_1.default.startSession();
|
|
398
|
+
try {
|
|
399
|
+
await session.withTransaction(async () => {
|
|
400
|
+
await LoanProducts_model_1.LoanProduct.findByIdAndUpdate(changedTransaction.productId, { isFloatedBalanceActual: false });
|
|
401
|
+
const previousEqualBalancesTransaction = await LoanTransaction_model_1.LoanTransaction.aggregate([
|
|
402
|
+
{
|
|
403
|
+
$match: {
|
|
404
|
+
'productId': new mongoose_1.default.Types.ObjectId(changedTransaction.productId.toString()),
|
|
405
|
+
'date': { $lt: new Date(changedTransaction.date) },
|
|
406
|
+
$expr: { $eq: ['$balance', '$floatedBalance'] },
|
|
407
|
+
},
|
|
408
|
+
}, {
|
|
409
|
+
$sort: {
|
|
410
|
+
'date': -1,
|
|
411
|
+
'order': -1,
|
|
412
|
+
'createdAt': -1,
|
|
413
|
+
},
|
|
414
|
+
}, {
|
|
415
|
+
$limit: 1,
|
|
415
416
|
},
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
417
|
+
]);
|
|
418
|
+
let currentFloatedBalance = 0;
|
|
419
|
+
if (previousEqualBalancesTransaction.length) {
|
|
420
|
+
const previousTransaction = await LoanTransaction_model_1.LoanTransaction.aggregate([
|
|
421
|
+
{
|
|
422
|
+
$match: {
|
|
423
|
+
'productId': new mongoose_1.default.Types.ObjectId(previousEqualBalancesTransaction[0].productId.toString()),
|
|
424
|
+
'date': { $lt: new Date(previousEqualBalancesTransaction[0].date) },
|
|
425
|
+
},
|
|
426
|
+
}, {
|
|
427
|
+
$sort: {
|
|
428
|
+
'date': -1,
|
|
429
|
+
'order': -1,
|
|
430
|
+
'createdAt': -1,
|
|
431
|
+
},
|
|
432
|
+
}, {
|
|
433
|
+
$limit: 1,
|
|
434
|
+
},
|
|
435
|
+
]);
|
|
436
|
+
if (previousTransaction.length) {
|
|
437
|
+
currentFloatedBalance = previousTransaction[0].floatedBalance;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
const initTransaction = previousEqualBalancesTransaction.length ? previousEqualBalancesTransaction[0] : changedTransaction;
|
|
441
|
+
const recalculatedTransactions = await LoanTransaction_model_1.LoanTransaction.aggregate([
|
|
442
|
+
{
|
|
443
|
+
$match: {
|
|
444
|
+
'productId': new mongoose_1.default.Types.ObjectId(initTransaction.productId.toString()),
|
|
445
|
+
'date': { $gte: new Date(initTransaction.date) },
|
|
446
|
+
},
|
|
447
|
+
}, {
|
|
448
|
+
$sort: {
|
|
449
|
+
'date': 1,
|
|
450
|
+
'order': 1,
|
|
451
|
+
'createdAt': 1,
|
|
452
|
+
},
|
|
421
453
|
},
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
454
|
+
]);
|
|
455
|
+
for (const transaction of recalculatedTransactions) {
|
|
456
|
+
const totalPostponed = await (0, loan_products_db_1.getPostponedTransactions)(transaction.date, transaction.productId.toString(), true);
|
|
457
|
+
switch (transaction.transactionType) {
|
|
458
|
+
case LoanTransaction_model_1.ELoanTransactionTypes.COLLECTION:
|
|
459
|
+
await this.cleanRecalculated(transaction._id.toString());
|
|
460
|
+
await this.createPostponedTransaction(transaction);
|
|
461
|
+
currentFloatedBalance = new decimal_js_1.default(currentFloatedBalance).add(totalPostponed).toNumber();
|
|
462
|
+
break;
|
|
463
|
+
case LoanTransaction_model_1.ELoanTransactionTypes.DISBURSEMENT:
|
|
464
|
+
currentFloatedBalance = new decimal_js_1.default(currentFloatedBalance).add(transaction.amount).add(totalPostponed).toNumber();
|
|
465
|
+
break;
|
|
466
|
+
case LoanTransaction_model_1.ELoanTransactionTypes.ADJUSTMENT:
|
|
467
|
+
currentFloatedBalance = new decimal_js_1.default(currentFloatedBalance).add(transaction.amount).add(totalPostponed).toNumber();
|
|
468
|
+
break;
|
|
469
|
+
}
|
|
470
|
+
await LoanTransaction_model_1.LoanTransaction.findByIdAndUpdate(transaction._id, { floatedBalance: currentFloatedBalance });
|
|
471
|
+
}
|
|
472
|
+
await LoanProducts_model_1.LoanProduct.findByIdAndUpdate(changedTransaction.productId, { isFloatedBalanceActual: true });
|
|
473
|
+
});
|
|
429
474
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
await this.cleanRecalculated(transaction._id.toString());
|
|
450
|
-
await this.createPostponedTransaction(transaction);
|
|
451
|
-
currentFloatedBalance = (0, numbers_helper_1.roundToXDigits)(currentFloatedBalance + totalPostponed);
|
|
452
|
-
break;
|
|
453
|
-
case LoanTransaction_model_1.ELoanTransactionTypes.DISBURSEMENT:
|
|
454
|
-
currentFloatedBalance = (0, numbers_helper_1.roundToXDigits)(currentFloatedBalance + transaction.amount + totalPostponed);
|
|
455
|
-
break;
|
|
456
|
-
case LoanTransaction_model_1.ELoanTransactionTypes.ADJUSTMENT:
|
|
457
|
-
currentFloatedBalance = (0, numbers_helper_1.roundToXDigits)(currentFloatedBalance + transaction.amount + totalPostponed);
|
|
458
|
-
break;
|
|
475
|
+
finally {
|
|
476
|
+
await session.endSession();
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
await recalcBalance();
|
|
480
|
+
await recalcFloatedBalance();
|
|
481
|
+
}
|
|
482
|
+
async recalculateBalance(transactionId) {
|
|
483
|
+
const startTransaction = await LoanTransaction_model_1.LoanTransaction.findById(transactionId).lean();
|
|
484
|
+
if (!startTransaction) {
|
|
485
|
+
console.error(`Transaction not found: ${transactionId}`);
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
// Получаем все транзакции, начиная с самой ранней, которую нужно пересчитать
|
|
489
|
+
const earliestTransaction = await LoanTransaction_model_1.LoanTransaction.aggregate([
|
|
490
|
+
{
|
|
491
|
+
$match: {
|
|
492
|
+
productId: startTransaction.productId,
|
|
493
|
+
date: { $lte: new Date(startTransaction.date) }
|
|
459
494
|
}
|
|
460
|
-
|
|
495
|
+
},
|
|
496
|
+
{ $sort: { date: 1, order: 1, createdAt: 1 } },
|
|
497
|
+
{ $limit: 1 }
|
|
498
|
+
]);
|
|
499
|
+
const fromDate = earliestTransaction.length
|
|
500
|
+
? earliestTransaction[0].date
|
|
501
|
+
: startTransaction.date;
|
|
502
|
+
const allTransactions = await LoanTransaction_model_1.LoanTransaction.aggregate([
|
|
503
|
+
{
|
|
504
|
+
$match: {
|
|
505
|
+
productId: startTransaction.productId,
|
|
506
|
+
date: { $gte: fromDate }
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
{ $sort: { date: 1, order: 1, createdAt: 1 } }
|
|
510
|
+
]);
|
|
511
|
+
let balance = 0;
|
|
512
|
+
let floatedBalance = 0;
|
|
513
|
+
const prevBeforeStart = await LoanTransaction_model_1.LoanTransaction.aggregate([
|
|
514
|
+
{
|
|
515
|
+
$match: {
|
|
516
|
+
productId: startTransaction.productId,
|
|
517
|
+
date: { $lt: fromDate }
|
|
518
|
+
}
|
|
519
|
+
},
|
|
520
|
+
{ $sort: { date: -1, order: -1, createdAt: -1 } },
|
|
521
|
+
{ $limit: 1 }
|
|
522
|
+
]);
|
|
523
|
+
if (prevBeforeStart.length) {
|
|
524
|
+
balance = prevBeforeStart[0].balance || 0;
|
|
525
|
+
floatedBalance = prevBeforeStart[0].floatedBalance || 0;
|
|
526
|
+
}
|
|
527
|
+
for (const tr of allTransactions) {
|
|
528
|
+
// regular balance recalculation
|
|
529
|
+
balance = new decimal_js_1.default(balance).add(tr.amount).toNumber();
|
|
530
|
+
// floatedBalance recalculation
|
|
531
|
+
const totalPostponed = await (0, loan_products_db_1.getPostponedTransactions)(tr.date, tr.productId.toString(), true);
|
|
532
|
+
switch (tr.transactionType) {
|
|
533
|
+
case LoanTransaction_model_1.ELoanTransactionTypes.COLLECTION:
|
|
534
|
+
await this.cleanRecalculated(tr._id.toString());
|
|
535
|
+
await this.createPostponedTransaction(tr);
|
|
536
|
+
floatedBalance = new decimal_js_1.default(floatedBalance).add(totalPostponed).toNumber();
|
|
537
|
+
break;
|
|
538
|
+
case LoanTransaction_model_1.ELoanTransactionTypes.DISBURSEMENT:
|
|
539
|
+
case LoanTransaction_model_1.ELoanTransactionTypes.ADJUSTMENT:
|
|
540
|
+
floatedBalance = new decimal_js_1.default(floatedBalance).add(tr.amount).add(totalPostponed).toNumber();
|
|
541
|
+
break;
|
|
461
542
|
}
|
|
462
|
-
await
|
|
463
|
-
}
|
|
543
|
+
await LoanTransaction_model_1.LoanTransaction.updateOne({ _id: tr._id }, { balance, floatedBalance });
|
|
544
|
+
}
|
|
545
|
+
await LoanProducts_model_1.LoanProduct.updateOne({ _id: startTransaction.productId }, { isBalanceActual: true, isFloatedBalanceActual: true });
|
|
464
546
|
}
|
|
465
547
|
async deleteLoanTransaction(transactionId, updateLoanPayment, userId = null) {
|
|
466
548
|
const currentTransaction = await LoanTransaction_model_1.LoanTransaction.findById(transactionId).lean();
|
|
467
549
|
if (!currentTransaction) {
|
|
550
|
+
console.error(`no transactions with id ${transactionId}`);
|
|
468
551
|
return;
|
|
469
552
|
}
|
|
470
553
|
const nextTransaction = await LoanTransaction_model_1.LoanTransaction.aggregate([
|