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,547 @@
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.PdfService = exports.defaultPDFPageSettings = exports.defaultPDFPageSize = exports.defaultPDFPageMarginSize = void 0;
7
+ const decimal_js_1 = __importDefault(require("decimal.js"));
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const pdfmake_1 = __importDefault(require("pdfmake/build/pdfmake"));
11
+ const vfs_fonts_1 = __importDefault(require("pdfmake/build/vfs_fonts"));
12
+ const dayjs_1 = __importDefault(require("dayjs"));
13
+ const LoanProducts_model_1 = require("../models/LoanProducts.model");
14
+ const Borrower_model_1 = require("../models/Borrower.model");
15
+ const loan_charge_type_enum_1 = require("../enums/loan-charge-type.enum");
16
+ const numbers_helper_1 = require("../helpers/numbers.helper");
17
+ const loan_types_enum_1 = require("../enums/loan-types.enum");
18
+ const receivables_db_1 = require("../db/receivables.db");
19
+ const financial_indexes_service_1 = require("./financial-indexes.service");
20
+ const mappedChargeTypes = {
21
+ [loan_charge_type_enum_1.ELoanChargeType.INTEREST_FEE]: 'Interest',
22
+ [loan_charge_type_enum_1.ELoanChargeType.ADMIN_FEE]: 'Loan Administration Fee',
23
+ [loan_charge_type_enum_1.ELoanChargeType.UNUSED_LINE_FEE]: 'Unused Line Fee',
24
+ [loan_charge_type_enum_1.ELoanChargeType.WIRE_FEE]: 'Wire fee',
25
+ [loan_charge_type_enum_1.ELoanChargeType.ANNUAL_LINE_FEE]: 'Annual Line Fee',
26
+ [loan_charge_type_enum_1.ELoanChargeType.OTHER]: 'Other',
27
+ [loan_charge_type_enum_1.ELoanChargeType.RECOVERABLE]: 'Recoverable',
28
+ };
29
+ exports.defaultPDFPageMarginSize = 30;
30
+ exports.defaultPDFPageSize = {
31
+ width: 841.890, // Page width in points for A4 size (8.27 inches)
32
+ height: 595.276, // Page height in points for A4 size (11.69 inches)
33
+ };
34
+ exports.defaultPDFPageSettings = {
35
+ margin: exports.defaultPDFPageMarginSize,
36
+ docWidth: exports.defaultPDFPageSize.width - exports.defaultPDFPageMarginSize * 2,
37
+ docHeight: exports.defaultPDFPageSize.width - exports.defaultPDFPageMarginSize * 2,
38
+ };
39
+ const defaultDateFormat = 'MM/DD/YYYY';
40
+ class PdfService {
41
+ financialIndexesService;
42
+ loanChargesService;
43
+ loanStatementBalanceService;
44
+ loanStatementService;
45
+ loanTransactionsService;
46
+ organizationsService;
47
+ termLoanService;
48
+ config;
49
+ margin = exports.defaultPDFPageMarginSize;
50
+ docWidth;
51
+ docHeight;
52
+ constructor(config, financialIndexesService, loanChargesService, loanStatementBalanceService, loanStatementService, loanTransactionsService, organizationsService, termLoanService) {
53
+ this.financialIndexesService = financialIndexesService;
54
+ this.loanChargesService = loanChargesService;
55
+ this.loanStatementBalanceService = loanStatementBalanceService;
56
+ this.loanStatementService = loanStatementService;
57
+ this.loanTransactionsService = loanTransactionsService;
58
+ this.organizationsService = organizationsService;
59
+ this.termLoanService = termLoanService;
60
+ this.config = config;
61
+ }
62
+ addHeaderNew(organizationSubfolder) {
63
+ const imageData = (imageUrl) => {
64
+ const imagePath = path_1.default.join(this.config.rootDir, imageUrl);
65
+ const imageBuffer = fs_1.default.readFileSync(imagePath);
66
+ const imageBase64 = Buffer.from(imageBuffer).toString('base64');
67
+ return `data:image/png;base64,${imageBase64}`;
68
+ };
69
+ const logoElement = {
70
+ image: imageData(`./public/images/${organizationSubfolder}/logo.png`),
71
+ width: 150,
72
+ };
73
+ const gradientElement = {
74
+ image: imageData(`./public/images/${organizationSubfolder}/gradient.png`),
75
+ width: this.docWidth * 0.8,
76
+ height: 60,
77
+ };
78
+ return {
79
+ alignment: 'justify',
80
+ columns: [
81
+ logoElement,
82
+ gradientElement,
83
+ ],
84
+ };
85
+ }
86
+ async getProductStatementData(productId, start, end) {
87
+ const product = await LoanProducts_model_1.LoanProduct.findById(productId).lean();
88
+ const borrower = await Borrower_model_1.BorrowerModel.findById(product.borrowerId).lean();
89
+ const charges = await this.loanChargesService.getLoanChargeForProduct(productId);
90
+ const periodStart = (0, dayjs_1.default)(start);
91
+ const getInterestFee = (adminFeePercent) => {
92
+ const fullFee = new decimal_js_1.default(primeIndex).mul(100).add(adminFeePercent ?? 0).toDP(4).toNumber();
93
+ if (product.type === loan_types_enum_1.ELoanTypes.TERM) {
94
+ const minPercent = (product.minPercent ?? 0) === 0 ? 0 : new decimal_js_1.default(product.minPercent).mul(100).toNumber() ?? 0;
95
+ const maxPercent = (product.maxPercent ?? 0) === 0 ? 100 : new decimal_js_1.default(product.maxPercent).mul(100).toNumber();
96
+ return Math.min(Math.max(fullFee, minPercent), maxPercent);
97
+ }
98
+ return fullFee;
99
+ };
100
+ const getAdminFeeMin = () => {
101
+ const adminFee = charges.find((charge) => charge.chargeType === loan_charge_type_enum_1.ELoanChargeType.ADMIN_FEE);
102
+ if (!adminFee) {
103
+ return '';
104
+ }
105
+ if (!!adminFee.minimumAmount && adminFee.minimumAmount > 0) {
106
+ return `(min = ${adminFee.minimumAmount}$)`;
107
+ }
108
+ return '';
109
+ };
110
+ const { groupedData, otherStatements, transactions, } = await this.loanStatementService.getProductStatementPdfData(productId, start, end);
111
+ const chargeInfo = (chargeType) => {
112
+ const foundCharge = charges.find((charge) => charge.chargeType === chargeType);
113
+ if (!foundCharge) {
114
+ return { percent: null, minimumAmount: null };
115
+ }
116
+ return { percent: foundCharge.percent * 100, minimumAmount: foundCharge.minimumAmount };
117
+ };
118
+ const primeIndex = await this.financialIndexesService.getFinancialIndexValue(financial_indexes_service_1.EFinancialIndex.PRIME_RATE) ?? 0;
119
+ const chargeMap = {
120
+ [loan_charge_type_enum_1.ELoanChargeType.INTEREST_FEE]: {
121
+ title: mappedChargeTypes[loan_charge_type_enum_1.ELoanChargeType.INTEREST_FEE],
122
+ explanation: `${getInterestFee(chargeInfo(loan_charge_type_enum_1.ELoanChargeType.INTEREST_FEE).percent)}% - daily charge`,
123
+ },
124
+ [loan_charge_type_enum_1.ELoanChargeType.ADMIN_FEE]: {
125
+ title: mappedChargeTypes[loan_charge_type_enum_1.ELoanChargeType.ADMIN_FEE],
126
+ explanation: `${chargeInfo(loan_charge_type_enum_1.ELoanChargeType.ADMIN_FEE).percent}% - per month, average monthly balance ${getAdminFeeMin()}`,
127
+ },
128
+ [loan_charge_type_enum_1.ELoanChargeType.UNUSED_LINE_FEE]: {
129
+ title: mappedChargeTypes[loan_charge_type_enum_1.ELoanChargeType.UNUSED_LINE_FEE],
130
+ explanation: `${chargeInfo(loan_charge_type_enum_1.ELoanChargeType.UNUSED_LINE_FEE).percent}% - daily charge on unused amount`,
131
+ },
132
+ [loan_charge_type_enum_1.ELoanChargeType.WIRE_FEE]: {
133
+ title: mappedChargeTypes[loan_charge_type_enum_1.ELoanChargeType.WIRE_FEE],
134
+ explanation: `${chargeInfo(loan_charge_type_enum_1.ELoanChargeType.WIRE_FEE).minimumAmount}$ per disbursement`,
135
+ },
136
+ [loan_charge_type_enum_1.ELoanChargeType.ANNUAL_LINE_FEE]: {
137
+ title: mappedChargeTypes[loan_charge_type_enum_1.ELoanChargeType.ANNUAL_LINE_FEE],
138
+ explanation: `${chargeInfo(loan_charge_type_enum_1.ELoanChargeType.ANNUAL_LINE_FEE).percent}% of commitment`,
139
+ },
140
+ [loan_charge_type_enum_1.ELoanChargeType.OTHER]: {
141
+ title: mappedChargeTypes[loan_charge_type_enum_1.ELoanChargeType.OTHER],
142
+ explanation: '',
143
+ },
144
+ [loan_charge_type_enum_1.ELoanChargeType.RECOVERABLE]: {
145
+ title: mappedChargeTypes[loan_charge_type_enum_1.ELoanChargeType.RECOVERABLE],
146
+ explanation: '',
147
+ },
148
+ };
149
+ const preparedStatement = Object.entries(groupedData).map(([chargeType, amount]) => {
150
+ if (amount === 0) {
151
+ return null;
152
+ }
153
+ return [
154
+ chargeMap[chargeType].title,
155
+ { text: (0, numbers_helper_1.formatNumbers)(amount), alignment: 'right' },
156
+ { text: chargeMap[chargeType].explanation, noWrap: true },
157
+ ];
158
+ });
159
+ const groupedOtherStatements = otherStatements.reduce((acc, otherStatement) => {
160
+ const groupName = `${otherStatement.chargeName}${receivables_db_1.CUSTOMER_NUMBER_SEPARATOR}${otherStatement.memo}`;
161
+ const foundValue = acc[groupName];
162
+ if (foundValue) {
163
+ acc[groupName].amount = new decimal_js_1.default(foundValue.amount).add(otherStatement.amount).toNumber();
164
+ return acc;
165
+ }
166
+ return {
167
+ ...acc,
168
+ [groupName]: {
169
+ amount: otherStatement.amount,
170
+ chargeName: otherStatement.chargeName,
171
+ memo: otherStatement.memo,
172
+ },
173
+ };
174
+ }, {});
175
+ Object
176
+ .values(groupedOtherStatements)
177
+ .sort((values1, values2) => values1.memo.localeCompare(values2.memo))
178
+ .sort((values1, values2) => values1.chargeName.localeCompare(values2.chargeName))
179
+ .forEach((values) => {
180
+ preparedStatement.push([
181
+ { text: values.chargeName, noWrap: false },
182
+ { text: (0, numbers_helper_1.formatNumbers)(values.amount), alignment: 'right' },
183
+ { text: values.memo, noWrap: false },
184
+ ]);
185
+ });
186
+ const previousStatementTransaction = await this.loanStatementBalanceService.getLastStatementTransactionForDate(productId, new Date(periodStart.format('YYYY-MM-DD')));
187
+ const startStatementBalance = previousStatementTransaction ? previousStatementTransaction.balance : 0;
188
+ let monthlyTermPrincipal = null;
189
+ if (product.type === loan_types_enum_1.ELoanTypes.TERM) {
190
+ const { monthlyPrincipal } = await this.getTermLoan(product._id.toString(), new Date(start));
191
+ monthlyTermPrincipal = monthlyPrincipal;
192
+ }
193
+ const totalOther = Object.values(groupedOtherStatements).reduce((acc, st) => new decimal_js_1.default(acc).add(st.amount).toNumber(), 0);
194
+ const other = { other: totalOther };
195
+ const totalAmountDue = Object.values({ ...groupedData, ...other }).reduce((acc, value) => new decimal_js_1.default(acc).add(value || 0).toNumber(), 0);
196
+ const fullStatementTable = [
197
+ [{ text: '' }, { text: 'AMOUNT', bold: true, alignment: 'right' }, { text: 'BASIS FOR CHARGE', bold: true }],
198
+ ...preparedStatement.filter((statement) => !!statement),
199
+ monthlyTermPrincipal ? [{ text: 'Principal' }, {
200
+ text: (0, numbers_helper_1.formatNumbers)(monthlyTermPrincipal),
201
+ alignment: 'right',
202
+ }, { text: '' }] : [],
203
+ [
204
+ { text: 'Past due amount from previous statement', bold: true, border: [false], noWrap: true },
205
+ {
206
+ text: (0, numbers_helper_1.formatNumbers)(startStatementBalance),
207
+ bold: true,
208
+ border: [false],
209
+ alignment: 'right',
210
+ },
211
+ { text: '', border: [false] },
212
+ ],
213
+ [{
214
+ text: 'TOTAL AMOUNT DUE',
215
+ bold: true,
216
+ color: 'red',
217
+ border: [false],
218
+ noWrap: true,
219
+ }, {
220
+ text: (0, numbers_helper_1.formatNumbers)(new decimal_js_1.default(totalAmountDue).add(startStatementBalance).add(monthlyTermPrincipal ? monthlyTermPrincipal : 0).toNumber()),
221
+ bold: true,
222
+ color: 'red',
223
+ border: [false],
224
+ alignment: 'right',
225
+ }, { text: '', border: [false] }],
226
+ ].filter((row) => row.length > 0);
227
+ const productInfoTable = [
228
+ [{ text: '' }, { text: '' }],
229
+ [{ text: 'Product start date' }, {
230
+ text: (0, dayjs_1.default)(product.startDate).format(defaultDateFormat),
231
+ alignment: 'right',
232
+ }],
233
+ [{ text: 'Product maturity date' }, {
234
+ text: (0, dayjs_1.default)(product.maturityDate).format(defaultDateFormat),
235
+ alignment: 'right',
236
+ }],
237
+ [{ text: 'Commitment amount' }, { text: (0, numbers_helper_1.formatNumbers)(product.commitment), alignment: 'right' }],
238
+ ];
239
+ const preparedStatementHeader = [
240
+ { text: `STATEMENT FOR PRODUCT: ${product.name}`, bold: true },
241
+ { text: `Client: ${borrower.code}`, bold: true },
242
+ {
243
+ text: `PERIOD FROM ${(0, dayjs_1.default)(start.slice(0, 10)).format(defaultDateFormat)} PERIOD TO ${(0, dayjs_1.default)(end.slice(0, 10)).format(defaultDateFormat)}`,
244
+ bold: true,
245
+ },
246
+ {
247
+ table: { widths: [120, 140], body: productInfoTable },
248
+ layout: 'lightHorizontalLines',
249
+ },
250
+ ];
251
+ const previousTransaction = transactions.length > 0
252
+ ? await this.loanTransactionsService.getLastTransactionForDate(transactions[0].productId.toString(), (0, dayjs_1.default)(transactions[0].date).subtract(1, 'second').toDate())
253
+ : await this.loanTransactionsService.getLastTransactionForDate(productId, (0, dayjs_1.default)(periodStart).subtract(1, 'second').toDate());
254
+ const lastTransaction = transactions.length > 0
255
+ ? transactions[transactions.length - 1]
256
+ : previousTransaction;
257
+ const preparedTransactionsHeader = [
258
+ { text: `LOAN TRANSACTIONS: ${product.name}` },
259
+ ];
260
+ const preparedTransactions = transactions.map((transaction) => {
261
+ return [
262
+ { text: (0, dayjs_1.default)(transaction.date).format(defaultDateFormat) },
263
+ { text: transaction.transactionType },
264
+ { text: (0, numbers_helper_1.formatNumbers)(transaction.amount), alignment: 'right' },
265
+ { text: transaction.reference },
266
+ { text: (0, numbers_helper_1.formatNumbers)(transaction.balance), alignment: 'right' },
267
+ ];
268
+ });
269
+ const fullTransactionsTable = [
270
+ [
271
+ { text: 'Date' },
272
+ { text: 'Type' },
273
+ { text: 'Amount', alignment: 'right' },
274
+ { text: 'Reference' },
275
+ { text: 'Balance', alignment: 'right' },
276
+ ],
277
+ [
278
+ { text: '' },
279
+ { text: '' },
280
+ { text: '' },
281
+ { text: 'OPENING BALANCE' },
282
+ { text: `${previousTransaction ? (0, numbers_helper_1.formatNumbers)(previousTransaction.balance) : 0}`, alignment: 'right' },
283
+ ],
284
+ ...preparedTransactions,
285
+ [
286
+ { text: '' },
287
+ { text: '' },
288
+ { text: '' },
289
+ { text: 'CLOSING BALANCE' },
290
+ { text: `${lastTransaction ? (0, numbers_helper_1.formatNumbers)(lastTransaction.balance) : 0}`, alignment: 'right' },
291
+ ],
292
+ ];
293
+ return {
294
+ startStatementBalance,
295
+ preparedStatementHeader,
296
+ preparedStatement: {
297
+ table: {
298
+ widths: ['auto', 100, '*'],
299
+ body: fullStatementTable,
300
+ },
301
+ layout: 'lightHorizontalLines',
302
+ },
303
+ preparedTransactionsHeader,
304
+ preparedTransactions: {
305
+ table: {
306
+ widths: [80, 100, 80, '*', 80],
307
+ body: fullTransactionsTable,
308
+ },
309
+ layout: 'lightHorizontalLines',
310
+ },
311
+ groupedData,
312
+ otherStatements,
313
+ };
314
+ }
315
+ async getTermLoan(productId, start) {
316
+ const termLoan = await this.termLoanService.getTermLoan(productId, true);
317
+ let isMatch = false;
318
+ const tableHeader = [
319
+ { text: 'Relevant statement', bold: true },
320
+ { text: 'Due date', bold: true },
321
+ { text: 'Interest rate', bold: true, alignment: 'right' },
322
+ { text: 'Closing Balance', bold: true, alignment: 'right' },
323
+ { text: 'Principal', bold: true, alignment: 'right' },
324
+ { text: 'Interest', bold: true, alignment: 'right' },
325
+ { text: 'EMI', bold: true, alignment: 'right' },
326
+ { text: 'Admin Fee', bold: true, alignment: 'right' },
327
+ { text: 'Total Payment', bold: true, alignment: 'right' },
328
+ ];
329
+ let tableData = [];
330
+ let monthlyPrincipal = null;
331
+ let dueDate = null;
332
+ const cellParams = { border: [false], noWrap: true, fontSize: 12 };
333
+ const numberCellParams = { ...cellParams, alignment: 'right' };
334
+ if (termLoan) {
335
+ tableData = termLoan.calculated.reduce((acc, calculatedRow) => {
336
+ isMatch = isMatch || (0, dayjs_1.default)(calculatedRow.relevantStatement).endOf('month').isAfter((0, dayjs_1.default)(start));
337
+ if (!isMatch) {
338
+ return acc;
339
+ }
340
+ const EMI = new decimal_js_1.default(calculatedRow.monthlyPrincipal).add(calculatedRow.monthlyInterest).toNumber();
341
+ const totalPayment = new decimal_js_1.default(EMI).add(calculatedRow.adminFee).toNumber();
342
+ if (monthlyPrincipal === null) {
343
+ monthlyPrincipal = calculatedRow.monthlyPrincipal;
344
+ dueDate = calculatedRow.paymentDueDate;
345
+ }
346
+ return [
347
+ ...acc,
348
+ [
349
+ { text: (0, dayjs_1.default)(calculatedRow.relevantStatement).format(defaultDateFormat), ...cellParams },
350
+ { text: (0, dayjs_1.default)(calculatedRow.paymentDueDate).format(defaultDateFormat), ...cellParams },
351
+ { text: (0, numbers_helper_1.formatNumbers)(new decimal_js_1.default(calculatedRow.interestRate).mul(100).toDP(2).toNumber() + '%'), ...numberCellParams },
352
+ { text: (0, numbers_helper_1.formatNumbers)(calculatedRow.closingBalance), ...numberCellParams },
353
+ { text: (0, numbers_helper_1.formatNumbers)(calculatedRow.monthlyPrincipal), ...numberCellParams },
354
+ { text: (0, numbers_helper_1.formatNumbers)(calculatedRow.monthlyInterest), ...numberCellParams },
355
+ { text: (0, numbers_helper_1.formatNumbers)(EMI), ...numberCellParams },
356
+ { text: (0, numbers_helper_1.formatNumbers)(calculatedRow.adminFee), ...numberCellParams },
357
+ { text: (0, numbers_helper_1.formatNumbers)(totalPayment), ...numberCellParams },
358
+ ],
359
+ ];
360
+ }, []);
361
+ }
362
+ return {
363
+ monthlyPrincipal,
364
+ dueDate,
365
+ termLoanTableData: [tableHeader, ...tableData],
366
+ };
367
+ }
368
+ async createStatementDoc(params, getOnlyTotal = false) {
369
+ const { borrowerId, start, end } = params;
370
+ const products = await this.loanChargesService.getLoanProducts(borrowerId);
371
+ const borrower = await Borrower_model_1.BorrowerModel.findById(borrowerId).lean();
372
+ const organization = await this.organizationsService.getOrganizationForBorrower(borrowerId);
373
+ pdfmake_1.default.vfs = vfs_fonts_1.default.pdfMake.vfs;
374
+ const pageSize = {
375
+ width: 841.890, // Page width in points for A4 size (8.27 inches)
376
+ height: 595.276, // Page height in points for A4 size (11.69 inches)
377
+ };
378
+ this.docWidth = exports.defaultPDFPageSize.width - this.margin * 2;
379
+ this.docHeight = exports.defaultPDFPageSize.height - this.margin * 2;
380
+ const emptyString = { text: ' ', margin: 5 };
381
+ const pageBreaker = { text: '', pageBreak: 'after' };
382
+ const totalGroupedData = {
383
+ [loan_charge_type_enum_1.ELoanChargeType.INTEREST_FEE]: 0,
384
+ [loan_charge_type_enum_1.ELoanChargeType.ADMIN_FEE]: 0,
385
+ [loan_charge_type_enum_1.ELoanChargeType.UNUSED_LINE_FEE]: 0,
386
+ [loan_charge_type_enum_1.ELoanChargeType.WIRE_FEE]: 0,
387
+ [loan_charge_type_enum_1.ELoanChargeType.ANNUAL_LINE_FEE]: 0,
388
+ [loan_charge_type_enum_1.ELoanChargeType.OTHER]: 0,
389
+ [loan_charge_type_enum_1.ELoanChargeType.RECOVERABLE]: 0,
390
+ };
391
+ let totalOverDueStatementBalance = 0;
392
+ const productTotals = products.reduce((acc, p) => ({
393
+ ...acc,
394
+ [p._id.toString()]: 0,
395
+ }), {});
396
+ const docContent = await Promise.all(products.map(async (product, index) => {
397
+ const { startStatementBalance, preparedStatementHeader, preparedStatement, preparedTransactionsHeader, preparedTransactions, groupedData, otherStatements, } = await this.getProductStatementData(product._id.toString(), start, end);
398
+ totalOverDueStatementBalance = new decimal_js_1.default(totalOverDueStatementBalance).add(startStatementBalance).toNumber();
399
+ let totalPerProduct = 0;
400
+ Object.entries(groupedData).forEach(([chargeType, amount]) => {
401
+ totalGroupedData[chargeType] = new decimal_js_1.default(totalGroupedData[chargeType]).add(amount).toNumber();
402
+ totalPerProduct = new decimal_js_1.default(totalPerProduct).add(amount).toNumber();
403
+ });
404
+ otherStatements.forEach((otherStatement) => {
405
+ totalGroupedData[otherStatement.chargeType] = new decimal_js_1.default(totalGroupedData[otherStatement.chargeType]).add(otherStatement.amount).toNumber();
406
+ totalPerProduct = new decimal_js_1.default(totalPerProduct).add(otherStatement.amount).toNumber();
407
+ });
408
+ productTotals[product._id.toString()] = new decimal_js_1.default(startStatementBalance).add(totalPerProduct).toNumber();
409
+ const warningText = product.type === loan_types_enum_1.ELoanTypes.REVOLVER
410
+ ? `AMOUNT WILL BE ADDED TO THE LOAN ON 1ST. ${organization.name.toUpperCase()} RESERVES THE RIGHT TO STOP FUNDING IF THERE IS INSUFFICIENT AVAILABILITY TO ADD IT TO THE LOAN.`
411
+ : `PAYABLE BY 7TH. ${organization.name.toUpperCase()} RESERVES THE RIGHT TO STOP FUNDING IF THE STATEMENT IS NOT PAID.`;
412
+ return [
413
+ this.addHeaderNew(organization.subfolder), // Add the image element to the content
414
+ emptyString,
415
+ ...preparedStatementHeader,
416
+ emptyString,
417
+ preparedStatement,
418
+ emptyString,
419
+ {
420
+ text: warningText,
421
+ color: 'red',
422
+ },
423
+ {
424
+ text: `PAYABLE BY DIRECT TRANSFER, OR BORROWING BASE SUBMISSION CONFIRMING AVAILABILITY. ${organization.name.toUpperCase()} RESERVES THE RIGHT TO ACH FROM YOUR ACCOUNT`,
425
+ bold: true,
426
+ },
427
+ emptyString,
428
+ ...preparedTransactionsHeader,
429
+ preparedTransactions,
430
+ products.length === index + 1 ? emptyString : pageBreaker,
431
+ ];
432
+ }));
433
+ let totalStatementValue = 0;
434
+ const preparedTotal = Object.entries(totalGroupedData).map(([chargeType, amount]) => {
435
+ totalStatementValue = new decimal_js_1.default(totalStatementValue).add(amount).toNumber();
436
+ return [
437
+ { text: mappedChargeTypes[loan_charge_type_enum_1.ELoanChargeType[chargeType]] },
438
+ { text: (0, numbers_helper_1.formatNumbers)(amount), alignment: 'right' },
439
+ { text: '' },
440
+ ];
441
+ });
442
+ const totalOverDueStatement = totalOverDueStatementBalance > 0
443
+ ? [
444
+ { text: 'Past due amount from previous statement' },
445
+ { text: (0, numbers_helper_1.formatNumbers)(totalOverDueStatementBalance), alignment: 'right' },
446
+ { text: '' }
447
+ ]
448
+ : [];
449
+ const principalData = [];
450
+ let paymentDueDate = null;
451
+ const termLoanProducts = products.filter((product) => product.type === loan_types_enum_1.ELoanTypes.TERM);
452
+ await Promise.all(termLoanProducts.map(async (product) => {
453
+ const { termLoanTableData, monthlyPrincipal, dueDate, } = await this.getTermLoan(product._id.toString(), new Date(start));
454
+ if (monthlyPrincipal !== null) {
455
+ totalStatementValue = new decimal_js_1.default(totalStatementValue).add(monthlyPrincipal).toNumber();
456
+ principalData.push([
457
+ { text: 'Principal' },
458
+ { text: (0, numbers_helper_1.formatNumbers)(monthlyPrincipal), alignment: 'right' },
459
+ { text: '' },
460
+ ]);
461
+ paymentDueDate = dueDate;
462
+ productTotals[product._id.toString()] = new decimal_js_1.default(productTotals[product._id.toString()]).add(monthlyPrincipal).toNumber();
463
+ }
464
+ docContent.push([
465
+ pageBreaker,
466
+ this.addHeaderNew(organization.subfolder),
467
+ emptyString,
468
+ { text: `Term loan schedule: `, fontSize: 15, bold: true },
469
+ emptyString,
470
+ {
471
+ table: { widths: ['*', '*', '*', '*', '*', '*', '*', '*', '*'], body: termLoanTableData },
472
+ layout: 'lightHorizontalLines',
473
+ },
474
+ ]);
475
+ }));
476
+ const totalOwed = new decimal_js_1.default(totalStatementValue).add(totalOverDueStatementBalance).toNumber();
477
+ if (getOnlyTotal) {
478
+ return { total: totalOwed, dueDate: paymentDueDate, productTotals };
479
+ }
480
+ const bankAccounts = {
481
+ 'Black Feather': [
482
+ [{ text: 'Bank name' }, { text: 'Chase' }],
483
+ [{ text: 'ABA' }, { text: '322271627' }],
484
+ [{ text: 'Account' }, { text: '80009785264' }],
485
+ ],
486
+ 'GemCap': [
487
+ [{ text: 'Bank name' }, { text: 'CIBC Bank USA' }],
488
+ [{ text: 'ABA' }, { text: '0710-0648-6' }],
489
+ [{ text: 'SWIFT' }, { text: 'PVTBUS44' }],
490
+ [{ text: 'Account' }, { text: '2583852' }],
491
+ ],
492
+ };
493
+ const paymentInstruction = [
494
+ [{ text: 'Please remit payment to', fillColor: '#44464b', color: 'white' }, { text: '', fillColor: '#44464b' }],
495
+ ...bankAccounts[organization.name],
496
+ [{ text: 'Account name' }, { text: `${this.config.title} Solutions Master Concentration` }],
497
+ [{ text: 'Reference' }, { text: `${borrower.code} - STATEMENT PAYMENT` }],
498
+ [{ text: 'The reference is required to ensure timely settlement of your account.', color: 'red' }, {}],
499
+ ];
500
+ const totalStatementTable = [
501
+ [{ text: '' }, { text: 'AMOUNT', bold: true, alignment: 'right' }, { text: '' }],
502
+ ...preparedTotal,
503
+ ...principalData,
504
+ totalOverDueStatement,
505
+ [
506
+ { text: 'TOTAL', color: 'red' },
507
+ {
508
+ text: (0, numbers_helper_1.formatNumbers)(totalOwed),
509
+ bold: true,
510
+ color: 'red',
511
+ alignment: 'right',
512
+ },
513
+ { text: paymentDueDate ? `due on ${(0, dayjs_1.default)(paymentDueDate).format(defaultDateFormat)}` : '', color: 'red' },
514
+ ],
515
+ ];
516
+ docContent.unshift([
517
+ this.addHeaderNew(organization.subfolder),
518
+ emptyString,
519
+ { text: 'Total Statement Amount', fontSize: 18, bold: true },
520
+ { text: `Client: ${borrower.name}`, fontSize: 15, bold: true },
521
+ {
522
+ table: { widths: [300, 100, '*'], body: totalStatementTable.filter((row) => row.length !== 0) },
523
+ layout: 'lightHorizontalLines',
524
+ },
525
+ emptyString,
526
+ {
527
+ table: { widths: ['*', '*'], body: paymentInstruction, styles: 'section' },
528
+ layout: 'lightHorizontalLines',
529
+ },
530
+ pageBreaker,
531
+ ]);
532
+ const docDefinition = {
533
+ content: docContent,
534
+ footer: (currentPage, pageCount) => {
535
+ return {
536
+ text: 'Page ' + currentPage.toString() + ' of ' + pageCount,
537
+ alignment: 'center',
538
+ };
539
+ },
540
+ pageOrientation: 'landscape',
541
+ pageSize,
542
+ pageMargins: this.margin,
543
+ };
544
+ return pdfmake_1.default.createPdf(docDefinition);
545
+ }
546
+ }
547
+ exports.PdfService = PdfService;