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,485 @@
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.LoanPaymentsService = exports.paymentOrder = void 0;
7
+ const mongoose_1 = __importDefault(require("mongoose"));
8
+ const dayjs_1 = __importDefault(require("dayjs"));
9
+ const decimal_js_1 = __importDefault(require("decimal.js"));
10
+ const joi_1 = __importDefault(require("joi"));
11
+ const common_helper_1 = require("../helpers/common.helper");
12
+ const loan_charge_type_enum_1 = require("../enums/loan-charge-type.enum");
13
+ const loan_types_enum_1 = require("../enums/loan-types.enum");
14
+ const LoanStatementTransaction_model_1 = require("../models/LoanStatementTransaction.model");
15
+ const collaterals_db_1 = require("../db/collaterals.db");
16
+ const LoanTransaction_model_1 = require("../models/LoanTransaction.model");
17
+ const LoanProducts_model_1 = require("../models/LoanProducts.model");
18
+ const Borrower_model_1 = require("../models/Borrower.model");
19
+ const User_model_1 = require("../models/User.model");
20
+ const LoanPayment_model_1 = require("../models/LoanPayment.model");
21
+ exports.paymentOrder = [
22
+ loan_charge_type_enum_1.ELoanChargeType.RECOVERABLE,
23
+ loan_charge_type_enum_1.ELoanChargeType.INTEREST_FEE,
24
+ loan_charge_type_enum_1.ELoanChargeType.ADMIN_FEE,
25
+ loan_charge_type_enum_1.ELoanChargeType.UNUSED_LINE_FEE,
26
+ loan_charge_type_enum_1.ELoanChargeType.WIRE_FEE,
27
+ loan_charge_type_enum_1.ELoanChargeType.OTHER,
28
+ loan_charge_type_enum_1.ELoanChargeType.ANNUAL_LINE_FEE,
29
+ ];
30
+ const CALCULATION_VAR = 'BULK_PAYMENT';
31
+ class LoanPaymentsService {
32
+ redisClient;
33
+ borrowerService;
34
+ financialComplianceService;
35
+ loanChargesService;
36
+ loanProductsService;
37
+ loanStatementBalanceService;
38
+ getLoanStatementService;
39
+ loanStatementStatusService;
40
+ loanTransactionsService;
41
+ lockService;
42
+ termLoanService;
43
+ constructor(redisClient, borrowerService, financialComplianceService, loanChargesService, loanProductsService, loanStatementBalanceService, getLoanStatementService, loanStatementStatusService, loanTransactionsService, lockService, termLoanService) {
44
+ this.redisClient = redisClient;
45
+ this.borrowerService = borrowerService;
46
+ this.financialComplianceService = financialComplianceService;
47
+ this.loanChargesService = loanChargesService;
48
+ this.loanProductsService = loanProductsService;
49
+ this.loanStatementBalanceService = loanStatementBalanceService;
50
+ this.getLoanStatementService = getLoanStatementService;
51
+ this.loanStatementStatusService = loanStatementStatusService;
52
+ this.loanTransactionsService = loanTransactionsService;
53
+ this.lockService = lockService;
54
+ this.termLoanService = termLoanService;
55
+ }
56
+ async getLoanPayment(paymentId) {
57
+ return LoanPayment_model_1.LoanPaymentModel.findById(paymentId).lean();
58
+ }
59
+ async getLoanPayments(filter, paginatorOptions) {
60
+ return LoanPayment_model_1.LoanPaymentModel.aggregate([
61
+ {
62
+ $match: {
63
+ $and: [
64
+ { 'productId': { $in: filter.productIds.map((id) => new mongoose_1.default.Types.ObjectId(id)) } },
65
+ { 'date': { $gte: filter.start } },
66
+ { 'date': { $lte: (0, dayjs_1.default)(filter.end).utcOffset(0).endOf('day').toDate() } },
67
+ ],
68
+ },
69
+ }, {
70
+ $sort: {
71
+ 'date': 1,
72
+ },
73
+ },
74
+ ...(0, collaterals_db_1.ITEMS_PAGINATION)(paginatorOptions),
75
+ ]);
76
+ }
77
+ async getTotalLoanPaymentsForProduct(filter) {
78
+ return LoanPayment_model_1.LoanPaymentModel.countDocuments({
79
+ $and: [
80
+ { 'productId': { $in: filter.productIds } },
81
+ { 'date': { $gte: filter.start } },
82
+ { 'date': { $lte: filter.end } },
83
+ ],
84
+ });
85
+ }
86
+ async saveLoanPayment(payment, userId) {
87
+ if (!payment._id) {
88
+ delete payment._id;
89
+ const newPayment = new LoanPayment_model_1.LoanPaymentModel(payment);
90
+ await newPayment.save();
91
+ await this.calculatePaymentProportions(newPayment, newPayment.productId.toString(), userId);
92
+ }
93
+ else {
94
+ await LoanPayment_model_1.LoanPaymentModel.findByIdAndUpdate(payment._id, payment);
95
+ await this.calculatePaymentProportions(payment, payment.productId.toString(), userId);
96
+ }
97
+ }
98
+ async createLoanPayment(payment, userId) {
99
+ const purePayment = (0, common_helper_1.createFilteredObject)(payment, LoanPayment_model_1.LOAN_PAYMENT_FIELDS);
100
+ await this.saveLoanPayment(purePayment, userId);
101
+ }
102
+ async updateLoanPayment(payment, userId) {
103
+ const foundPayment = await LoanPayment_model_1.LoanPaymentModel.findById(payment._id).lean();
104
+ if (!foundPayment) {
105
+ return;
106
+ }
107
+ await this.loanStatementBalanceService.cleanDecreasePayment(foundPayment, userId);
108
+ const purePayment = (0, common_helper_1.createFilteredObject)(payment, LoanPayment_model_1.LOAN_PAYMENT_FIELDS);
109
+ await this.saveLoanPayment(purePayment, userId);
110
+ }
111
+ async recalculateAfterPayment(productId, userId) {
112
+ console.log('started recalculating product', productId);
113
+ await this.recalculateProduct(productId, userId);
114
+ await this.loanTransactionsService.recalculateProduct(productId);
115
+ }
116
+ async deleteLoanPayment(paymentId, userId) {
117
+ const foundPayment = await LoanPayment_model_1.LoanPaymentModel.findById(paymentId).lean();
118
+ if (!foundPayment) {
119
+ return;
120
+ }
121
+ await this.loanStatementBalanceService.cleanDecreasePayment(foundPayment, userId);
122
+ await LoanPayment_model_1.LoanPaymentModel.findByIdAndDelete(paymentId);
123
+ const statementDate = this.loanStatementStatusService.getStatementDateForDate(new Date(foundPayment.date));
124
+ await this.loanStatementStatusService.updateStatementStatus(foundPayment.productId.toString(), statementDate, false);
125
+ await this.termLoanService.setTermLoanExpected(foundPayment.productId.toString());
126
+ }
127
+ async calculatePaymentProportions(payment, productId, userId) {
128
+ const product = await LoanProducts_model_1.LoanProduct.findById(productId).lean();
129
+ const settlementCode = payment.settlementCode;
130
+ const borrower = await Borrower_model_1.BorrowerModel.findById(product.borrowerId).lean();
131
+ const loanCharges = await this.loanChargesService.getLoanChargeForProduct(productId);
132
+ const chargesIds = loanCharges.map((charge) => charge._id);
133
+ const productPaymentOrder = !payment.paymentOrder || payment.paymentOrder.length === 0
134
+ ? exports.paymentOrder
135
+ : payment.paymentOrder.map((p) => loanCharges.find((charge) => charge._id.toString() === p).chargeType);
136
+ const paymentOrderQuery = productPaymentOrder.map((charge, index) => {
137
+ return {
138
+ case: {
139
+ $eq: ['$charge.chargeType', charge],
140
+ },
141
+ then: index,
142
+ };
143
+ });
144
+ const unpaidStatements = await LoanStatementTransaction_model_1.LoanStatementTransactionModel.aggregate([
145
+ {
146
+ $match: {
147
+ 'chargeId': { '$in': chargesIds },
148
+ 'date': { $lte: (0, dayjs_1.default)(new Date(payment.date)).utcOffset(0).startOf('month').subtract(1, 'second').toDate() },
149
+ $expr: { $lt: ['$amountPaid', '$amount'] },
150
+ },
151
+ }, {
152
+ $lookup: {
153
+ from: 'loan_charges',
154
+ localField: 'chargeId',
155
+ foreignField: '_id',
156
+ as: 'charge',
157
+ },
158
+ }, {
159
+ $unwind: {
160
+ path: '$charge',
161
+ },
162
+ }, {
163
+ $addFields: {
164
+ customSortValue: {
165
+ $switch: {
166
+ branches: paymentOrderQuery,
167
+ default: exports.paymentOrder.length,
168
+ },
169
+ },
170
+ },
171
+ }, {
172
+ $sort: {
173
+ customSortValue: 1,
174
+ date: 1,
175
+ order: 1,
176
+ },
177
+ },
178
+ ]);
179
+ let availableAmount = payment.amount;
180
+ const paidArray = [];
181
+ let firstPaidStatement = null;
182
+ for (const statement of unpaidStatements) {
183
+ const foundStatement = await LoanStatementTransaction_model_1.LoanStatementTransactionModel.findById(statement._id);
184
+ if (!foundStatement) {
185
+ return;
186
+ }
187
+ const prefPaidAmount = new decimal_js_1.default(statement.amount).sub(foundStatement.amountPaid).toNumber();
188
+ const amountPaid = prefPaidAmount > availableAmount ? availableAmount : prefPaidAmount;
189
+ availableAmount = new decimal_js_1.default(availableAmount).sub(amountPaid).toNumber();
190
+ paidArray.push({ statementId: statement._id, amount: amountPaid });
191
+ await LoanStatementTransaction_model_1.LoanStatementTransactionModel.findByIdAndUpdate(statement._id, {
192
+ amountPaid: new decimal_js_1.default(foundStatement.amountPaid).add(amountPaid).toNumber(),
193
+ settlementCode,
194
+ });
195
+ if (!firstPaidStatement ||
196
+ (statement.date.getTime() < firstPaidStatement.date.getTime()) ||
197
+ (firstPaidStatement.date.getTime() === statement.date.getTime() && firstPaidStatement.order > statement.order)) {
198
+ firstPaidStatement = statement;
199
+ }
200
+ if (availableAmount === 0) {
201
+ break;
202
+ }
203
+ }
204
+ const loanTransactions = [];
205
+ if (availableAmount > 0) {
206
+ const transaction = {
207
+ amount: -availableAmount,
208
+ date: payment.date,
209
+ description: `${borrower.code} - STATEMENT PAID`,
210
+ effectiveDate: null,
211
+ loanPaymentId: payment._id,
212
+ order: 0,
213
+ productId: new mongoose_1.default.Types.ObjectId(productId),
214
+ reference: `${borrower.code} - STATEMENT PAID`,
215
+ transactionType: LoanTransaction_model_1.ELoanTransactionTypes.COLLECTION,
216
+ userId: new mongoose_1.default.Types.ObjectId(userId),
217
+ };
218
+ transaction.effectiveDate = await this.loanTransactionsService.calculateEffectiveDate(transaction);
219
+ const newTransaction = await this.loanTransactionsService.createLoanTransaction(transaction);
220
+ loanTransactions.push({ transactionId: newTransaction._id, amount: newTransaction.amount });
221
+ }
222
+ await LoanPayment_model_1.LoanPaymentModel.findByIdAndUpdate(payment._id, { paid: paidArray, loanTransactions }, { new: true });
223
+ if (firstPaidStatement) {
224
+ await this.loanStatementBalanceService.calculateProductBalance(productId, firstPaidStatement.date);
225
+ }
226
+ await this.updateComplianceBorrowerAmountReceived(borrower._id.toString());
227
+ const statementDate = this.loanStatementStatusService.getStatementDateForDate(new Date(payment.date));
228
+ await this.loanStatementStatusService.updateStatementStatus(productId, statementDate, false);
229
+ await this.termLoanService.setTermLoanExpected(productId, true);
230
+ }
231
+ async updateComplianceBorrowerAmountReceived(borrowerId) {
232
+ const allProducts = await this.loanChargesService.getLoanProducts(borrowerId);
233
+ const productIds = allProducts.map((p) => p._id.toString());
234
+ const startDate = (0, dayjs_1.default)().startOf('month').toDate();
235
+ const endDate = (0, dayjs_1.default)().endOf('month').toDate();
236
+ const payments = await this.getPaymentsForPeriod(productIds, startDate, endDate);
237
+ const totalPayments = payments.reduce((acc, p) => new decimal_js_1.default(acc).add(p.amount ?? 0).toNumber(), 0);
238
+ const complianceBorrower = await this.financialComplianceService.getFinancialComplianceBorrower(borrowerId);
239
+ if (!complianceBorrower) {
240
+ return;
241
+ }
242
+ await this.financialComplianceService.updateBorrower(complianceBorrower._id.toString(), {
243
+ ...complianceBorrower,
244
+ amountReceived: totalPayments,
245
+ });
246
+ }
247
+ async recalculateProduct(productId, userId) {
248
+ const loanCharges = await this.loanChargesService.getLoanChargeForProduct(productId);
249
+ const chargesIds = loanCharges.map((charge) => charge._id);
250
+ await LoanStatementTransaction_model_1.LoanStatementTransactionModel.updateMany({ 'chargeId': { $in: chargesIds } }, { amountPaid: 0 });
251
+ const firstStatements = await LoanStatementTransaction_model_1.LoanStatementTransactionModel.aggregate([
252
+ {
253
+ $match: {
254
+ 'chargeId': { $in: chargesIds },
255
+ },
256
+ }, {
257
+ $sort: {
258
+ 'date': 1,
259
+ 'order': 1,
260
+ },
261
+ }, {
262
+ $limit: 1,
263
+ },
264
+ ]);
265
+ if (firstStatements.length > 0) {
266
+ const loanStatementService = this.getLoanStatementService();
267
+ await loanStatementService.updateStatementTransaction(firstStatements[0]);
268
+ }
269
+ const payments = await LoanPayment_model_1.LoanPaymentModel.aggregate([
270
+ {
271
+ $match: { 'productId': new mongoose_1.default.Types.ObjectId(productId) },
272
+ },
273
+ {
274
+ $sort: {
275
+ 'date': 1,
276
+ 'createdAt': 1,
277
+ },
278
+ },
279
+ ]);
280
+ for (const [index, payment] of payments.entries()) {
281
+ try {
282
+ console.log(`updating payment ${index + 1}/${payments.length}`, (0, dayjs_1.default)(payment.date).format('DD-MM-YYYY'), payment.amount);
283
+ for (const loanTransaction of payment.loanTransactions) {
284
+ await LoanTransaction_model_1.LoanTransaction.findByIdAndDelete(loanTransaction.transactionId);
285
+ }
286
+ await LoanPayment_model_1.LoanPaymentModel.findByIdAndUpdate(payment._id, { paid: [], loanTransactions: [] });
287
+ await this.updateLoanPayment(payment, userId);
288
+ }
289
+ catch (e) {
290
+ console.error({ productId, payments });
291
+ console.error(e);
292
+ }
293
+ }
294
+ }
295
+ async getPaymentsForPeriod(productIds, startDate, endDate) {
296
+ return LoanPayment_model_1.LoanPaymentModel.aggregate([
297
+ {
298
+ $match: {
299
+ $and: [
300
+ { 'productId': { $in: productIds.map((id) => new mongoose_1.default.Types.ObjectId(id)) } },
301
+ { 'date': { $gte: startDate } },
302
+ { 'date': { $lte: endDate } },
303
+ ],
304
+ },
305
+ }, {
306
+ $sort: {
307
+ 'date': 1,
308
+ 'createdAt': 1,
309
+ },
310
+ },
311
+ ]);
312
+ }
313
+ async proceedCombinedPayment(combinedPayment, userId) {
314
+ try {
315
+ if (combinedPayment.addToRevolver) {
316
+ const isLockedRes = await Promise.all([...combinedPayment.products, ...combinedPayment.linkedProducts].map(async (productGroup) => {
317
+ const product = await LoanProducts_model_1.LoanProduct.findById(productGroup.productId).lean();
318
+ if (product) {
319
+ return await this.lockService.isDateLocked(new Date(combinedPayment.date), product.borrowerId.toString());
320
+ }
321
+ return false;
322
+ }));
323
+ if (isLockedRes.some((isLocked) => !!isLocked)) {
324
+ return { success: false, message: 'Period is signed and locked' };
325
+ }
326
+ }
327
+ const loanStatementService = this.getLoanStatementService();
328
+ const data = await loanStatementService.getBorrowerComplianceData(combinedPayment.borrowerId, new Date());
329
+ let totalSumToCover = combinedPayment.payment;
330
+ const products = await this.loanChargesService.getLoanProducts(combinedPayment.borrowerId);
331
+ const revolverProduct = products.find((product) => product.type === loan_types_enum_1.ELoanTypes.REVOLVER);
332
+ for (const p of combinedPayment.products) {
333
+ await this.loanProductsService.savePaymentOrder(p.productId, p.paymentOrder);
334
+ const desiredProductSum = data.productTotals[p.productId];
335
+ const product = await LoanProducts_model_1.LoanProduct.findById(p.productId).lean();
336
+ const sumForProduct = desiredProductSum > totalSumToCover ? totalSumToCover : desiredProductSum;
337
+ if (sumForProduct > 0) {
338
+ const newPayment = {
339
+ _id: null,
340
+ productId: new mongoose_1.default.Types.ObjectId(p.productId),
341
+ amount: sumForProduct,
342
+ date: new Date(combinedPayment.date),
343
+ settlementCode: p.settlementCode,
344
+ paymentOrder: p.paymentOrder,
345
+ };
346
+ await this.createLoanPayment(newPayment, userId);
347
+ if (combinedPayment.addToRevolver && revolverProduct) {
348
+ const newTransactions = {
349
+ amount: sumForProduct,
350
+ bankId: null,
351
+ date: combinedPayment.date,
352
+ description: `${product.type} STATEMENT ADDED TO LOAN`,
353
+ effectiveDate: null,
354
+ productId: revolverProduct._id,
355
+ reference: `${product.type} STATEMENT ADDED TO LOAN`,
356
+ transactionType: LoanTransaction_model_1.ELoanTransactionTypes.DISBURSEMENT,
357
+ userId: new mongoose_1.default.Types.ObjectId(userId),
358
+ };
359
+ newTransactions.effectiveDate = await this.loanTransactionsService.calculateEffectiveDate(newTransactions);
360
+ await this.loanTransactionsService.createLoanTransaction(newTransactions);
361
+ }
362
+ }
363
+ totalSumToCover = new decimal_js_1.default(totalSumToCover).sub(sumForProduct).toNumber();
364
+ }
365
+ if (totalSumToCover > 0 && revolverProduct && !combinedPayment.addToRevolver) {
366
+ const newTransactions = {
367
+ amount: -totalSumToCover,
368
+ bankId: null,
369
+ date: combinedPayment.date,
370
+ description: `OVERPAYMENT OF STATEMENT`,
371
+ effectiveDate: null,
372
+ productId: revolverProduct._id,
373
+ reference: `OVERPAYMENT OF STATEMENT`,
374
+ transactionType: LoanTransaction_model_1.ELoanTransactionTypes.COLLECTION,
375
+ userId: new mongoose_1.default.Types.ObjectId(userId),
376
+ };
377
+ newTransactions.effectiveDate = await this.loanTransactionsService.calculateEffectiveDate(newTransactions);
378
+ await this.loanTransactionsService.createLoanTransaction(newTransactions);
379
+ }
380
+ await Promise.all(combinedPayment.linkedProducts.map(async (p) => {
381
+ const newTransactions = {
382
+ amount: -p.payableSum,
383
+ bankId: null,
384
+ date: combinedPayment.date,
385
+ description: `EXTRA PAYMENT`,
386
+ effectiveDate: null,
387
+ productId: new mongoose_1.default.Types.ObjectId(p.productId),
388
+ reference: `EXTRA PAYMENT REF`,
389
+ transactionType: LoanTransaction_model_1.ELoanTransactionTypes.COLLECTION,
390
+ userId: new mongoose_1.default.Types.ObjectId(userId),
391
+ };
392
+ newTransactions.effectiveDate = await this.loanTransactionsService.calculateEffectiveDate(newTransactions);
393
+ await this.loanTransactionsService.createLoanTransaction(newTransactions);
394
+ }));
395
+ return { success: true, message: null };
396
+ }
397
+ catch (e) {
398
+ console.error(e);
399
+ }
400
+ }
401
+ async getExpectedPayments(userId) {
402
+ const user = await User_model_1.UserModel.findById(userId).lean();
403
+ if (!user) {
404
+ return [];
405
+ }
406
+ const borrowers = await this.borrowerService.getAllowedBorrowers(user);
407
+ const isCalculated = await this.redisClient.get(CALCULATION_VAR);
408
+ const borrowersData = await Promise.all(borrowers
409
+ .filter((borrower) => borrower.active)
410
+ .map(async (borrower) => {
411
+ const loanStatementService = this.getLoanStatementService();
412
+ const dueAmounts = await loanStatementService.getBorrowerProductTotals(borrower._id.toString());
413
+ return {
414
+ borrowerId: borrower.id,
415
+ borrowerTitle: borrower.name,
416
+ totalDue: dueAmounts.total,
417
+ productTotals: dueAmounts.productTotals,
418
+ };
419
+ }));
420
+ return { borrowers: borrowersData, isCalculated: !!isCalculated };
421
+ }
422
+ async payExpectedPayments(userId, borrowerIds) {
423
+ const arrayOfStringsSchema = joi_1.default.array().items(joi_1.default.string()).required();
424
+ const { error } = arrayOfStringsSchema.validate(borrowerIds, { abortEarly: false });
425
+ if (error) {
426
+ return { message: 'Incorrect list of borrowers IDs' };
427
+ }
428
+ const addToRevolver = true;
429
+ await this.redisClient.set(CALCULATION_VAR, 1);
430
+ const user = await User_model_1.UserModel.findById(userId).lean();
431
+ if (!user) {
432
+ return { message: 'Cannot find user with this id' };
433
+ }
434
+ const borrowers = await this.borrowerService.getAllowedBorrowers(user);
435
+ const paymentPromises = borrowers.map(async (borrower) => {
436
+ if (borrowerIds.includes(borrower._id.toString())) {
437
+ try {
438
+ const loanStatementService = this.getLoanStatementService();
439
+ const dueAmounts = await loanStatementService.getBorrowerProductTotals(borrower._id.toString());
440
+ if (dueAmounts.total === 0) {
441
+ console.log('no payment for this borrower');
442
+ return;
443
+ }
444
+ const products = await Promise.all(Object.entries(dueAmounts.productTotals).map(async ([productId, amount]) => {
445
+ const product = await LoanProducts_model_1.LoanProduct.findById(productId);
446
+ if (product) {
447
+ return {
448
+ productId: productId,
449
+ payableSum: amount,
450
+ settlementCode: addToRevolver ? product.code : product.settlementCode,
451
+ paymentOrder: null,
452
+ };
453
+ }
454
+ }));
455
+ const combinedPayment = {
456
+ addToRevolver,
457
+ borrowerId: borrower._id.toString(),
458
+ date: new Date(),
459
+ linkedProducts: [],
460
+ payment: dueAmounts.total,
461
+ products: products.filter((product) => !!product),
462
+ };
463
+ await this.proceedCombinedPayment(combinedPayment, userId);
464
+ console.log(`Success on payment ${borrower.title}`);
465
+ }
466
+ catch (err) {
467
+ console.error(`Error on payment ${borrower.title}:`, err);
468
+ }
469
+ }
470
+ });
471
+ const processPayments = async (paymentPromises) => {
472
+ try {
473
+ await Promise.allSettled(paymentPromises);
474
+ console.log('All payments processed.');
475
+ await this.redisClient.del(CALCULATION_VAR);
476
+ }
477
+ catch (err) {
478
+ console.error('Error during payment processing:', err);
479
+ }
480
+ };
481
+ processPayments(paymentPromises).catch(console.error);
482
+ return { message: 'Payments are being processed in the background.' };
483
+ }
484
+ }
485
+ exports.LoanPaymentsService = LoanPaymentsService;