gemcap-be-common 1.3.97 → 1.3.99
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/models/Prospect.model.d.ts +1 -0
- package/models/Prospect.model.js +2 -0
- package/models/Prospect.model.ts +2 -0
- package/package.json +1 -1
- package/services/compliance-borrowers.service.d.ts +1 -1
- package/services/loan-transactions.service.d.ts +1 -0
- package/services/loan-transactions.service.js +202 -109
- package/services/loan-transactions.service.ts +221 -109
- package/tsconfig.tsbuildinfo +1 -1
package/models/Prospect.model.js
CHANGED
|
@@ -100,6 +100,7 @@ exports.prospectFileGroups = [
|
|
|
100
100
|
ProspectInfoStageTwo_model_1.ExternalProspectStageTwoTables.listOfOfficers,
|
|
101
101
|
ProspectInfoStageTwo_model_1.ExternalProspectStageTwoTables.itSystems,
|
|
102
102
|
ProspectInfoStageTwo_model_1.ExternalProspectStageTwoTables.insuranceBrokers,
|
|
103
|
+
ProspectInfoStageTwo_model_1.ExternalProspectStageTwoTables.insurancePolicies,
|
|
103
104
|
ProspectInfoStageTwo_model_1.ExternalProspectStageTwoTables.accountsReceivablesExtra,
|
|
104
105
|
ProspectInfoStageTwo_model_1.ExternalProspectStageTwoTables.inventoryInformation,
|
|
105
106
|
];
|
|
@@ -123,6 +124,7 @@ exports.prospectFileGroupsMap = {
|
|
|
123
124
|
[ProspectInfoStageTwo_model_1.ExternalProspectStageTwoTables.listOfOfficers]: 'List Of Officers',
|
|
124
125
|
[ProspectInfoStageTwo_model_1.ExternalProspectStageTwoTables.itSystems]: 'IT Systems',
|
|
125
126
|
[ProspectInfoStageTwo_model_1.ExternalProspectStageTwoTables.insuranceBrokers]: 'Insurance Brokers',
|
|
127
|
+
[ProspectInfoStageTwo_model_1.ExternalProspectStageTwoTables.insurancePolicies]: 'Insurance Brokers',
|
|
126
128
|
[ProspectInfoStageTwo_model_1.ExternalProspectStageTwoTables.accountsReceivablesExtra]: 'Accounts Receivables Extra',
|
|
127
129
|
[ProspectInfoStageTwo_model_1.ExternalProspectStageTwoTables.inventoryInformation]: 'Inventory Information',
|
|
128
130
|
};
|
package/models/Prospect.model.ts
CHANGED
|
@@ -164,6 +164,7 @@ export const prospectFileGroups: string[] = [
|
|
|
164
164
|
ExternalProspectStageTwoTables.listOfOfficers,
|
|
165
165
|
ExternalProspectStageTwoTables.itSystems,
|
|
166
166
|
ExternalProspectStageTwoTables.insuranceBrokers,
|
|
167
|
+
ExternalProspectStageTwoTables.insurancePolicies,
|
|
167
168
|
ExternalProspectStageTwoTables.accountsReceivablesExtra,
|
|
168
169
|
ExternalProspectStageTwoTables.inventoryInformation,
|
|
169
170
|
];
|
|
@@ -189,6 +190,7 @@ export const prospectFileGroupsMap = {
|
|
|
189
190
|
[ExternalProspectStageTwoTables.listOfOfficers]: 'List Of Officers',
|
|
190
191
|
[ExternalProspectStageTwoTables.itSystems]: 'IT Systems',
|
|
191
192
|
[ExternalProspectStageTwoTables.insuranceBrokers]: 'Insurance Brokers',
|
|
193
|
+
[ExternalProspectStageTwoTables.insurancePolicies]: 'Insurance Brokers',
|
|
192
194
|
[ExternalProspectStageTwoTables.accountsReceivablesExtra]: 'Accounts Receivables Extra',
|
|
193
195
|
[ExternalProspectStageTwoTables.inventoryInformation]: 'Inventory Information',
|
|
194
196
|
};
|
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,226 @@ 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
|
-
|
|
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,
|
|
416
|
+
},
|
|
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
|
+
},
|
|
453
|
+
},
|
|
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
|
+
});
|
|
474
|
+
}
|
|
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
|
+
const session = await mongoose_1.default.startSession();
|
|
489
|
+
try {
|
|
490
|
+
await session.withTransaction(async () => {
|
|
491
|
+
// Получаем все транзакции, начиная с самой ранней, которую нужно пересчитать
|
|
492
|
+
const earliestTransaction = await LoanTransaction_model_1.LoanTransaction.aggregate([
|
|
493
|
+
{
|
|
494
|
+
$match: {
|
|
495
|
+
productId: startTransaction.productId,
|
|
496
|
+
date: { $lte: new Date(startTransaction.date) }
|
|
497
|
+
}
|
|
397
498
|
},
|
|
398
|
-
|
|
399
|
-
$
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
499
|
+
{ $sort: { date: 1, order: 1, createdAt: 1 } },
|
|
500
|
+
{ $limit: 1 }
|
|
501
|
+
]);
|
|
502
|
+
const fromDate = earliestTransaction.length
|
|
503
|
+
? earliestTransaction[0].date
|
|
504
|
+
: startTransaction.date;
|
|
505
|
+
const allTransactions = await LoanTransaction_model_1.LoanTransaction.aggregate([
|
|
506
|
+
{
|
|
507
|
+
$match: {
|
|
508
|
+
productId: startTransaction.productId,
|
|
509
|
+
date: { $gte: fromDate }
|
|
510
|
+
}
|
|
403
511
|
},
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
const previousTransaction = await LoanTransaction_model_1.LoanTransaction.aggregate([
|
|
512
|
+
{ $sort: { date: 1, order: 1, createdAt: 1 } }
|
|
513
|
+
]);
|
|
514
|
+
let balance = 0;
|
|
515
|
+
let floatedBalance = 0;
|
|
516
|
+
// Найдём стартовые значения
|
|
517
|
+
const prevBeforeStart = await LoanTransaction_model_1.LoanTransaction.aggregate([
|
|
411
518
|
{
|
|
412
519
|
$match: {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
}
|
|
416
|
-
}, {
|
|
417
|
-
$sort: {
|
|
418
|
-
'date': -1,
|
|
419
|
-
'order': -1,
|
|
420
|
-
'createdAt': -1,
|
|
421
|
-
},
|
|
422
|
-
}, {
|
|
423
|
-
$limit: 1,
|
|
520
|
+
productId: startTransaction.productId,
|
|
521
|
+
date: { $lt: fromDate }
|
|
522
|
+
}
|
|
424
523
|
},
|
|
524
|
+
{ $sort: { date: -1, order: -1, createdAt: -1 } },
|
|
525
|
+
{ $limit: 1 }
|
|
425
526
|
]);
|
|
426
|
-
if (
|
|
427
|
-
|
|
527
|
+
if (prevBeforeStart.length) {
|
|
528
|
+
balance = prevBeforeStart[0].balance || 0;
|
|
529
|
+
floatedBalance = prevBeforeStart[0].floatedBalance || 0;
|
|
428
530
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
switch (transaction.transactionType) {
|
|
448
|
-
case LoanTransaction_model_1.ELoanTransactionTypes.COLLECTION:
|
|
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;
|
|
531
|
+
// Один проход для расчёта balance и floatedBalance
|
|
532
|
+
for (const tr of allTransactions) {
|
|
533
|
+
// Пересчёт обычного баланса
|
|
534
|
+
balance = new decimal_js_1.default(balance).add(tr.amount).toNumber();
|
|
535
|
+
// Пересчёт floatedBalance
|
|
536
|
+
const totalPostponed = await (0, loan_products_db_1.getPostponedTransactions)(tr.date, tr.productId.toString(), true);
|
|
537
|
+
switch (tr.transactionType) {
|
|
538
|
+
case LoanTransaction_model_1.ELoanTransactionTypes.COLLECTION:
|
|
539
|
+
await this.cleanRecalculated(tr._id.toString());
|
|
540
|
+
await this.createPostponedTransaction(tr);
|
|
541
|
+
floatedBalance = new decimal_js_1.default(floatedBalance).add(totalPostponed).toNumber();
|
|
542
|
+
break;
|
|
543
|
+
case LoanTransaction_model_1.ELoanTransactionTypes.DISBURSEMENT:
|
|
544
|
+
case LoanTransaction_model_1.ELoanTransactionTypes.ADJUSTMENT:
|
|
545
|
+
floatedBalance = new decimal_js_1.default(floatedBalance).add(tr.amount).add(totalPostponed).toNumber();
|
|
546
|
+
break;
|
|
547
|
+
}
|
|
548
|
+
await LoanTransaction_model_1.LoanTransaction.updateOne({ _id: tr._id }, { balance, floatedBalance }, { session });
|
|
459
549
|
}
|
|
460
|
-
await
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
|
|
550
|
+
await LoanProducts_model_1.LoanProduct.updateOne({ _id: startTransaction.productId }, { isBalanceActual: true, isFloatedBalanceActual: true }, { session });
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
finally {
|
|
554
|
+
await session.endSession();
|
|
555
|
+
}
|
|
464
556
|
}
|
|
465
557
|
async deleteLoanTransaction(transactionId, updateLoanPayment, userId = null) {
|
|
466
558
|
const currentTransaction = await LoanTransaction_model_1.LoanTransaction.findById(transactionId).lean();
|
|
467
559
|
if (!currentTransaction) {
|
|
560
|
+
console.error(`no transactions with id ${transactionId}`);
|
|
468
561
|
return;
|
|
469
562
|
}
|
|
470
563
|
const nextTransaction = await LoanTransaction_model_1.LoanTransaction.aggregate([
|