gemcap-be-common 1.2.140 → 1.3.0

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.
Files changed (303) hide show
  1. package/classes/bank-transaction-item.d.ts +17 -0
  2. package/classes/bank-transaction-item.js +64 -0
  3. package/classes/bank-transaction-item.ts +66 -0
  4. package/classes/bank-uploaded-transaction.d.ts +17 -0
  5. package/classes/bank-uploaded-transaction.js +35 -0
  6. package/classes/bank-uploaded-transaction.ts +35 -0
  7. package/classes/inventory-item.d.ts +41 -0
  8. package/classes/inventory-item.js +44 -0
  9. package/classes/inventory-item.ts +63 -0
  10. package/classes/payable-account-item.d.ts +22 -0
  11. package/classes/payable-account-item.js +27 -0
  12. package/classes/payable-account-item.ts +35 -0
  13. package/classes/quickbook-item.d.ts +37 -0
  14. package/classes/quickbook-item.js +51 -0
  15. package/classes/quickbook-item.ts +59 -0
  16. package/classes/receivable-item.d.ts +26 -0
  17. package/classes/receivable-item.js +28 -0
  18. package/classes/receivable-item.ts +38 -0
  19. package/constants/date-formats.contsants.d.ts +1 -0
  20. package/constants/date-formats.contsants.js +4 -0
  21. package/constants/date-formats.contsants.ts +1 -0
  22. package/db/brokers.db.d.ts +185 -0
  23. package/db/brokers.db.js +35 -2
  24. package/db/brokers.db.ts +34 -1
  25. package/db/collateral-adjustments.db.d.ts +34 -0
  26. package/db/collateral-adjustments.db.js +52 -0
  27. package/db/collateral-adjustments.db.ts +54 -0
  28. package/db/collaterals.db.d.ts +1 -1
  29. package/db/equipment.db.d.ts +40 -0
  30. package/db/equipment.db.js +55 -0
  31. package/db/equipment.db.ts +56 -0
  32. package/db/financial-spreading.db.ts +2 -1
  33. package/db/groups.d.ts +5 -0
  34. package/db/groups.js +57 -0
  35. package/db/groups.ts +52 -0
  36. package/db/inventories.d.ts +91 -0
  37. package/db/inventories.js +449 -0
  38. package/db/inventories.ts +481 -0
  39. package/db/inventory-availability.d.ts +3 -0
  40. package/db/inventory-availability.js +103 -0
  41. package/db/inventory-availability.ts +113 -0
  42. package/db/new-summary.d.ts +31 -0
  43. package/db/new-summary.js +1295 -0
  44. package/db/new-summary.ts +1509 -0
  45. package/db/payable-accounts.d.ts +30 -0
  46. package/db/payable-accounts.js +55 -0
  47. package/db/payable-accounts.ts +50 -0
  48. package/db/reserve.db.d.ts +34 -0
  49. package/db/reserve.db.js +52 -0
  50. package/db/reserve.db.ts +48 -0
  51. package/db/uploads.db.d.ts +2 -0
  52. package/db/uploads.db.js +29 -0
  53. package/db/uploads.db.ts +24 -0
  54. package/helpers/main.helper.d.ts +31 -0
  55. package/helpers/main.helper.js +63 -0
  56. package/helpers/main.helper.ts +63 -0
  57. package/models/AccountPayableItem.model.d.ts +6 -6
  58. package/models/AllocatedBankTransaction.model.d.ts +54 -0
  59. package/models/AllocatedBankTransaction.model.js +70 -0
  60. package/models/AllocatedBankTransaction.model.ts +94 -0
  61. package/models/AllocatedData.model.d.ts +33 -0
  62. package/models/AllocatedData.model.js +19 -0
  63. package/models/AllocatedData.model.ts +24 -0
  64. package/models/BBCDate.model.d.ts +3 -3
  65. package/models/BBCSheet.model.d.ts +3 -3
  66. package/models/Banks.model.d.ts +3 -3
  67. package/models/Borrower.model.d.ts +3 -3
  68. package/models/BorrowerData.model.d.ts +3 -3
  69. package/models/BorrowerDataInsurance.model.d.ts +3 -3
  70. package/models/BorrowerDataTerm.model.d.ts +3 -3
  71. package/models/BorrowerSummary.model.js +1 -1
  72. package/models/BorrowerSummary.model.ts +1 -1
  73. package/models/CalandarDay.model.d.ts +40 -0
  74. package/models/CalandarDay.model.js +47 -0
  75. package/models/CalandarDay.model.ts +61 -0
  76. package/models/CashAllocationProduct.model.d.ts +119 -0
  77. package/models/CashAllocationProduct.model.js +102 -0
  78. package/models/CashAllocationProduct.model.ts +112 -0
  79. package/models/CashAllocationReference.model.d.ts +37 -0
  80. package/models/CashAllocationReference.model.js +27 -0
  81. package/models/CashAllocationReference.model.ts +40 -0
  82. package/models/CollateralAdjustment.model.d.ts +51 -0
  83. package/models/CollateralAdjustment.model.js +61 -0
  84. package/models/CollateralAdjustment.model.ts +98 -0
  85. package/models/Company.model.d.ts +35 -0
  86. package/models/Company.model.js +18 -0
  87. package/models/Company.model.ts +29 -0
  88. package/models/CustomerAPGroup.model.d.ts +32 -0
  89. package/models/CustomerAPGroup.model.js +24 -0
  90. package/models/CustomerAPGroup.model.ts +31 -0
  91. package/models/Equipment.model.d.ts +53 -0
  92. package/models/Equipment.model.js +140 -0
  93. package/models/Equipment.model.ts +172 -0
  94. package/models/FinancialCompliance.model.d.ts +39 -0
  95. package/models/FinancialCompliance.model.js +64 -0
  96. package/models/FinancialCompliance.model.ts +78 -0
  97. package/models/FinancialComplianceBorrower.model.d.ts +58 -0
  98. package/models/FinancialComplianceBorrower.model.js +82 -0
  99. package/models/FinancialComplianceBorrower.model.ts +118 -0
  100. package/models/FinancialIndexes.model.d.ts +36 -0
  101. package/models/FinancialIndexes.model.js +27 -0
  102. package/models/FinancialIndexes.model.ts +37 -0
  103. package/models/Inventory.model.d.ts +18 -18
  104. package/models/InventoryAvailability.model.d.ts +21 -21
  105. package/models/InventoryAvailabilityItem.model.d.ts +6 -6
  106. package/models/InventoryItem.model.d.ts +24 -24
  107. package/models/InventoryManualEntry.model.d.ts +9 -9
  108. package/models/InventorySeasonalRates.model.d.ts +3 -3
  109. package/models/LoanBroker.model.d.ts +3 -3
  110. package/models/LoanCharges.model.d.ts +12 -12
  111. package/models/LoanProducts.model.d.ts +9 -9
  112. package/models/LoanStatementStatus.model.d.ts +35 -0
  113. package/models/LoanStatementStatus.model.js +34 -0
  114. package/models/LoanStatementStatus.model.ts +45 -0
  115. package/models/LoanStatementTransaction.model.d.ts +9 -9
  116. package/models/LoanTransactionFile.model.d.ts +41 -0
  117. package/models/LoanTransactionFile.model.js +44 -0
  118. package/models/LoanTransactionFile.model.ts +61 -0
  119. package/models/MappedGroup.model.d.ts +37 -0
  120. package/models/MappedGroup.model.js +33 -0
  121. package/models/MappedGroup.model.ts +46 -0
  122. package/models/MonthEndData.Model.d.ts +41 -0
  123. package/models/MonthEndData.Model.js +42 -0
  124. package/models/MonthEndData.Model.ts +53 -0
  125. package/models/OrganizationEmails.model.d.ts +44 -0
  126. package/models/OrganizationEmails.model.js +40 -0
  127. package/models/OrganizationEmails.model.ts +54 -0
  128. package/models/ProductBroker.model.d.ts +9 -9
  129. package/models/QuickbooksAccount.model.d.ts +39 -0
  130. package/models/QuickbooksAccount.model.js +43 -0
  131. package/models/QuickbooksAccount.model.ts +57 -0
  132. package/models/Receivable.model.d.ts +12 -12
  133. package/models/ReceivableAvailability.model.d.ts +54 -54
  134. package/models/ReceivableAvailabilityItem.model.d.ts +57 -57
  135. package/models/ReceivableItem.model.d.ts +6 -6
  136. package/models/Reserve.model.d.ts +51 -0
  137. package/models/Reserve.model.js +96 -0
  138. package/models/Reserve.model.ts +125 -0
  139. package/models/TermLoan.model.d.ts +3 -3
  140. package/models/TermLoanCalculated.model.d.ts +6 -6
  141. package/models/TransactionAttachedFile.Model.d.ts +35 -0
  142. package/models/TransactionAttachedFile.Model.js +37 -0
  143. package/models/TransactionAttachedFile.Model.ts +48 -0
  144. package/models/UploadedBankTransaction.model.d.ts +56 -0
  145. package/models/UploadedBankTransaction.model.js +78 -0
  146. package/models/UploadedBankTransaction.model.ts +110 -0
  147. package/models/UploadedData.model.d.ts +36 -0
  148. package/models/UploadedData.model.js +23 -0
  149. package/models/UploadedData.model.ts +35 -0
  150. package/models/UploadedFile.model.d.ts +40 -0
  151. package/models/UploadedFile.model.js +41 -0
  152. package/models/UploadedFile.model.ts +57 -0
  153. package/models/UploadedSheet.model.d.ts +46 -0
  154. package/models/UploadedSheet.model.js +27 -0
  155. package/models/UploadedSheet.model.ts +51 -0
  156. package/package.json +10 -1
  157. package/repositories/globals.repository.d.ts +8 -0
  158. package/repositories/globals.repository.js +24 -0
  159. package/repositories/globals.repository.ts +21 -0
  160. package/services/attached-files.service.d.ts +57 -0
  161. package/services/attached-files.service.js +103 -0
  162. package/services/attached-files.service.ts +123 -0
  163. package/services/availability.service.d.ts +77 -0
  164. package/services/availability.service.js +897 -0
  165. package/services/availability.service.ts +1034 -0
  166. package/services/bank-uploaded-transactions.service.d.ts +33 -0
  167. package/services/bank-uploaded-transactions.service.js +430 -0
  168. package/services/bank-uploaded-transactions.service.ts +475 -0
  169. package/services/banks.service.d.ts +36 -0
  170. package/services/banks.service.js +91 -0
  171. package/services/banks.service.ts +95 -0
  172. package/services/borrower-summary.service.d.ts +35 -0
  173. package/services/borrower-summary.service.js +310 -0
  174. package/services/borrower-summary.service.ts +334 -0
  175. package/services/borrowers.service.d.ts +103 -0
  176. package/services/borrowers.service.js +268 -0
  177. package/services/borrowers.service.ts +302 -0
  178. package/services/brokers.service.d.ts +212 -0
  179. package/services/brokers.service.js +160 -0
  180. package/services/brokers.service.ts +200 -0
  181. package/services/calendar.service.d.ts +53 -0
  182. package/services/calendar.service.js +108 -0
  183. package/services/calendar.service.ts +128 -0
  184. package/services/cash-allocation.service.d.ts +40 -0
  185. package/services/cash-allocation.service.js +92 -0
  186. package/services/cash-allocation.service.ts +105 -0
  187. package/services/collateral-adjustments.service.d.ts +38 -0
  188. package/services/collateral-adjustments.service.js +82 -0
  189. package/services/collateral-adjustments.service.ts +95 -0
  190. package/services/collaterals.service.d.ts +69 -0
  191. package/services/collaterals.service.js +279 -0
  192. package/services/collaterals.service.ts +319 -0
  193. package/services/companies.service.d.ts +5 -0
  194. package/services/companies.service.js +21 -0
  195. package/services/companies.service.ts +23 -0
  196. package/services/compliance-borrowers.service.d.ts +152 -0
  197. package/services/compliance-borrowers.service.js +569 -0
  198. package/services/compliance-borrowers.service.ts +617 -0
  199. package/services/equipment.service.d.ts +42 -0
  200. package/services/equipment.service.js +120 -0
  201. package/services/equipment.service.ts +149 -0
  202. package/services/file-manager.service.d.ts +44 -0
  203. package/services/file-manager.service.js +120 -0
  204. package/services/file-manager.service.ts +146 -0
  205. package/services/financial-compliance.service.d.ts +58 -0
  206. package/services/financial-compliance.service.js +281 -0
  207. package/services/financial-compliance.service.ts +309 -0
  208. package/services/financial-indexes.service.d.ts +20 -0
  209. package/services/financial-indexes.service.js +241 -0
  210. package/services/financial-indexes.service.ts +257 -0
  211. package/services/financial-spreading.service.d.ts +74 -0
  212. package/services/financial-spreading.service.js +450 -0
  213. package/services/financial-spreading.service.ts +517 -0
  214. package/services/globals.service.d.ts +5 -0
  215. package/services/globals.service.js +11 -0
  216. package/services/globals.service.ts +8 -0
  217. package/services/groups.service.d.ts +39 -0
  218. package/services/groups.service.js +65 -0
  219. package/services/groups.service.ts +64 -0
  220. package/services/inventory-availability.service.d.ts +13 -0
  221. package/services/inventory-availability.service.js +170 -0
  222. package/services/inventory-availability.service.ts +187 -0
  223. package/services/inventory.service.d.ts +118 -0
  224. package/services/inventory.service.js +239 -0
  225. package/services/inventory.service.ts +276 -0
  226. package/services/loan-charges.service.d.ts +83 -0
  227. package/services/loan-charges.service.js +343 -0
  228. package/services/loan-charges.service.ts +396 -0
  229. package/services/loan-payments.service.d.ts +94 -0
  230. package/services/loan-payments.service.js +485 -0
  231. package/services/loan-payments.service.ts +541 -0
  232. package/services/loan-products.service.d.ts +12 -0
  233. package/services/loan-products.service.js +55 -0
  234. package/services/loan-products.service.ts +58 -0
  235. package/services/loan-statement-balance.service.d.ts +16 -0
  236. package/services/loan-statement-balance.service.js +106 -0
  237. package/services/loan-statement-balance.service.ts +113 -0
  238. package/services/loan-statement-effects.service.d.ts +8 -0
  239. package/services/loan-statement-effects.service.js +42 -0
  240. package/services/loan-statement-effects.service.ts +41 -0
  241. package/services/loan-statement-status.service.d.ts +208 -0
  242. package/services/loan-statement-status.service.js +159 -0
  243. package/services/loan-statement-status.service.ts +177 -0
  244. package/services/loan-statement.service.d.ts +186 -0
  245. package/services/loan-statement.service.js +935 -0
  246. package/services/loan-statement.service.ts +1040 -0
  247. package/services/loan-transactions.service.d.ts +169 -0
  248. package/services/loan-transactions.service.js +941 -0
  249. package/services/loan-transactions.service.ts +1042 -0
  250. package/services/lock.service.d.ts +6 -0
  251. package/services/lock.service.js +45 -0
  252. package/services/lock.service.ts +45 -0
  253. package/services/manual-entry.service.d.ts +20 -0
  254. package/services/manual-entry.service.js +186 -0
  255. package/services/manual-entry.service.ts +201 -0
  256. package/services/month-end-data.service.d.ts +34 -0
  257. package/services/month-end-data.service.js +30 -0
  258. package/services/month-end-data.service.ts +35 -0
  259. package/services/nodemailer.service.d.ts +96 -0
  260. package/services/nodemailer.service.js +689 -0
  261. package/services/nodemailer.service.ts +774 -0
  262. package/services/organization-emails.service.d.ts +31 -0
  263. package/services/organization-emails.service.js +10 -0
  264. package/services/organization-emails.service.ts +7 -0
  265. package/services/organizations.service.d.ts +34 -0
  266. package/services/organizations.service.js +74 -0
  267. package/services/organizations.service.ts +84 -0
  268. package/services/pdf.service.d.ts +61 -0
  269. package/services/pdf.service.js +547 -0
  270. package/services/pdf.service.ts +642 -0
  271. package/services/quickbooks.service.d.ts +99 -0
  272. package/services/quickbooks.service.js +640 -0
  273. package/services/quickbooks.service.ts +734 -0
  274. package/services/reports/investor-summary.service.d.ts +28 -0
  275. package/services/reports/investor-summary.service.js +136 -0
  276. package/services/reports/investor-summary.service.ts +159 -0
  277. package/services/reports.service.d.ts +126 -0
  278. package/services/reports.service.js +584 -0
  279. package/services/reports.service.ts +702 -0
  280. package/services/reserve.service.d.ts +37 -0
  281. package/services/reserve.service.js +76 -0
  282. package/services/reserve.service.ts +79 -0
  283. package/services/sentry.service.d.ts +11 -0
  284. package/services/sentry.service.js +49 -0
  285. package/services/sentry.service.ts +33 -0
  286. package/services/signs.service.d.ts +69 -0
  287. package/services/signs.service.js +230 -0
  288. package/services/signs.service.ts +260 -0
  289. package/services/term-loan.service.d.ts +30 -0
  290. package/services/term-loan.service.js +614 -0
  291. package/services/term-loan.service.ts +696 -0
  292. package/services/uploads.service.d.ts +134 -0
  293. package/services/uploads.service.js +587 -0
  294. package/services/uploads.service.ts +643 -0
  295. package/services/user-logs.service.d.ts +23 -0
  296. package/services/user-logs.service.js +160 -0
  297. package/services/user-logs.service.ts +177 -0
  298. package/services/users.service.d.ts +4 -4
  299. package/services/yield.service.d.ts +46 -0
  300. package/services/yield.service.js +42 -12
  301. package/services/yield.service.ts +38 -8
  302. package/tsconfig.json +5 -5
  303. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,396 @@
1
+ import mongoose from 'mongoose';
2
+ import dayjs from 'dayjs';
3
+
4
+ import { IPaginatorOptions } from '../interfaces/collaterals.interface';
5
+ import { ELoanChargeType } from '../enums/loan-charge-type.enum';
6
+ import { MODEL_NAMES } from '../models/_models';
7
+ import {
8
+ fieldsToUnset,
9
+ getLoanProductBalance as getLoanProductBalanceDB,
10
+ getLoanProductById as getLoanProductDB,
11
+ getLoanProducts,
12
+ } from '../db/loan-products.db';
13
+ import { EChargeCalculationBasis, EChargeFrequencies, ELoanTypes } from '../enums/loan-types.enum';
14
+ import { getLoanChargeForProduct } from '../db/loan-charges.db';
15
+ import {
16
+ ILoanProductDoc,
17
+ ILoanProductView,
18
+ ILoanProductWithId,
19
+ LoanProduct,
20
+ } from '../models/LoanProducts.model';
21
+ import {
22
+ chargeViewValidationSchema,
23
+ ILoanChargeView,
24
+ ILoanChargeWithId,
25
+ LoanCharge,
26
+ } from '../models/LoanCharges.model';
27
+ import {
28
+ ILoanStatementTransactionDoc,
29
+ ILoanStatementTransactionDocWithCharge,
30
+ LoanStatementTransactionModel,
31
+ } from '../models/LoanStatementTransaction.model';
32
+ import { ITEMS_PAGINATION } from '../db/collaterals.db';
33
+ import { BorrowerService } from './borrowers.service';
34
+
35
+ const updateChargesForProduct = false;
36
+
37
+ export class LoanChargesService {
38
+
39
+ constructor(
40
+ private readonly borrowerService: BorrowerService,
41
+ ) {
42
+ }
43
+
44
+ private validateCharge = (charge: ILoanChargeView) => {
45
+ const chargePLCode = charge.PLCode ? charge.PLCode.trim() : '';
46
+ const chargeBorrowerCode = charge.code.trim().slice(3, 6);
47
+ return chargePLCode.length > 0 && chargeBorrowerCode.length > 0;
48
+ };
49
+
50
+ async getProductByChargeId(chargeId: string) {
51
+ const charge = await LoanCharge.findById(chargeId).lean();
52
+ if (!charge) {
53
+ return null;
54
+ }
55
+ return LoanProduct.findById(charge.productId).lean();
56
+ }
57
+
58
+ async getBorrowersLoanProducts(borrowerId: string) {
59
+ return LoanProduct.find({ borrowerId }).lean();
60
+ }
61
+
62
+ async getAllLoanProducts() {
63
+ const borrowers = await this.borrowerService.getActiveBorrowers();
64
+ const borrowerIds = borrowers.map((borrower) => borrower._id);
65
+ return LoanProduct.aggregate<ILoanProductDoc>([
66
+ { $match: { borrowerId: { $in: borrowerIds } } },
67
+ {
68
+ $lookup: {
69
+ from: MODEL_NAMES.borrowers,
70
+ localField: 'borrowerId',
71
+ foreignField: '_id',
72
+ as: 'borrower',
73
+ },
74
+ },
75
+ { $unwind: '$borrower' },
76
+ { $sort: { 'borrower.name': 1 } },
77
+ { $project: { borrower: 0 } },
78
+ ]);
79
+ }
80
+
81
+ async getLoanProducts(borrowerId: string) {
82
+ return getLoanProducts(borrowerId);
83
+ }
84
+
85
+ async getLoanProductsByIds(productIds: string[]) {
86
+ const ids = productIds.map((productId) => new mongoose.Types.ObjectId(productId));
87
+ return LoanProduct.aggregate<ILoanProductView>([
88
+ {
89
+ $match: {
90
+ '_id': { $in: ids },
91
+ },
92
+ }, {
93
+ $sort: {
94
+ 'order': 1,
95
+ },
96
+ }, {
97
+ $unset: fieldsToUnset,
98
+ }, {
99
+ $addFields: {
100
+ valid: true,
101
+ },
102
+ },
103
+ ]);
104
+ }
105
+
106
+ async getLoanProductBalance(productId: string, forDate = new Date()) {
107
+ return getLoanProductBalanceDB(productId, forDate);
108
+ }
109
+
110
+ async getParticipationBalance(code: string, end: Date){
111
+ const masterProduct = await LoanProduct.findOne({ masterCode: code }).lean();
112
+ if (!masterProduct) {
113
+ return 0;
114
+ }
115
+ const { balance } = await this.getLoanProductBalance(masterProduct._id.toString(), end);
116
+ return balance;
117
+ };
118
+
119
+ async getLoanProductById(productId: string) {
120
+ return getLoanProductDB(productId);
121
+ }
122
+
123
+ async getLoanProductIdByCode(code: string): Promise<string> {
124
+ const foundProduct = await LoanProduct.findOne({ code }).lean();
125
+ if (foundProduct) {
126
+ return foundProduct._id.toString();
127
+ }
128
+ return null;
129
+ }
130
+
131
+ async getLoanChargeIdByCode(code: string): Promise<string> {
132
+ const foundCharge = await LoanCharge.findOne({ code }).lean();
133
+ if (foundCharge) {
134
+ return foundCharge._id.toString();
135
+ }
136
+ return null;
137
+ }
138
+
139
+ async saveLoanProducts(borrowerId: string, loanProducts: ILoanProductView[]): Promise<void> {
140
+ const mappedProducts: ILoanProductWithId[] = loanProducts.map((product, order) => {
141
+ return { ...product, borrowerId: new mongoose.Types.ObjectId(borrowerId), order };
142
+ });
143
+ const allProducts = await this.getLoanProducts(borrowerId);
144
+ const productIdsToRemove = allProducts.map((product) => product._id.toString());
145
+ await Promise.all(mappedProducts.map(async (product) => {
146
+ if (!product._id) {
147
+ const newProduct = new LoanProduct(product);
148
+ const savedProduct = await newProduct.save();
149
+ if (product.type === ELoanTypes.TERM) {
150
+ const chargeTypes = [
151
+ {
152
+ chargeType: ELoanChargeType.INTEREST_FEE,
153
+ calculationBasis: EChargeCalculationBasis.DAILY_BALANCE,
154
+ frequency: EChargeFrequencies.DAILY,
155
+ },
156
+ {
157
+ chargeType: ELoanChargeType.ADMIN_FEE,
158
+ calculationBasis: EChargeCalculationBasis.AVERAGE_MONTHLY_BALANCE,
159
+ frequency: EChargeFrequencies.MONTHLY,
160
+ },
161
+ ];
162
+ const charges = chargeTypes.map((charge) => {
163
+ const newCharge: ILoanChargeView = {
164
+ PLCode: 'XXXXXX',
165
+ _id: null,
166
+ active: true,
167
+ applyFrom: product.startDate,
168
+ calculationBasis: charge.calculationBasis,
169
+ chargeType: charge.chargeType,
170
+ code: 'XXXXXX',
171
+ frequency: charge.frequency,
172
+ includeInYield: true,
173
+ minimumAmount: 0,
174
+ name: charge.chargeType,
175
+ percent: 0,
176
+ productId: new mongoose.Types.ObjectId(String(savedProduct._id)),
177
+ };
178
+ return newCharge;
179
+ });
180
+ await this.saveLoanCharges(borrowerId, charges, true);
181
+ }
182
+ } else {
183
+ await LoanProduct.findByIdAndUpdate(product._id, product);
184
+ if (updateChargesForProduct) {
185
+ await this.updatedChargeCodes(product._id.toString());
186
+ }
187
+ const index = productIdsToRemove.indexOf(product._id.toString());
188
+ if (index > -1) {
189
+ productIdsToRemove.splice(index, 1);
190
+ }
191
+ }
192
+ }));
193
+ await Promise.all(productIdsToRemove.map(async (id) => {
194
+ await LoanProduct.findByIdAndDelete(id);
195
+ const foundLinkedCharges = await LoanCharge.find({ productId: new mongoose.Types.ObjectId(id) });
196
+ await Promise.all(foundLinkedCharges.map(async (foundLinked) => {
197
+ await LoanCharge.findByIdAndDelete(foundLinked._id);
198
+ }));
199
+ }));
200
+ }
201
+
202
+ async getLoanCharges(borrowerId: string): Promise<ILoanChargeView[]> {
203
+ return LoanCharge.aggregate<ILoanChargeView>([
204
+ {
205
+ $match: {
206
+ 'borrowerId': new mongoose.Types.ObjectId(borrowerId),
207
+ 'deletedAt': { $exists: false },
208
+ },
209
+ }, {
210
+ $sort: {
211
+ 'productId': 1,
212
+ 'order': 1,
213
+ },
214
+ }, {
215
+ $unset: fieldsToUnset,
216
+ }, {
217
+ $addFields: {
218
+ valid: true,
219
+ },
220
+ },
221
+ ]);
222
+ }
223
+
224
+ async getLoanChargeForProduct(productId: string): Promise<ILoanChargeView[]> {
225
+ return getLoanChargeForProduct(productId);
226
+ }
227
+
228
+ validateLoanCharge(loanCharge: ILoanChargeView) {
229
+ const validationResult = chargeViewValidationSchema.validate(loanCharge);
230
+ return !!validationResult.error;
231
+ }
232
+
233
+ async saveLoanCharges(borrowerId: string, loanCharges: ILoanChargeView[], quickCreate = false): Promise<void> {
234
+ const mappedCharges: ILoanChargeWithId[] = loanCharges.map((charge, order) => {
235
+ return { ...charge, borrowerId: new mongoose.Types.ObjectId(borrowerId), order };
236
+ });
237
+ const allCharges = await this.getLoanCharges(borrowerId);
238
+ const chargeIdsToRemove = allCharges.map((charge) => charge._id.toString());
239
+ await Promise.all(mappedCharges.map(async (charge) => {
240
+ if (!quickCreate) {
241
+ if (!this.validateCharge(charge)) {
242
+ if (charge._id) {
243
+ const index = chargeIdsToRemove.indexOf(charge._id.toString());
244
+ if (index > -1) {
245
+ chargeIdsToRemove.splice(index, 1);
246
+ }
247
+ }
248
+ return;
249
+ }
250
+ }
251
+ if (!charge._id || charge._id.toString().includes('new_')) {
252
+ const { _id, ...rest } = charge;
253
+ const newCharge = new LoanCharge(rest);
254
+ await newCharge.save();
255
+ } else {
256
+ await LoanCharge.findByIdAndUpdate(charge._id, charge);
257
+ const index = chargeIdsToRemove.indexOf(charge._id.toString());
258
+ if (index > -1) {
259
+ chargeIdsToRemove.splice(index, 1);
260
+ }
261
+ }
262
+ }));
263
+ if (!quickCreate) {
264
+ await Promise.all(chargeIdsToRemove.map(async (id) => {
265
+ await LoanCharge.findByIdAndUpdate(id, { deletedAt: new Date() });
266
+ }));
267
+ }
268
+ }
269
+
270
+ private async getChargeIds(productIds: string[], chargeType: ELoanChargeType = null) {
271
+ const loanChargesGrouped = await Promise.all(productIds.map(async (productId) => {
272
+ return await this.getLoanChargeForProduct(productId);
273
+ }));
274
+ const loanCharges = loanChargesGrouped.reduce((acc, group) => [...acc, ...group], []);
275
+ const filteredCharges = chargeType ? loanCharges.filter((charge) => charge.chargeType === chargeType) : loanCharges;
276
+ return filteredCharges.map((charge) => charge._id);
277
+ }
278
+
279
+ async getLoanStatementsForProduct(filter: {
280
+ productIds: string[],
281
+ start: Date,
282
+ end: Date
283
+ }, paginatorOptions: IPaginatorOptions = null, chargeType: ELoanChargeType = null) {
284
+ const chargesIds = await this.getChargeIds(filter.productIds, chargeType);
285
+ return LoanStatementTransactionModel.aggregate<ILoanStatementTransactionDoc>([
286
+ {
287
+ $match: {
288
+ $and: [
289
+ { 'date': { $gte: filter.start } },
290
+ { 'date': { $lte: dayjs(filter.end).endOf('day').toDate() } },
291
+ { 'chargeId': { '$in': chargesIds } },
292
+ ],
293
+ },
294
+ }, {
295
+ $sort: {
296
+ 'date': 1,
297
+ 'order': 1,
298
+ },
299
+ },
300
+ ...ITEMS_PAGINATION(paginatorOptions),
301
+ ]);
302
+ }
303
+
304
+ async getLoanStatementsForIdsAndCharge(filter: {
305
+ productIds: string[],
306
+ transactionIds: string[],
307
+ start: Date,
308
+ end: Date
309
+ }, paginatorOptions: IPaginatorOptions = null, chargeType: ELoanChargeType = null) {
310
+ const chargesIds = await this.getChargeIds(filter.productIds, chargeType);
311
+ return LoanStatementTransactionModel.aggregate<ILoanStatementTransactionDoc>([
312
+ {
313
+ $match: {
314
+ $and: [
315
+ { '_id': { '$in': filter.transactionIds } },
316
+ { 'chargeId': { '$in': chargesIds } },
317
+ ],
318
+ },
319
+ }, {
320
+ $sort: {
321
+ 'date': 1,
322
+ 'order': 1,
323
+ },
324
+ },
325
+ ...ITEMS_PAGINATION(paginatorOptions),
326
+ ]);
327
+ }
328
+
329
+ async getLoanStatementsForForProductWithCharges(filter: {
330
+ productIds: string[],
331
+ start: Date,
332
+ end: Date
333
+ }, paginatorOptions?: IPaginatorOptions) {
334
+ const loanChargesGrouped = await Promise.all(filter.productIds.map(async (productId) => {
335
+ return await this.getLoanChargeForProduct(productId);
336
+ }));
337
+ const loanCharges = loanChargesGrouped.reduce((acc, group) => [...acc, ...group], []);
338
+ const chargesIds = loanCharges.map((charge) => charge._id);
339
+ return LoanStatementTransactionModel.aggregate<ILoanStatementTransactionDocWithCharge>([
340
+ {
341
+ $match: {
342
+ $and: [
343
+ { 'date': { $gte: filter.start } },
344
+ { 'date': { $lte: filter.end } },
345
+ { 'chargeId': { '$in': chargesIds } },
346
+ ],
347
+ },
348
+ }, {
349
+ $sort: {
350
+ 'date': 1,
351
+ 'order': 1,
352
+ },
353
+ }, {
354
+ $lookup: {
355
+ from: 'loan_charges',
356
+ localField: 'chargeId',
357
+ foreignField: '_id',
358
+ as: 'charge',
359
+ },
360
+ }, {
361
+ $unwind: {
362
+ path: '$charge',
363
+ },
364
+ },
365
+ ...ITEMS_PAGINATION(paginatorOptions),
366
+ ]);
367
+ }
368
+
369
+ async getTotalLoanStatementsForProduct(filter: { productIds: string[], start: Date, end: Date }) {
370
+ const loanChargesGrouped = await Promise.all(filter.productIds.map(async (productId) => {
371
+ return await this.getLoanChargeForProduct(productId);
372
+ }));
373
+ const loanCharges = loanChargesGrouped.reduce((acc, group) => [...acc, ...group], []);
374
+ const chargesIds = loanCharges.map((charge) => charge._id);
375
+ return LoanStatementTransactionModel.countDocuments(
376
+ {
377
+ $and: [
378
+ { 'chargeId': { $in: chargesIds } },
379
+ { 'date': { $gte: filter.start } },
380
+ { 'date': { $lte: filter.end } },
381
+ ],
382
+ },
383
+ );
384
+ }
385
+
386
+ async updatedChargeCodes(productId: string) {
387
+ const product = await LoanProduct.findById(productId).lean();
388
+ const borrowerProductCode = product.code.trim().slice(3, 6);
389
+ const charges = await this.getLoanChargeForProduct(productId);
390
+ await Promise.all(charges.map(async (charge) => {
391
+ const newCode = charge.code.trim().slice(0, 3) + borrowerProductCode;
392
+ await LoanCharge.findByIdAndUpdate(charge._id, { code: newCode });
393
+ }));
394
+ }
395
+
396
+ }
@@ -0,0 +1,94 @@
1
+ /// <reference types="mongoose/types/aggregate" />
2
+ /// <reference types="mongoose/types/callback" />
3
+ /// <reference types="mongoose/types/collection" />
4
+ /// <reference types="mongoose/types/connection" />
5
+ /// <reference types="mongoose/types/cursor" />
6
+ /// <reference types="mongoose/types/document" />
7
+ /// <reference types="mongoose/types/error" />
8
+ /// <reference types="mongoose/types/expressions" />
9
+ /// <reference types="mongoose/types/helpers" />
10
+ /// <reference types="mongoose/types/middlewares" />
11
+ /// <reference types="mongoose/types/indexes" />
12
+ /// <reference types="mongoose/types/models" />
13
+ /// <reference types="mongoose/types/mongooseoptions" />
14
+ /// <reference types="mongoose/types/pipelinestage" />
15
+ /// <reference types="mongoose/types/populate" />
16
+ /// <reference types="mongoose/types/query" />
17
+ /// <reference types="mongoose/types/schemaoptions" />
18
+ /// <reference types="mongoose/types/schematypes" />
19
+ /// <reference types="mongoose/types/session" />
20
+ /// <reference types="mongoose/types/types" />
21
+ /// <reference types="mongoose/types/utility" />
22
+ /// <reference types="mongoose/types/validation" />
23
+ /// <reference types="mongoose/types/virtuals" />
24
+ /// <reference types="mongoose/types/inferschematype" />
25
+ import mongoose from 'mongoose';
26
+ import { RedisClientType } from 'redis';
27
+ import { IPaginatorOptions } from '../interfaces/collaterals.interface';
28
+ import { ELoanChargeType } from '../enums/loan-charge-type.enum';
29
+ import { ICombinedPayment, ILoanPaymentDoc, ILoanPaymentWithId } from '../models/LoanPayment.model';
30
+ import { BorrowerService } from './borrowers.service';
31
+ import { LoanStatementBalanceService } from './loan-statement-balance.service';
32
+ import { LoanProductsService } from './loan-products.service';
33
+ import { LoanChargesService } from './loan-charges.service';
34
+ import { FinancialComplianceService } from './financial-compliance.service';
35
+ import { LoanStatementService } from './loan-statement.service';
36
+ import { LoanStatementStatusService } from './loan-statement-status.service';
37
+ import { LoanTransactionsService } from './loan-transactions.service';
38
+ import { TermLoanService } from './term-loan.service';
39
+ import { LockService } from './lock.service';
40
+ export declare const paymentOrder: ELoanChargeType[];
41
+ export declare class LoanPaymentsService {
42
+ private readonly redisClient;
43
+ private readonly borrowerService;
44
+ private readonly financialComplianceService;
45
+ private readonly loanChargesService;
46
+ private readonly loanProductsService;
47
+ private readonly loanStatementBalanceService;
48
+ private readonly getLoanStatementService;
49
+ private readonly loanStatementStatusService;
50
+ private readonly loanTransactionsService;
51
+ private readonly lockService;
52
+ private readonly termLoanService;
53
+ constructor(redisClient: RedisClientType, borrowerService: BorrowerService, financialComplianceService: FinancialComplianceService, loanChargesService: LoanChargesService, loanProductsService: LoanProductsService, loanStatementBalanceService: LoanStatementBalanceService, getLoanStatementService: () => LoanStatementService, loanStatementStatusService: LoanStatementStatusService, loanTransactionsService: LoanTransactionsService, lockService: LockService, termLoanService: TermLoanService);
54
+ getLoanPayment(paymentId: string): Promise<mongoose.FlattenMaps<ILoanPaymentDoc> & {
55
+ _id: mongoose.Types.ObjectId;
56
+ }>;
57
+ getLoanPayments(filter: {
58
+ productIds: string[];
59
+ start: Date;
60
+ end: Date;
61
+ }, paginatorOptions: IPaginatorOptions): Promise<ILoanPaymentDoc[]>;
62
+ getTotalLoanPaymentsForProduct(filter: {
63
+ productIds: string[];
64
+ start: Date;
65
+ end: Date;
66
+ }): Promise<number>;
67
+ saveLoanPayment(payment: Partial<ILoanPaymentWithId>, userId: string): Promise<void>;
68
+ createLoanPayment(payment: Partial<ILoanPaymentWithId>, userId: string): Promise<void>;
69
+ updateLoanPayment(payment: Partial<ILoanPaymentWithId>, userId: string): Promise<void>;
70
+ recalculateAfterPayment(productId: string, userId: string): Promise<void>;
71
+ deleteLoanPayment(paymentId: string, userId: string): Promise<void>;
72
+ private calculatePaymentProportions;
73
+ updateComplianceBorrowerAmountReceived(borrowerId: string): Promise<void>;
74
+ recalculateProduct(productId: string, userId: string): Promise<void>;
75
+ getPaymentsForPeriod(productIds: string[], startDate: Date, endDate: Date): Promise<ILoanPaymentDoc[]>;
76
+ proceedCombinedPayment(combinedPayment: ICombinedPayment, userId: string): Promise<{
77
+ success: boolean;
78
+ message: string;
79
+ }>;
80
+ getExpectedPayments(userId: string): Promise<any[] | {
81
+ borrowers: {
82
+ borrowerId: any;
83
+ borrowerTitle: string;
84
+ totalDue: number;
85
+ productTotals: {
86
+ [productId: string]: number;
87
+ };
88
+ }[];
89
+ isCalculated: boolean;
90
+ }>;
91
+ payExpectedPayments(userId: string, borrowerIds: string[]): Promise<{
92
+ message: string;
93
+ }>;
94
+ }