gemcap-be-common 1.2.59 → 1.2.60
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/db/brokers.db.d.ts +5 -0
- package/db/brokers.db.js +62 -0
- package/db/brokers.db.ts +60 -0
- package/db/loan-charges.db.d.ts +2 -0
- package/db/loan-charges.db.js +26 -0
- package/db/loan-charges.db.ts +21 -0
- package/db/loan-payments.db.d.ts +2 -0
- package/db/loan-payments.db.js +23 -0
- package/db/loan-payments.db.ts +18 -0
- package/db/loan-products.db.d.ts +3 -0
- package/db/loan-products.db.js +22 -1
- package/db/loan-products.db.ts +23 -1
- package/db/loan-statement.db.d.ts +44 -0
- package/db/loan-statement.db.js +186 -1
- package/db/loan-statement.db.ts +203 -5
- package/db/loan-transactions.db.d.ts +2 -0
- package/db/loan-transactions.db.js +39 -0
- package/db/loan-transactions.db.ts +33 -0
- package/db/reports.db.d.ts +56 -0
- package/db/reports.db.js +295 -0
- package/db/reports.db.ts +354 -0
- package/models/Borrower.model.d.ts +46 -0
- package/models/Borrower.model.js +75 -0
- package/models/Borrower.model.ts +103 -0
- package/models/LoanPayment.model.d.ts +66 -0
- package/models/LoanPayment.model.js +62 -0
- package/models/LoanPayment.model.ts +97 -0
- package/models/TermLoan.model.d.ts +53 -0
- package/models/TermLoan.model.js +74 -0
- package/models/TermLoan.model.ts +97 -0
- package/models/TermLoanCalculated.model.d.ts +54 -0
- package/models/TermLoanCalculated.model.js +98 -0
- package/models/TermLoanCalculated.model.ts +128 -0
- package/models/TermLoanSettings.model.d.ts +38 -0
- package/models/TermLoanSettings.model.js +39 -0
- package/models/TermLoanSettings.model.ts +53 -0
- package/models/_models.d.ts +3 -0
- package/models/_models.js +3 -0
- package/models/_models.ts +3 -0
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ILedgerDataRow } from './reports.db';
|
|
2
|
+
import { ILoanProductDoc } from '../models/LoanProducts.model';
|
|
3
|
+
import { IProductBrokerDocWithBroker } from '../models/ProductBroker.model';
|
|
4
|
+
export declare const getProductBrokers: (productId: string) => Promise<IProductBrokerDocWithBroker[]>;
|
|
5
|
+
export declare const enrichWithBrokers: (transactions: ILedgerDataRow[], product: ILoanProductDoc) => Promise<ILedgerDataRow[]>;
|
package/db/brokers.db.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.enrichWithBrokers = exports.getProductBrokers = void 0;
|
|
7
|
+
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
8
|
+
const mongoose_1 = __importDefault(require("mongoose"));
|
|
9
|
+
const reports_db_1 = require("./reports.db");
|
|
10
|
+
const ProductBroker_model_1 = require("../models/ProductBroker.model");
|
|
11
|
+
const getProductBrokers = async (productId) => {
|
|
12
|
+
return ProductBroker_model_1.ProductBrokerModel.aggregate([
|
|
13
|
+
{
|
|
14
|
+
'$match': {
|
|
15
|
+
'productId': new mongoose_1.default.Types.ObjectId(productId),
|
|
16
|
+
},
|
|
17
|
+
}, {
|
|
18
|
+
$sort: { 'order': 1 },
|
|
19
|
+
}, {
|
|
20
|
+
$lookup: {
|
|
21
|
+
from: 'loan_brokers',
|
|
22
|
+
localField: 'loanBrokerId',
|
|
23
|
+
foreignField: '_id',
|
|
24
|
+
as: 'loanBroker',
|
|
25
|
+
},
|
|
26
|
+
}, {
|
|
27
|
+
$unwind: {
|
|
28
|
+
path: '$loanBroker',
|
|
29
|
+
preserveNullAndEmptyArrays: true,
|
|
30
|
+
},
|
|
31
|
+
}, {
|
|
32
|
+
$unset: ['createdAt', 'updatedAt', '__v'],
|
|
33
|
+
},
|
|
34
|
+
]);
|
|
35
|
+
};
|
|
36
|
+
exports.getProductBrokers = getProductBrokers;
|
|
37
|
+
const enrichWithBrokers = async (transactions, product) => {
|
|
38
|
+
const productBrokers = await (0, exports.getProductBrokers)(product._id.toString());
|
|
39
|
+
if (productBrokers.length === 0) {
|
|
40
|
+
return transactions;
|
|
41
|
+
}
|
|
42
|
+
const handleFee = (t, broker, shareName) => {
|
|
43
|
+
return {
|
|
44
|
+
...t,
|
|
45
|
+
statementAmount: new decimal_js_1.default(-t.statementAmount).mul(broker[shareName]).toDP(2).toNumber(),
|
|
46
|
+
title: `${t.title.replace('ACCRUED', '').trim()}: ${broker.loanBroker.name}`,
|
|
47
|
+
chargeCode: broker.BSCode,
|
|
48
|
+
PLCode: broker.PLCode,
|
|
49
|
+
isBrokerFee: true,
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
const handlers = {
|
|
53
|
+
[reports_db_1.EChargeType.ADMIN_FEE]: (t, broker) => handleFee(t, broker, 'adminShare'),
|
|
54
|
+
[reports_db_1.EChargeType.INTEREST_FEE]: (t, broker) => handleFee(t, broker, 'interestShare'),
|
|
55
|
+
[reports_db_1.EChargeType.OTHER]: (t, broker) => handleFee(t, broker, 'otherShare'),
|
|
56
|
+
};
|
|
57
|
+
return transactions.reduce((acc, t) => {
|
|
58
|
+
const handler = handlers[reports_db_1.EChargeType[t.type]];
|
|
59
|
+
return handler ? [...acc, t, ...productBrokers.map((broker) => handler(t, broker))] : [...acc, t];
|
|
60
|
+
}, []);
|
|
61
|
+
};
|
|
62
|
+
exports.enrichWithBrokers = enrichWithBrokers;
|
package/db/brokers.db.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import Decimal from 'decimal.js';
|
|
2
|
+
import mongoose from 'mongoose';
|
|
3
|
+
|
|
4
|
+
import { EChargeType, ILedgerDataRow } from './reports.db';
|
|
5
|
+
import { ILoanProductDoc } from '../models/LoanProducts.model';
|
|
6
|
+
import { IProductBrokerDocWithBroker, ProductBrokerModel } from '../models/ProductBroker.model';
|
|
7
|
+
|
|
8
|
+
export const getProductBrokers = async (productId: string) => {
|
|
9
|
+
return ProductBrokerModel.aggregate<IProductBrokerDocWithBroker>([
|
|
10
|
+
{
|
|
11
|
+
'$match': {
|
|
12
|
+
'productId': new mongoose.Types.ObjectId(productId),
|
|
13
|
+
},
|
|
14
|
+
}, {
|
|
15
|
+
$sort: { 'order': 1 },
|
|
16
|
+
}, {
|
|
17
|
+
$lookup: {
|
|
18
|
+
from: 'loan_brokers',
|
|
19
|
+
localField: 'loanBrokerId',
|
|
20
|
+
foreignField: '_id',
|
|
21
|
+
as: 'loanBroker',
|
|
22
|
+
},
|
|
23
|
+
}, {
|
|
24
|
+
$unwind: {
|
|
25
|
+
path: '$loanBroker',
|
|
26
|
+
preserveNullAndEmptyArrays: true,
|
|
27
|
+
},
|
|
28
|
+
}, {
|
|
29
|
+
$unset: ['createdAt', 'updatedAt', '__v'],
|
|
30
|
+
},
|
|
31
|
+
]);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const enrichWithBrokers = async (transactions: ILedgerDataRow[], product: ILoanProductDoc): Promise<ILedgerDataRow[]> => {
|
|
35
|
+
const productBrokers = await getProductBrokers(product._id.toString());
|
|
36
|
+
if (productBrokers.length === 0) {
|
|
37
|
+
return transactions;
|
|
38
|
+
}
|
|
39
|
+
const handleFee = (t: ILedgerDataRow, broker: IProductBrokerDocWithBroker, shareName: 'adminShare' | 'interestShare' | 'otherShare'): ILedgerDataRow => {
|
|
40
|
+
return {
|
|
41
|
+
...t,
|
|
42
|
+
statementAmount: new Decimal(-t.statementAmount).mul(broker[shareName]).toDP(2).toNumber(),
|
|
43
|
+
title: `${t.title.replace('ACCRUED', '').trim()}: ${broker.loanBroker.name}`,
|
|
44
|
+
chargeCode: broker.BSCode,
|
|
45
|
+
PLCode: broker.PLCode,
|
|
46
|
+
isBrokerFee: true,
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const handlers = {
|
|
51
|
+
[EChargeType.ADMIN_FEE]: (t: ILedgerDataRow, broker: IProductBrokerDocWithBroker) => handleFee(t, broker, 'adminShare'),
|
|
52
|
+
[EChargeType.INTEREST_FEE]: (t: ILedgerDataRow, broker: IProductBrokerDocWithBroker) => handleFee(t, broker, 'interestShare'),
|
|
53
|
+
[EChargeType.OTHER]: (t: ILedgerDataRow, broker: IProductBrokerDocWithBroker) => handleFee(t, broker, 'otherShare'),
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return transactions.reduce((acc, t) => {
|
|
57
|
+
const handler = handlers[EChargeType[t.type]];
|
|
58
|
+
return handler ? [...acc, t, ...productBrokers.map((broker) => handler(t, broker))] : [...acc, t];
|
|
59
|
+
}, <ILedgerDataRow[]>[]);
|
|
60
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getLoanChargeForProduct = void 0;
|
|
7
|
+
const mongoose_1 = __importDefault(require("mongoose"));
|
|
8
|
+
const LoanCharges_model_1 = require("../models/LoanCharges.model");
|
|
9
|
+
const loan_products_db_1 = require("./loan-products.db");
|
|
10
|
+
const getLoanChargeForProduct = async (productId) => {
|
|
11
|
+
return LoanCharges_model_1.LoanCharge.aggregate([
|
|
12
|
+
{
|
|
13
|
+
$match: {
|
|
14
|
+
'productId': new mongoose_1.default.Types.ObjectId(productId),
|
|
15
|
+
'deletedAt': { $exists: false },
|
|
16
|
+
},
|
|
17
|
+
}, {
|
|
18
|
+
$sort: {
|
|
19
|
+
'order': 1,
|
|
20
|
+
},
|
|
21
|
+
}, {
|
|
22
|
+
$unset: loan_products_db_1.fieldsToUnset,
|
|
23
|
+
},
|
|
24
|
+
]);
|
|
25
|
+
};
|
|
26
|
+
exports.getLoanChargeForProduct = getLoanChargeForProduct;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
|
|
3
|
+
import { ILoanChargeView, LoanCharge } from '../models/LoanCharges.model';
|
|
4
|
+
import { fieldsToUnset } from './loan-products.db';
|
|
5
|
+
|
|
6
|
+
export const getLoanChargeForProduct = async (productId: string): Promise<ILoanChargeView[]> => {
|
|
7
|
+
return LoanCharge.aggregate<ILoanChargeView>([
|
|
8
|
+
{
|
|
9
|
+
$match: {
|
|
10
|
+
'productId': new mongoose.Types.ObjectId(productId),
|
|
11
|
+
'deletedAt': { $exists: false },
|
|
12
|
+
},
|
|
13
|
+
}, {
|
|
14
|
+
$sort: {
|
|
15
|
+
'order': 1,
|
|
16
|
+
},
|
|
17
|
+
}, {
|
|
18
|
+
$unset: fieldsToUnset,
|
|
19
|
+
},
|
|
20
|
+
]);
|
|
21
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getPaymentForTransaction = void 0;
|
|
7
|
+
const mongoose_1 = __importDefault(require("mongoose"));
|
|
8
|
+
const LoanPayment_model_1 = require("../models/LoanPayment.model");
|
|
9
|
+
const getPaymentForTransaction = async (productId, transactionId) => {
|
|
10
|
+
const payments = await LoanPayment_model_1.LoanPaymentModel.aggregate([
|
|
11
|
+
{
|
|
12
|
+
$match: {
|
|
13
|
+
'productId': new mongoose_1.default.Types.ObjectId(productId),
|
|
14
|
+
'paid.statementId': new mongoose_1.default.Types.ObjectId(transactionId),
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
]);
|
|
18
|
+
if (payments.length === 0) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
return payments;
|
|
22
|
+
};
|
|
23
|
+
exports.getPaymentForTransaction = getPaymentForTransaction;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
|
|
3
|
+
import { ILoanPaymentDoc, LoanPaymentModel } from '../models/LoanPayment.model';
|
|
4
|
+
|
|
5
|
+
export const getPaymentForTransaction = async (productId: string, transactionId: string) => {
|
|
6
|
+
const payments = await LoanPaymentModel.aggregate<ILoanPaymentDoc>([
|
|
7
|
+
{
|
|
8
|
+
$match: {
|
|
9
|
+
'productId': new mongoose.Types.ObjectId(productId),
|
|
10
|
+
'paid.statementId': new mongoose.Types.ObjectId(transactionId),
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
]);
|
|
14
|
+
if (payments.length === 0) {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
return payments;
|
|
18
|
+
}
|
package/db/loan-products.db.d.ts
CHANGED
|
@@ -23,8 +23,10 @@
|
|
|
23
23
|
/// <reference types="mongoose/types/virtuals" />
|
|
24
24
|
/// <reference types="mongoose/types/inferschematype" />
|
|
25
25
|
import mongoose from 'mongoose';
|
|
26
|
+
import { ILoanProductView } from '../models/LoanProducts.model';
|
|
26
27
|
import { ILoanChargeView } from '../models/LoanCharges.model';
|
|
27
28
|
import { IStatementPeriod } from '../models/LoanStatementTransaction.model';
|
|
29
|
+
export declare const fieldsToUnset: string[];
|
|
28
30
|
export declare const getLoanProductById: (productId: string) => Promise<mongoose.FlattenMaps<import("../models/LoanProducts.model").ILoanProductDoc> & {
|
|
29
31
|
_id: mongoose.Types.ObjectId;
|
|
30
32
|
}>;
|
|
@@ -35,3 +37,4 @@ export declare const getLoanProductBalance: (productId: string, forDate?: Date)
|
|
|
35
37
|
export declare const getPostponedTransactions: (date: Date, productId: string, removePostponed?: boolean) => Promise<number>;
|
|
36
38
|
export declare const getAverageBalance: (productId: string, period: IStatementPeriod, charge?: ILoanChargeView) => Promise<number>;
|
|
37
39
|
export declare const useFloatingBalance: (productId: string) => Promise<boolean>;
|
|
40
|
+
export declare const getLoanProducts: (borrowerId: string) => Promise<ILoanProductView[]>;
|
package/db/loan-products.db.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.useFloatingBalance = exports.getAverageBalance = exports.getPostponedTransactions = exports.getLoanProductBalance = exports.getLoanProductById = void 0;
|
|
6
|
+
exports.getLoanProducts = exports.useFloatingBalance = exports.getAverageBalance = exports.getPostponedTransactions = exports.getLoanProductBalance = exports.getLoanProductById = exports.fieldsToUnset = void 0;
|
|
7
7
|
const mongoose_1 = __importDefault(require("mongoose"));
|
|
8
8
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
9
9
|
const minMax_1 = __importDefault(require("dayjs/plugin/minMax"));
|
|
@@ -16,6 +16,7 @@ const LoanProducts_model_1 = require("../models/LoanProducts.model");
|
|
|
16
16
|
const LoanTransaction_model_1 = require("../models/LoanTransaction.model");
|
|
17
17
|
const loan_types_enum_1 = require("../enums/loan-types.enum");
|
|
18
18
|
dayjs_1.default.extend(minMax_1.default);
|
|
19
|
+
exports.fieldsToUnset = ['order', '__v', 'createdAt', 'updatedAt', 'borrowerId'];
|
|
19
20
|
const getLoanProductById = async (productId) => {
|
|
20
21
|
return LoanProducts_model_1.LoanProduct.findById(productId).lean();
|
|
21
22
|
};
|
|
@@ -165,3 +166,23 @@ const useFloatingBalance = async (productId) => {
|
|
|
165
166
|
return product.type === loan_types_enum_1.ELoanTypes.REVOLVER;
|
|
166
167
|
};
|
|
167
168
|
exports.useFloatingBalance = useFloatingBalance;
|
|
169
|
+
const getLoanProducts = async (borrowerId) => {
|
|
170
|
+
return LoanProducts_model_1.LoanProduct.aggregate([
|
|
171
|
+
{
|
|
172
|
+
$match: {
|
|
173
|
+
'borrowerId': new mongoose_1.default.Types.ObjectId(borrowerId),
|
|
174
|
+
},
|
|
175
|
+
}, {
|
|
176
|
+
$sort: {
|
|
177
|
+
'order': 1,
|
|
178
|
+
},
|
|
179
|
+
}, {
|
|
180
|
+
$unset: exports.fieldsToUnset,
|
|
181
|
+
}, {
|
|
182
|
+
$addFields: {
|
|
183
|
+
valid: true,
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
]);
|
|
187
|
+
};
|
|
188
|
+
exports.getLoanProducts = getLoanProducts;
|
package/db/loan-products.db.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { getDays } from '../helpers/date.helper';
|
|
|
7
7
|
import { roundToXDigits } from '../helpers/numbers.helper';
|
|
8
8
|
import { getTotalForDate } from './loan-statement.db';
|
|
9
9
|
import { IPostponedTransactionWithTransaction, PostponedTransaction } from '../models/PostponedTransactions.model';
|
|
10
|
-
import { LoanProduct } from '../models/LoanProducts.model';
|
|
10
|
+
import { ILoanProductView, LoanProduct } from '../models/LoanProducts.model';
|
|
11
11
|
import { ILoanChargeView } from '../models/LoanCharges.model';
|
|
12
12
|
import { ILoanTransactionDoc, LoanTransaction } from '../models/LoanTransaction.model';
|
|
13
13
|
import { IStatementPeriod } from '../models/LoanStatementTransaction.model';
|
|
@@ -15,6 +15,8 @@ import { ELoanTypes } from '../enums/loan-types.enum';
|
|
|
15
15
|
|
|
16
16
|
dayjs.extend(minMax);
|
|
17
17
|
|
|
18
|
+
export const fieldsToUnset = ['order', '__v', 'createdAt', 'updatedAt', 'borrowerId'];
|
|
19
|
+
|
|
18
20
|
export const getLoanProductById = async (productId: string) => {
|
|
19
21
|
return LoanProduct.findById(productId).lean();
|
|
20
22
|
};
|
|
@@ -169,3 +171,23 @@ export const useFloatingBalance = async (productId: string) => {
|
|
|
169
171
|
const product = await getLoanProductById(productId);
|
|
170
172
|
return product.type === ELoanTypes.REVOLVER;
|
|
171
173
|
};
|
|
174
|
+
|
|
175
|
+
export const getLoanProducts = async (borrowerId: string) => {
|
|
176
|
+
return LoanProduct.aggregate<ILoanProductView>([
|
|
177
|
+
{
|
|
178
|
+
$match: {
|
|
179
|
+
'borrowerId': new mongoose.Types.ObjectId(borrowerId),
|
|
180
|
+
},
|
|
181
|
+
}, {
|
|
182
|
+
$sort: {
|
|
183
|
+
'order': 1,
|
|
184
|
+
},
|
|
185
|
+
}, {
|
|
186
|
+
$unset: fieldsToUnset,
|
|
187
|
+
}, {
|
|
188
|
+
$addFields: {
|
|
189
|
+
valid: true,
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
]);
|
|
193
|
+
}
|
|
@@ -1,2 +1,46 @@
|
|
|
1
|
+
import { IStatementPeriod } from '../models/LoanStatementTransaction.model';
|
|
2
|
+
export declare enum ELedgerReportType {
|
|
3
|
+
SHORT = 0,
|
|
4
|
+
DETAILED = 1
|
|
5
|
+
}
|
|
6
|
+
export declare const ledgerHeadersMap: {
|
|
7
|
+
0: {
|
|
8
|
+
borrowerCode: string;
|
|
9
|
+
type: string;
|
|
10
|
+
chargeCode: string;
|
|
11
|
+
PLCode: string;
|
|
12
|
+
productCode: string;
|
|
13
|
+
productName: string;
|
|
14
|
+
info: string;
|
|
15
|
+
title: string;
|
|
16
|
+
amount: string;
|
|
17
|
+
statementAmount: string;
|
|
18
|
+
};
|
|
19
|
+
1: {
|
|
20
|
+
borrowerCode: string;
|
|
21
|
+
date: string;
|
|
22
|
+
type: string;
|
|
23
|
+
chargeCode: string;
|
|
24
|
+
PLCode: string;
|
|
25
|
+
productCode: string;
|
|
26
|
+
productName: string;
|
|
27
|
+
info: string;
|
|
28
|
+
amount: string;
|
|
29
|
+
statementAmount: string;
|
|
30
|
+
title: string;
|
|
31
|
+
balance: string;
|
|
32
|
+
floatedBalance: string;
|
|
33
|
+
paymentDate: string;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
1
36
|
export declare const getTotalTransactionAmountForCharge: (chargeId: string, start: Date, end: Date) => Promise<any>;
|
|
2
37
|
export declare const getTotalForDate: (productId: string, date: Date) => Promise<number>;
|
|
38
|
+
export declare const getStatementBorrowersTransactions: (start: string, end: string, selectedPeriod: string, selectedBorrowerIds: string[], ledgerType: ELedgerReportType) => Promise<{
|
|
39
|
+
transactions: any[];
|
|
40
|
+
}[]>;
|
|
41
|
+
export declare const getBorrowerWithPeriods: (borrowerId: string, period: {
|
|
42
|
+
selectedPeriod: string;
|
|
43
|
+
selectedStart: Date;
|
|
44
|
+
selectedEnd: Date;
|
|
45
|
+
}, splitPeriods?: boolean) => Promise<any[]>;
|
|
46
|
+
export declare const getPeriods: (selectedPeriod: string, productId: string) => Promise<IStatementPeriod[]>;
|
package/db/loan-statement.db.js
CHANGED
|
@@ -3,10 +3,52 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getTotalForDate = exports.getTotalTransactionAmountForCharge = void 0;
|
|
6
|
+
exports.getPeriods = exports.getBorrowerWithPeriods = exports.getStatementBorrowersTransactions = exports.getTotalForDate = exports.getTotalTransactionAmountForCharge = exports.ledgerHeadersMap = exports.ELedgerReportType = void 0;
|
|
7
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
7
8
|
const mongoose_1 = __importDefault(require("mongoose"));
|
|
9
|
+
const dayjs_1 = __importDefault(require("dayjs"));
|
|
8
10
|
const LoanStatementTransaction_model_1 = require("../models/LoanStatementTransaction.model");
|
|
9
11
|
const LoanTransaction_model_1 = require("../models/LoanTransaction.model");
|
|
12
|
+
const loan_products_db_1 = require("./loan-products.db");
|
|
13
|
+
const LoanProducts_model_1 = require("../models/LoanProducts.model");
|
|
14
|
+
const Borrower_model_1 = require("../models/Borrower.model");
|
|
15
|
+
const loan_transactions_db_1 = require("./loan-transactions.db");
|
|
16
|
+
const reports_db_1 = require("./reports.db");
|
|
17
|
+
var ELedgerReportType;
|
|
18
|
+
(function (ELedgerReportType) {
|
|
19
|
+
ELedgerReportType[ELedgerReportType["SHORT"] = 0] = "SHORT";
|
|
20
|
+
ELedgerReportType[ELedgerReportType["DETAILED"] = 1] = "DETAILED";
|
|
21
|
+
})(ELedgerReportType || (exports.ELedgerReportType = ELedgerReportType = {}));
|
|
22
|
+
exports.ledgerHeadersMap = {
|
|
23
|
+
[ELedgerReportType.SHORT]: {
|
|
24
|
+
borrowerCode: 'borrower code',
|
|
25
|
+
type: 'type',
|
|
26
|
+
chargeCode: 'BS code',
|
|
27
|
+
PLCode: 'P&L code',
|
|
28
|
+
productCode: 'product code',
|
|
29
|
+
productName: 'product name',
|
|
30
|
+
info: 'memo/reference',
|
|
31
|
+
title: 'title',
|
|
32
|
+
amount: 'amount',
|
|
33
|
+
statementAmount: 'Statement amount',
|
|
34
|
+
},
|
|
35
|
+
[ELedgerReportType.DETAILED]: {
|
|
36
|
+
borrowerCode: 'borrower code',
|
|
37
|
+
date: 'date',
|
|
38
|
+
type: 'type',
|
|
39
|
+
chargeCode: 'BS code',
|
|
40
|
+
PLCode: 'P&L code',
|
|
41
|
+
productCode: 'product code',
|
|
42
|
+
productName: 'product name',
|
|
43
|
+
info: 'memo/reference',
|
|
44
|
+
amount: 'amount',
|
|
45
|
+
statementAmount: 'Statement amount',
|
|
46
|
+
title: 'title',
|
|
47
|
+
balance: 'balance',
|
|
48
|
+
floatedBalance: 'floated balance',
|
|
49
|
+
paymentDate: 'payment date',
|
|
50
|
+
},
|
|
51
|
+
};
|
|
10
52
|
const getTotalTransactionAmountForCharge = async (chargeId, start, end) => {
|
|
11
53
|
const results = await LoanStatementTransaction_model_1.LoanStatementTransactionModel.aggregate([
|
|
12
54
|
{
|
|
@@ -58,3 +100,146 @@ const getTotalForDate = async (productId, date) => {
|
|
|
58
100
|
return totalAmount[0].totalAmount;
|
|
59
101
|
};
|
|
60
102
|
exports.getTotalForDate = getTotalForDate;
|
|
103
|
+
const getStatementBorrowersTransactions = async (start, end, selectedPeriod, selectedBorrowerIds, ledgerType) => {
|
|
104
|
+
const header = exports.ledgerHeadersMap[ledgerType];
|
|
105
|
+
if (!selectedBorrowerIds) {
|
|
106
|
+
return [{ transactions: [header] }];
|
|
107
|
+
}
|
|
108
|
+
const allTransactions = {};
|
|
109
|
+
await Promise.all(selectedBorrowerIds.map(async (borrowerId) => {
|
|
110
|
+
const products = await (0, loan_products_db_1.getLoanProducts)(borrowerId);
|
|
111
|
+
const periodFull = await (0, exports.getBorrowerWithPeriods)(borrowerId, {
|
|
112
|
+
selectedStart: new Date(start),
|
|
113
|
+
selectedEnd: new Date(end),
|
|
114
|
+
selectedPeriod,
|
|
115
|
+
});
|
|
116
|
+
const someMappedResults = products.reduce((acc, product) => {
|
|
117
|
+
return [
|
|
118
|
+
...acc,
|
|
119
|
+
...periodFull.map((periodDesc) => ({
|
|
120
|
+
productStart: periodDesc.period.start,
|
|
121
|
+
productEnd: periodDesc.period.end,
|
|
122
|
+
productId: product._id.toString(),
|
|
123
|
+
})),
|
|
124
|
+
];
|
|
125
|
+
}, []);
|
|
126
|
+
await Promise.all(someMappedResults.map(async (productDesc) => {
|
|
127
|
+
const borrowerTransactions = await (0, reports_db_1.getLedger)(productDesc.productId, new Date(productDesc.productStart), new Date(productDesc.productEnd), ledgerType, true);
|
|
128
|
+
Object.values(borrowerTransactions).forEach((transactions) => {
|
|
129
|
+
const [_header, ...onlyData] = transactions;
|
|
130
|
+
const mappedData = lodash_1.default.map(onlyData, (obj) => lodash_1.default.omit(obj, ['balance', 'floatedBalance']));
|
|
131
|
+
allTransactions[borrowerId] = mappedData;
|
|
132
|
+
});
|
|
133
|
+
}));
|
|
134
|
+
}));
|
|
135
|
+
const sortedTransactions = [];
|
|
136
|
+
for (const borrowerId of selectedBorrowerIds) {
|
|
137
|
+
console.log(borrowerId);
|
|
138
|
+
sortedTransactions.push(...allTransactions[borrowerId]);
|
|
139
|
+
}
|
|
140
|
+
return [{ transactions: [header, ...sortedTransactions] }];
|
|
141
|
+
};
|
|
142
|
+
exports.getStatementBorrowersTransactions = getStatementBorrowersTransactions;
|
|
143
|
+
const getBorrowerWithPeriods = async (borrowerId, period, splitPeriods = false) => {
|
|
144
|
+
const borrower = await Borrower_model_1.BorrowerModel.findById(borrowerId).lean();
|
|
145
|
+
let start;
|
|
146
|
+
let end;
|
|
147
|
+
switch (period.selectedPeriod) {
|
|
148
|
+
case 'SELECTED_PERIOD': {
|
|
149
|
+
start = (0, dayjs_1.default)(new Date(period.selectedStart)).startOf('day');
|
|
150
|
+
end = (0, dayjs_1.default)(new Date(period.selectedEnd)).endOf('day');
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
case 'ENTIRE_LOAN': {
|
|
154
|
+
const products = await LoanProducts_model_1.LoanProduct.find({ borrowerId: borrower._id.toString() }).lean();
|
|
155
|
+
const productPeriods = await Promise.all(products.map(async (product) => {
|
|
156
|
+
const periods = await (0, exports.getPeriods)(period.selectedPeriod, product._id.toString());
|
|
157
|
+
const periodStart = periods[0].start.startOf('day');
|
|
158
|
+
const periodEnd = periods[periods.length - 1].end.endOf('day');
|
|
159
|
+
return { periodStart, periodEnd };
|
|
160
|
+
}));
|
|
161
|
+
const starts = productPeriods.map((p) => p.periodStart);
|
|
162
|
+
const ends = productPeriods.map((p) => p.periodEnd);
|
|
163
|
+
start = dayjs_1.default.min(starts);
|
|
164
|
+
end = dayjs_1.default.max(ends);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
default: {
|
|
168
|
+
const periods = await (0, exports.getPeriods)(period.selectedPeriod, null);
|
|
169
|
+
start = periods[0].start.startOf('day');
|
|
170
|
+
end = periods[periods.length - 1].end.endOf('day');
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (splitPeriods) {
|
|
175
|
+
const result = [];
|
|
176
|
+
let currentMonth = start.startOf('month');
|
|
177
|
+
while (currentMonth.isBefore(end) || currentMonth.isSame(end, 'month')) {
|
|
178
|
+
const startOfMonth = currentMonth.startOf('month');
|
|
179
|
+
const endOfMonth = currentMonth.endOf('month');
|
|
180
|
+
result.push({
|
|
181
|
+
_id: borrower._id.toString(),
|
|
182
|
+
code: borrower.code,
|
|
183
|
+
name: borrower.name,
|
|
184
|
+
period: {
|
|
185
|
+
selectedPeriod: period.selectedPeriod,
|
|
186
|
+
start: startOfMonth.utc().toDate().toISOString(),
|
|
187
|
+
end: endOfMonth.utc().toDate().toISOString(),
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
currentMonth = currentMonth.add(1, 'month');
|
|
191
|
+
}
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
return [{
|
|
196
|
+
_id: borrower._id.toString(),
|
|
197
|
+
code: borrower.code,
|
|
198
|
+
name: borrower.name,
|
|
199
|
+
period: {
|
|
200
|
+
selectedPeriod: period.selectedPeriod,
|
|
201
|
+
start: start.utc().toDate().toISOString(),
|
|
202
|
+
end: end.utc().toDate().toISOString(),
|
|
203
|
+
},
|
|
204
|
+
}];
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
exports.getBorrowerWithPeriods = getBorrowerWithPeriods;
|
|
208
|
+
const getPeriods = async (selectedPeriod, productId) => {
|
|
209
|
+
let start;
|
|
210
|
+
let end;
|
|
211
|
+
switch (selectedPeriod) {
|
|
212
|
+
case 'CURRENT_MONTH': {
|
|
213
|
+
start = (0, dayjs_1.default)().utcOffset(0).startOf('month');
|
|
214
|
+
end = (0, dayjs_1.default)().utcOffset(0).endOf('month');
|
|
215
|
+
return [{ start, end }];
|
|
216
|
+
}
|
|
217
|
+
case 'LAST_MONTH': {
|
|
218
|
+
start = (0, dayjs_1.default)().subtract(1, 'month').utcOffset(0).startOf('month');
|
|
219
|
+
end = (0, dayjs_1.default)().subtract(1, 'month').utcOffset(0).endOf('month');
|
|
220
|
+
return [{ start, end }];
|
|
221
|
+
}
|
|
222
|
+
case 'ENTIRE_LOAN': {
|
|
223
|
+
const product = await (0, loan_products_db_1.getLoanProductById)(productId);
|
|
224
|
+
const lastTransaction = await (0, loan_transactions_db_1.getLastTransactionForDate)(productId);
|
|
225
|
+
start = (0, dayjs_1.default)(product.startDate).tz('UTC');
|
|
226
|
+
let lastDate = (0, dayjs_1.default)(new Date()).endOf('month').toDate();
|
|
227
|
+
if (lastTransaction) {
|
|
228
|
+
if ((0, dayjs_1.default)(lastTransaction.date).tz('UTC').toDate() > (0, dayjs_1.default)(new Date()).endOf('month').toDate()) {
|
|
229
|
+
lastDate = lastTransaction.date;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
end = (0, dayjs_1.default)(lastDate);
|
|
233
|
+
const finish = (0, dayjs_1.default)(lastDate);
|
|
234
|
+
const periods = [];
|
|
235
|
+
do {
|
|
236
|
+
end = start.endOf('month');
|
|
237
|
+
periods.push({ start, end });
|
|
238
|
+
start = end.add(1, 'day').startOf('month').utc();
|
|
239
|
+
} while (finish.toDate() > end.toDate());
|
|
240
|
+
return periods;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return [];
|
|
244
|
+
};
|
|
245
|
+
exports.getPeriods = getPeriods;
|