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,569 @@
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.ComplianceBorrowersService = void 0;
7
+ const dayjs_1 = __importDefault(require("dayjs"));
8
+ const lodash_1 = __importDefault(require("lodash"));
9
+ const mongoose_1 = __importDefault(require("mongoose"));
10
+ const item_progress_status_enum_1 = require("../enums/item-progress-status.enum");
11
+ const BorrowerCompliance_model_1 = require("../models/BorrowerCompliance.model");
12
+ const Borrower_model_1 = require("../models/Borrower.model");
13
+ const FinancialComplianceBorrower_model_1 = __importDefault(require("../models/FinancialComplianceBorrower.model"));
14
+ const frequencies = {
15
+ ONCE: { value: 1, unit: 'day' },
16
+ MONTHLY: { value: 1, unit: 'month' },
17
+ ANNUAL: { value: 1, unit: 'year' },
18
+ WEEKLY: { value: 1, unit: 'week' },
19
+ QUARTERLY: { value: 3, unit: 'month' },
20
+ TWICE_MONTHLY: { value: 15, unit: 'day' },
21
+ END_OF_MONTH: { value: 15, unit: 'day' },
22
+ };
23
+ const dueDifference = (date) => {
24
+ const currentDate = (0, dayjs_1.default)().startOf('day');
25
+ const nextDate = (0, dayjs_1.default)(new Date(date)).startOf('day');
26
+ return currentDate.diff(nextDate, 'day');
27
+ };
28
+ class ComplianceBorrowersService {
29
+ _fileManagerService;
30
+ _uploadsService;
31
+ constructor(_fileManagerService, _uploadsService) {
32
+ this._fileManagerService = _fileManagerService;
33
+ this._uploadsService = _uploadsService;
34
+ }
35
+ isComplianceBorrowerAllowed(userAccess, requestedBorrowerId) {
36
+ const allowedBorrower = userAccess.complianceBorrowersAccess.some((b) => b.borrower === requestedBorrowerId);
37
+ if (!allowedBorrower) {
38
+ throw new Error('Non allowed compliance borrower');
39
+ }
40
+ return true;
41
+ }
42
+ calculateInstanceStatuses(instance, item) {
43
+ let progress;
44
+ let score = null;
45
+ if (instance.submittedDate) {
46
+ progress = { text: 'submitted', status: 'SUBMITTED' };
47
+ }
48
+ const diff = dueDifference(instance.nextDate);
49
+ if (diff !== 0) {
50
+ const progressText = `${diff > 0 ? 'overdue' : 'due'} ${Math.abs(diff)} ${Math.abs(diff) > 1 ? 'days' : 'day'}`;
51
+ progress = { text: progressText, status: diff > 0 ? item_progress_status_enum_1.EItemProgressStatus.OVERDUE : item_progress_status_enum_1.EItemProgressStatus.DUE };
52
+ }
53
+ if (diff > 0) {
54
+ score = {
55
+ value: item.item.importanceScore * item.item.multiplier * diff,
56
+ tooltip: `${item.item.importanceScore} (importance) x ${item.item.multiplier} (multiplier) x ${diff} (days)`,
57
+ };
58
+ }
59
+ if (instance.status === 'IN_REVIEW') {
60
+ progress = { text: 'in review', status: item_progress_status_enum_1.EItemProgressStatus.IN_REVIEW };
61
+ }
62
+ if (instance.status === 'ACCEPTED') {
63
+ progress = null;
64
+ }
65
+ return { progress, score };
66
+ }
67
+ async getFullComplianceBorrowerById(complianceBorrowerId) {
68
+ if (!complianceBorrowerId) {
69
+ return null;
70
+ }
71
+ const ourBorrower = await BorrowerCompliance_model_1.BorrowerCompliance
72
+ .findById(complianceBorrowerId)
73
+ .populate('borrower plaidAccessToken')
74
+ .populate({
75
+ path: 'items',
76
+ populate: { path: 'item', model: 'complianceItems' },
77
+ })
78
+ .populate({
79
+ path: 'items',
80
+ populate: { path: 'instances.files.uploadedBy', model: 'users' },
81
+ })
82
+ .transform((borrower) => ({ ...borrower, plaidAccessToken: borrower?.plaidAccessToken ?? false }))
83
+ .lean();
84
+ if (!ourBorrower.borrower) {
85
+ return Promise.resolve({ ...ourBorrower });
86
+ }
87
+ const financeBorrower = await FinancialComplianceBorrower_model_1.default.findOne({ borrower: ourBorrower.borrower?._id });
88
+ if (financeBorrower) {
89
+ const currentDate = (0, dayjs_1.default)();
90
+ const stopFundingDate = (0, dayjs_1.default)(financeBorrower.stopFundingDate);
91
+ if (financeBorrower.balanceOutstanding > 0 && currentDate.diff(stopFundingDate) > 0) {
92
+ ourBorrower.fundingStatus = 'NOT_PAID';
93
+ }
94
+ }
95
+ if (!ourBorrower) {
96
+ return Promise.resolve(null);
97
+ }
98
+ const items = { items: [], ...ourBorrower }.items.map((item) => {
99
+ return {
100
+ ...item,
101
+ instances: item.instances.reduce((acc, instance) => {
102
+ try {
103
+ const statuses = this.calculateInstanceStatuses(instance, item);
104
+ const files = instance.files.map((file) => {
105
+ const uploadedByUser = file.uploadedBy ? file.uploadedBy['firstName'] : null;
106
+ return { ...file, uploadedByUser };
107
+ });
108
+ return [...acc, { ...instance, ...statuses, itemId: item._id, files }];
109
+ }
110
+ catch (e) {
111
+ console.error({ e });
112
+ return acc;
113
+ }
114
+ }, []),
115
+ };
116
+ });
117
+ return Promise.resolve({ ...ourBorrower, items });
118
+ }
119
+ async getAllBorrowersShortened(userAccess) {
120
+ const allComplianceBorrower = await BorrowerCompliance_model_1.BorrowerCompliance
121
+ .find(userAccess.allBorrowers ? { isVisible: true } : {
122
+ 'borrower': { $in: userAccess.borrowersAccess.map((b) => b.borrower) },
123
+ isVisible: true,
124
+ })
125
+ .populate('borrower')
126
+ .populate({
127
+ path: 'items',
128
+ populate: { path: 'item', model: 'complianceItems' },
129
+ })
130
+ .collation({ locale: 'en' })
131
+ .lean();
132
+ const borrowers = await Promise.all(allComplianceBorrower.map(async (borrower) => {
133
+ if (!borrower.borrower) {
134
+ return borrower;
135
+ }
136
+ if (!borrower.borrower.active) {
137
+ return;
138
+ }
139
+ const financeBorrower = await FinancialComplianceBorrower_model_1.default.findOne({ borrower: borrower.borrower._id });
140
+ if (financeBorrower) {
141
+ const currentDate = (0, dayjs_1.default)();
142
+ const stopFundingDate = (0, dayjs_1.default)(financeBorrower.stopFundingDate);
143
+ if (financeBorrower.balanceOutstanding > 0 && currentDate.diff(stopFundingDate) > 0) {
144
+ borrower.fundingStatus = 'NOT_PAID';
145
+ }
146
+ }
147
+ const items = borrower.items.map((item) => {
148
+ return {
149
+ ...item,
150
+ instances: item.instances.reduce((acc, instance) => {
151
+ try {
152
+ const statuses = this.calculateInstanceStatuses(instance, item);
153
+ return [...acc, { ...instance, ...statuses }];
154
+ }
155
+ catch (e) {
156
+ return acc;
157
+ }
158
+ }, []),
159
+ };
160
+ });
161
+ return { ...borrower, items };
162
+ }));
163
+ return borrowers
164
+ .filter((borrower) => !!borrower)
165
+ .sort((a, b) => a.borrower.code > b.borrower.code ? 1 : -1);
166
+ }
167
+ async generateInstances(complianceBorrowerId) {
168
+ const complianceBorrower = await this.getFullComplianceBorrowerById(complianceBorrowerId);
169
+ const getLatestInstanceDate = (item) => {
170
+ if (!item.instances || !item.instances.length) {
171
+ return null;
172
+ }
173
+ return item.instances
174
+ .reduce((a, b) => (new Date(a.nextDate).getTime() > new Date(b.nextDate).getTime() ? a : b))
175
+ .nextDate;
176
+ };
177
+ for (let [index, item] of complianceBorrower.items.entries()) {
178
+ const { frequency, startDate } = item;
179
+ if (frequency && startDate) {
180
+ const currentDatePlusNotification = (0, dayjs_1.default)(new Date())
181
+ .set('hour', 0)
182
+ .set('minute', 0)
183
+ .set('second', 0)
184
+ .add(item.item.notificationDays, 'day')
185
+ .toDate();
186
+ const emptyInstance = {
187
+ submittedDate: null,
188
+ status: 'NEW',
189
+ files: [],
190
+ };
191
+ let newInstance;
192
+ let newInstances;
193
+ let nextDate;
194
+ switch (frequency) {
195
+ case 'ONCE':
196
+ newInstance = { nextDate: (0, dayjs_1.default)(item.startDate).toDate(), ...emptyInstance };
197
+ if (!item.instances.length && currentDatePlusNotification >= newInstance.nextDate) {
198
+ await BorrowerCompliance_model_1.BorrowerCompliance.findByIdAndUpdate(complianceBorrowerId, { $push: { ['items.' + index + '.instances']: newInstance } });
199
+ }
200
+ break;
201
+ case 'END_OF_MONTH':
202
+ newInstances = [];
203
+ do {
204
+ const latestDate = newInstances.length ? newInstances[newInstances.length - 1].nextDate : getLatestInstanceDate(item);
205
+ let nextDateJs = !latestDate
206
+ ? (0, dayjs_1.default)(item.startDate)
207
+ : (0, dayjs_1.default)(latestDate)
208
+ .add(1, 'day');
209
+ nextDate = nextDateJs
210
+ .endOf('month')
211
+ .set('hour', 0)
212
+ .set('minute', 0)
213
+ .set('second', 0).toDate();
214
+ const newInstance = { nextDate, ...emptyInstance };
215
+ if (currentDatePlusNotification >= nextDate) {
216
+ newInstances.push(newInstance);
217
+ }
218
+ } while (currentDatePlusNotification >= nextDate);
219
+ if (newInstances.length) {
220
+ await BorrowerCompliance_model_1.BorrowerCompliance.findByIdAndUpdate(complianceBorrowerId, { $push: { ['items.' + index + '.instances']: newInstances } });
221
+ }
222
+ break;
223
+ default:
224
+ const { value, unit } = frequencies[frequency];
225
+ newInstances = [];
226
+ do {
227
+ const latestDate = newInstances.length ? newInstances[newInstances.length - 1].nextDate : getLatestInstanceDate(item);
228
+ nextDate = !latestDate
229
+ ? item.startDate
230
+ : (0, dayjs_1.default)(latestDate)
231
+ .add(value, unit)
232
+ .set('hour', 0)
233
+ .set('minute', 0)
234
+ .set('second', 0).toDate();
235
+ const newInstance = { nextDate, ...emptyInstance };
236
+ if (currentDatePlusNotification >= nextDate) {
237
+ newInstances.push(newInstance);
238
+ }
239
+ } while (currentDatePlusNotification >= nextDate);
240
+ if (newInstances.length) {
241
+ await BorrowerCompliance_model_1.BorrowerCompliance.findByIdAndUpdate(complianceBorrowerId, { $push: { ['items.' + index + '.instances']: newInstances } });
242
+ }
243
+ break;
244
+ }
245
+ }
246
+ }
247
+ return await this.getFullComplianceBorrowerById(complianceBorrowerId);
248
+ }
249
+ async calculateAndUpdateFundingStatus(complianceBorrowerId) {
250
+ const complianceBorrower = await this.getFullComplianceBorrowerById(complianceBorrowerId);
251
+ const fundingStatus = this.calculateFundingStatus(complianceBorrower);
252
+ await this.updateFundingStatus(complianceBorrowerId, fundingStatus);
253
+ }
254
+ calculateFundingStatus(complianceBorrower) {
255
+ let hasErrors = false;
256
+ let hasWarnings = false;
257
+ complianceBorrower.items.forEach((item) => {
258
+ item.instances.forEach((instance) => {
259
+ if (instance.status !== 'ACCEPTED') {
260
+ const { progress } = this.calculateInstanceStatuses(instance, item);
261
+ switch (progress?.status) {
262
+ case item_progress_status_enum_1.EItemProgressStatus.IN_REVIEW:
263
+ hasWarnings = true;
264
+ break;
265
+ case item_progress_status_enum_1.EItemProgressStatus.OVERDUE:
266
+ hasErrors = true;
267
+ break;
268
+ }
269
+ }
270
+ });
271
+ });
272
+ let fundingStatus = 'COMPLIANT';
273
+ if (hasWarnings) {
274
+ fundingStatus = 'PENDING';
275
+ }
276
+ if (hasErrors) {
277
+ fundingStatus = 'OVERDUE';
278
+ }
279
+ if (complianceBorrower.fundingStatus === 'NOT_PAID') {
280
+ fundingStatus = 'NOT_PAID';
281
+ }
282
+ return fundingStatus;
283
+ }
284
+ async updateComplianceBorrower(complianceBorrower) {
285
+ try {
286
+ const { _id } = complianceBorrower;
287
+ const fundingStatus = this.calculateFundingStatus(complianceBorrower);
288
+ return await BorrowerCompliance_model_1.BorrowerCompliance.findByIdAndUpdate(_id, { ...complianceBorrower, fundingStatus });
289
+ }
290
+ catch (e) {
291
+ console.error(e);
292
+ return null;
293
+ }
294
+ }
295
+ async updateFundingStatus(complianceBorrowerId, fundingStatus) {
296
+ try {
297
+ return await BorrowerCompliance_model_1.BorrowerCompliance
298
+ .findByIdAndUpdate(complianceBorrowerId, { fundingStatus });
299
+ }
300
+ catch (e) {
301
+ console.error(e);
302
+ return null;
303
+ }
304
+ }
305
+ async updateLastEmailSent(complianceBorrowerId, lastEmailSentAt) {
306
+ try {
307
+ return await BorrowerCompliance_model_1.BorrowerCompliance
308
+ .findByIdAndUpdate(complianceBorrowerId, { lastEmailSentAt });
309
+ }
310
+ catch (e) {
311
+ console.error(e);
312
+ return null;
313
+ }
314
+ }
315
+ async getAllBorrowersIds(onlyActive = true) {
316
+ try {
317
+ const mainFilter = { isVisible: true };
318
+ const filter = onlyActive ? { 'borrower.active': true, ...mainFilter } : { ...mainFilter };
319
+ const complianceBorrowers = await BorrowerCompliance_model_1.BorrowerCompliance.aggregate([
320
+ {
321
+ $lookup: {
322
+ from: 'borrowers',
323
+ localField: 'borrower',
324
+ foreignField: '_id',
325
+ as: 'borrower',
326
+ },
327
+ }, {
328
+ $unwind: {
329
+ path: '$borrower',
330
+ },
331
+ }, {
332
+ $match: filter,
333
+ },
334
+ ]);
335
+ return complianceBorrowers.map((complianceBorrower) => complianceBorrower._id.toString());
336
+ }
337
+ catch (e) {
338
+ console.error(e);
339
+ return null;
340
+ }
341
+ }
342
+ async getBorrowerListByItemId(complianceItemId) {
343
+ return BorrowerCompliance_model_1.BorrowerCompliance
344
+ .find({
345
+ 'items': {
346
+ $elemMatch: {
347
+ item: complianceItemId,
348
+ },
349
+ },
350
+ })
351
+ .populate('borrower');
352
+ }
353
+ async deleteInstanceById(complianceBorrowerId, complianceInstanceId) {
354
+ await BorrowerCompliance_model_1.BorrowerCompliance
355
+ .findOneAndUpdate({ _id: complianceBorrowerId }, { '$pull': { 'items.$[].instances': { _id: complianceInstanceId } } });
356
+ }
357
+ async getBorrowerByInstanceId(complianceInstanceId) {
358
+ return BorrowerCompliance_model_1.BorrowerCompliance
359
+ .findOne({
360
+ 'items.instances': {
361
+ $elemMatch: {
362
+ _id: complianceInstanceId,
363
+ },
364
+ },
365
+ });
366
+ }
367
+ async markInstanceFilesAsOld(complianceInstanceId) {
368
+ const items = await this._fileManagerService.findItemByInstanceId(complianceInstanceId);
369
+ if (items.length > 0) {
370
+ const itemId = items.pop().items._id;
371
+ return BorrowerCompliance_model_1.BorrowerCompliance
372
+ .findOneAndUpdate({
373
+ 'items.instances': {
374
+ $elemMatch: {
375
+ _id: complianceInstanceId,
376
+ },
377
+ },
378
+ }, { $set: { 'items.$[item].instances.$[instance].files.$[].isFileNew': false } }, {
379
+ arrayFilters: [
380
+ { 'item._id': itemId },
381
+ { 'instance._id': new mongoose_1.default.Types.ObjectId(complianceInstanceId) },
382
+ ],
383
+ });
384
+ }
385
+ }
386
+ async getBorrowerWithPlaidToken() {
387
+ return BorrowerCompliance_model_1.BorrowerCompliance
388
+ .find({ plaidAccessToken: { $exists: true } })
389
+ .select('+plaidAccessToken');
390
+ }
391
+ async getBorrowerEmails(userAccess) {
392
+ const allComplianceBorrower = await BorrowerCompliance_model_1.BorrowerCompliance
393
+ .find(userAccess.allBorrowers ? {} : { 'borrower': { $in: userAccess.borrowersAccess.map((b) => b.borrower) } })
394
+ .populate('borrower items.item')
395
+ .collation({ locale: 'en' })
396
+ .sort({ 'borrower.name': 1 });
397
+ return allComplianceBorrower.map((b) => {
398
+ const items = b.items.map((item) => {
399
+ return {
400
+ value: item.item?.id ?? null,
401
+ title: item.item?.name ?? null,
402
+ };
403
+ });
404
+ const uniqEmails = lodash_1.default.uniq((b.items.reduce((acc, item) => [...acc, ...item.emailAddresses], [])).map((email) => email.email));
405
+ const groupedEmails = b.items.reduce((acc, item) => {
406
+ if (item.emailAddresses.length) {
407
+ acc[item.item?.id ?? null] = item.emailAddresses;
408
+ }
409
+ return acc;
410
+ }, {});
411
+ if (!b.borrower) {
412
+ return;
413
+ }
414
+ return {
415
+ borrower: { _id: b.id, name: b.borrower?.name ?? '', borrowerId: b.borrower?.id ?? '' },
416
+ email: b.email,
417
+ mainEmails: b.mainEmails ?? [],
418
+ financialEmails: b.financialEmails ?? [],
419
+ isEmailingActive: b.isEmailingActive,
420
+ isDailyTransactionsEmailingActive: b.isDailyTransactionsEmailingActive,
421
+ uniqEmails,
422
+ groupedEmails,
423
+ items,
424
+ };
425
+ });
426
+ }
427
+ async getOneBorrowerEmails(userAccess, borrowerId) {
428
+ const borrower = await BorrowerCompliance_model_1.BorrowerCompliance
429
+ .findOne({ _id: borrowerId })
430
+ .populate('borrower items.item')
431
+ .collation({ locale: 'en' })
432
+ .sort({ 'borrower.name': 1 });
433
+ const items = borrower.items.map((item) => {
434
+ return {
435
+ value: item.item?.id ?? null,
436
+ title: item.item?.name ?? null,
437
+ };
438
+ });
439
+ const uniqEmails = lodash_1.default.uniq((borrower.items.reduce((acc, item) => [...acc, ...item.emailAddresses], [])).map((email) => email.email));
440
+ const groupedEmails = borrower.items.reduce((acc, item) => {
441
+ if (item.emailAddresses.length) {
442
+ acc[item.item?.id ?? null] = item.emailAddresses;
443
+ }
444
+ return acc;
445
+ }, {});
446
+ if (!borrower.borrower) {
447
+ return;
448
+ }
449
+ return {
450
+ borrower: { _id: borrower.id, name: borrower.borrower?.name ?? '', borrowerId: borrower.borrower?.id ?? '' },
451
+ email: borrower.email,
452
+ mainEmails: borrower.mainEmails ?? [],
453
+ financialEmails: borrower.financialEmails ?? [],
454
+ isEmailingActive: borrower.isEmailingActive,
455
+ isDailyTransactionsEmailingActive: borrower.isDailyTransactionsEmailingActive,
456
+ uniqEmails,
457
+ groupedEmails,
458
+ items,
459
+ };
460
+ }
461
+ async getBorrowerEmailsGrouped(borrowerId) {
462
+ const borrower = await BorrowerCompliance_model_1.BorrowerCompliance.findOne({ borrower: borrowerId });
463
+ if (borrower) {
464
+ return {
465
+ mainEmails: borrower.mainEmails,
466
+ financialEmails: borrower.financialEmails,
467
+ };
468
+ }
469
+ }
470
+ async updateBorrowerEmailAddresses(emailUpdate) {
471
+ const filter = { _id: emailUpdate._id };
472
+ const update = {
473
+ $set: {
474
+ isEmailingActive: emailUpdate.isEmailingActive,
475
+ isDailyTransactionsEmailingActive: emailUpdate.isDailyTransactionsEmailingActive,
476
+ mainEmails: emailUpdate.mainEmails,
477
+ financialEmails: emailUpdate.financialEmails,
478
+ 'items.$[].emailAddresses': [],
479
+ },
480
+ };
481
+ await BorrowerCompliance_model_1.BorrowerCompliance.updateOne(filter, update);
482
+ await Promise.all(Object.entries(emailUpdate.groupedEmails).map(async ([id, emails]) => {
483
+ const itemUpdate = {
484
+ $set: {
485
+ 'items.$[item].emailAddresses': emails,
486
+ },
487
+ };
488
+ const arrayFilter = {
489
+ arrayFilters: [
490
+ { 'item.item': id },
491
+ ],
492
+ };
493
+ await BorrowerCompliance_model_1.BorrowerCompliance.updateOne(filter, itemUpdate, arrayFilter);
494
+ }));
495
+ return BorrowerCompliance_model_1.BorrowerCompliance.findOne(filter);
496
+ }
497
+ async toggleComplianceBorrowerVisibility(borrowerId, isVisible) {
498
+ const foundBorrower = await BorrowerCompliance_model_1.BorrowerCompliance.findOne({ borrower: borrowerId });
499
+ if (!!foundBorrower) {
500
+ await BorrowerCompliance_model_1.BorrowerCompliance.findByIdAndUpdate(foundBorrower._id, { isVisible });
501
+ }
502
+ }
503
+ async createComplianceBorrower(borrowerId, isVisible = true) {
504
+ const foundBorrower = await BorrowerCompliance_model_1.BorrowerCompliance.findOne({ borrower: borrowerId });
505
+ if (!!foundBorrower) {
506
+ await BorrowerCompliance_model_1.BorrowerCompliance.findByIdAndUpdate(foundBorrower._id, { isVisible });
507
+ }
508
+ else {
509
+ const newComplianceBorrower = new BorrowerCompliance_model_1.BorrowerCompliance({ borrower: borrowerId, isVisible });
510
+ await newComplianceBorrower.save();
511
+ }
512
+ }
513
+ async removeIncorrectBorrowers() {
514
+ const allComplianceBorrowers = await BorrowerCompliance_model_1.BorrowerCompliance.find({});
515
+ let n = 0;
516
+ for (const borrower of allComplianceBorrowers) {
517
+ if ((borrower['isDeleted'] === true) || borrower['isDeleted'] === undefined) {
518
+ try {
519
+ await BorrowerCompliance_model_1.BorrowerCompliance.findByIdAndDelete(borrower._id);
520
+ n += 1;
521
+ }
522
+ catch (e) {
523
+ console.error(e);
524
+ }
525
+ }
526
+ await BorrowerCompliance_model_1.BorrowerCompliance.findByIdAndUpdate(borrower._id, { isVisible: true });
527
+ }
528
+ const allBorrowers = await Borrower_model_1.BorrowerModel.find({});
529
+ for (const borrower of allBorrowers) {
530
+ const complianceBorrower = await BorrowerCompliance_model_1.BorrowerCompliance.findOne({ borrower: borrower._id });
531
+ if (!complianceBorrower) {
532
+ await this.createComplianceBorrower(borrower._id.toString(), false);
533
+ }
534
+ }
535
+ }
536
+ async getBorrowerListReport(user) {
537
+ const userFilter = user.allBorrowers
538
+ ? { isVisible: true }
539
+ : { 'borrower': { $in: user.borrowersAccess.map((b) => b.borrower) }, isVisible: true };
540
+ const borrowers = await BorrowerCompliance_model_1.BorrowerCompliance
541
+ .find(userFilter)
542
+ .populate('borrower')
543
+ .populate('items.item');
544
+ const finalList = [
545
+ ['borrower', 'due date', 'item', 'status'],
546
+ ];
547
+ borrowers
548
+ .sort((a, b) => a.borrower.name.localeCompare(b.borrower.name))
549
+ .forEach((borrower) => {
550
+ borrower.items
551
+ .filter((borrowerItem) => !!borrowerItem.item)
552
+ .sort((a, b) => a.item.name.localeCompare(b.item.name))
553
+ .forEach((item) => {
554
+ item.instances.forEach((instance) => {
555
+ if (instance.status !== 'ACCEPTED') {
556
+ finalList.push([
557
+ borrower.borrower.name.trim(),
558
+ instance.nextDate,
559
+ item.item.name.trim(),
560
+ instance.status,
561
+ ]);
562
+ }
563
+ });
564
+ });
565
+ });
566
+ return await this._uploadsService.convertDataToFile([{ list: finalList }]);
567
+ }
568
+ }
569
+ exports.ComplianceBorrowersService = ComplianceBorrowersService;