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,640 @@
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.QuickbooksService = 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 lodash_1 = __importDefault(require("lodash"));
11
+ const loan_charge_type_enum_1 = require("../enums/loan-charge-type.enum");
12
+ const loan_types_enum_1 = require("../enums/loan-types.enum");
13
+ const LoanProducts_model_1 = require("../models/LoanProducts.model");
14
+ const Borrower_model_1 = require("../models/Borrower.model");
15
+ const TermLoan_model_1 = require("../models/TermLoan.model");
16
+ const reports_db_1 = require("../db/reports.db");
17
+ const QuickbooksAccount_model_1 = require("../models/QuickbooksAccount.model");
18
+ const headersIIF = [
19
+ {
20
+ service: '!TRNS',
21
+ id: 'TRNSID',
22
+ type: 'TRNSTYPE',
23
+ date: 'DATE',
24
+ account: 'ACCNT',
25
+ class: 'CLASS',
26
+ amount: 'AMOUNT',
27
+ document: 'DOCNUM',
28
+ memo: 'MEMO',
29
+ },
30
+ {
31
+ service: '!SPL',
32
+ id: 'SPLID',
33
+ type: 'TRNSTYPE',
34
+ date: 'DATE',
35
+ account: 'ACCNT',
36
+ class: 'CLASS',
37
+ amount: 'AMOUNT',
38
+ document: 'DOCNUM',
39
+ memo: 'MEMO',
40
+ },
41
+ {
42
+ service: '!ENDTRNS',
43
+ id: '',
44
+ type: '',
45
+ date: '',
46
+ account: '',
47
+ class: '',
48
+ amount: '',
49
+ document: '',
50
+ memo: '',
51
+ },
52
+ ];
53
+ const IIF = [
54
+ {
55
+ service: 'ENDTRNS',
56
+ id: '',
57
+ type: '',
58
+ date: '',
59
+ account: '',
60
+ class: '',
61
+ amount: '',
62
+ document: '',
63
+ memo: '',
64
+ },
65
+ ];
66
+ const headersCSV = () => {
67
+ return {
68
+ journalNumber: 'Journal No',
69
+ journalDate: 'Journal Date',
70
+ memo: 'Memo',
71
+ account: 'Account',
72
+ amount: 'Amount',
73
+ description: 'Description',
74
+ name: 'Name',
75
+ location: 'Location',
76
+ class: 'Class',
77
+ };
78
+ };
79
+ const transactionsDateFormat = 'DDMMMYYYY';
80
+ const IIFDateFormat = 'M/D/YYYY';
81
+ class QuickbooksService {
82
+ banksService;
83
+ bankUploadedTransactionsService;
84
+ borrowerService;
85
+ brokersService;
86
+ cashAllocationService;
87
+ companiesService;
88
+ loanChargesService;
89
+ loanPaymentsService;
90
+ constructor(banksService, bankUploadedTransactionsService, borrowerService, brokersService, cashAllocationService, companiesService, loanChargesService, loanPaymentsService) {
91
+ this.banksService = banksService;
92
+ this.bankUploadedTransactionsService = bankUploadedTransactionsService;
93
+ this.borrowerService = borrowerService;
94
+ this.brokersService = brokersService;
95
+ this.cashAllocationService = cashAllocationService;
96
+ this.companiesService = companiesService;
97
+ this.loanChargesService = loanChargesService;
98
+ this.loanPaymentsService = loanPaymentsService;
99
+ }
100
+ async uploadAccounts(accounts, deleteOld) {
101
+ const accountsWithId = accounts.map((account) => ({ _id: 'new_', ...account }));
102
+ await this.saveAccounts(accountsWithId, deleteOld);
103
+ }
104
+ async getAllAccounts() {
105
+ return QuickbooksAccount_model_1.QuickbooksAccount
106
+ .find({}, { createdAt: 0, updatedAt: 0, __v: 0 })
107
+ .sort({ order: 1 }).lean();
108
+ }
109
+ async saveAccounts(accounts, deleteOld) {
110
+ if (!accounts.length) {
111
+ return;
112
+ }
113
+ if (deleteOld) {
114
+ const companyId = accounts[0].companyId;
115
+ // console.log({ companyId });
116
+ // const existingAccounts = await QuickbooksAccount.find({ companyId: new mongoose.Types.ObjectId(companyId) });
117
+ // console.log({ existingAccounts });
118
+ const accountIds = accounts
119
+ .filter((account) => !account._id.startsWith('new_'))
120
+ .map((account) => new mongoose_1.default.Types.ObjectId(account._id));
121
+ await QuickbooksAccount_model_1.QuickbooksAccount.deleteMany({ _id: { $nin: accountIds }, companyId });
122
+ }
123
+ const accountSavePromises = accounts.map(async (account, order) => {
124
+ if (account._id.startsWith('new_')) {
125
+ const { _id, ...accountWithoutId } = account;
126
+ return QuickbooksAccount_model_1.QuickbooksAccount.create({ ...accountWithoutId, order });
127
+ }
128
+ else {
129
+ return QuickbooksAccount_model_1.QuickbooksAccount.findByIdAndUpdate(account._id, { ...account, order }, { new: true, upsert: true });
130
+ }
131
+ });
132
+ return Promise.all(accountSavePromises);
133
+ }
134
+ async getAllProducts() {
135
+ const borrowers = await this.borrowerService.getActiveBorrowers();
136
+ const borrowerIds = borrowers.map((borrower) => borrower._id);
137
+ return LoanProducts_model_1.LoanProduct.aggregate([
138
+ {
139
+ '$match': {
140
+ borrowerId: { $in: borrowerIds },
141
+ },
142
+ }, {
143
+ $lookup: {
144
+ from: 'borrowers',
145
+ localField: 'borrowerId',
146
+ foreignField: '_id',
147
+ as: 'borrower',
148
+ },
149
+ }, {
150
+ $unwind: {
151
+ path: '$borrower',
152
+ },
153
+ }, {
154
+ $project: {
155
+ '_id': 0,
156
+ 'data': {
157
+ $mergeObjects: [
158
+ {
159
+ $arrayToObject: {
160
+ $filter: {
161
+ input: { $objectToArray: '$$ROOT' },
162
+ cond: { $in: ['$$this.k', ['name', '_id', 'type']] },
163
+ },
164
+ },
165
+ }, {
166
+ 'clientName': '$borrower.name',
167
+ 'productAccrualStatus': '$borrower.accrualStatus',
168
+ },
169
+ ],
170
+ },
171
+ },
172
+ }, {
173
+ $replaceRoot: {
174
+ 'newRoot': '$data',
175
+ },
176
+ }, {
177
+ $project: {
178
+ '_id': 0,
179
+ 'productId': '$_id',
180
+ 'productName': '$name',
181
+ 'productType': '$type',
182
+ 'clientName': 1,
183
+ 'productAccrualStatus': 1,
184
+ },
185
+ }, {
186
+ $sort: {
187
+ 'clientName': 1,
188
+ 'order': 1,
189
+ },
190
+ }, {
191
+ $addFields: {
192
+ 'isSelected': null,
193
+ },
194
+ }, {
195
+ $lookup: {
196
+ from: 'term_loans',
197
+ let: {
198
+ productIdVar: '$productId',
199
+ productTypeVar: '$productType',
200
+ },
201
+ pipeline: [
202
+ {
203
+ $match: {
204
+ $expr: {
205
+ $and: [
206
+ {
207
+ $eq: [
208
+ '$productId',
209
+ '$$productIdVar',
210
+ ],
211
+ },
212
+ {
213
+ $ne: [
214
+ '$$productTypeVar',
215
+ 'REVOLVER',
216
+ ],
217
+ },
218
+ {
219
+ $eq: ['$actual', true],
220
+ },
221
+ ],
222
+ },
223
+ },
224
+ },
225
+ ],
226
+ as: 'term',
227
+ },
228
+ }, {
229
+ $unwind: {
230
+ path: '$term',
231
+ preserveNullAndEmptyArrays: true,
232
+ },
233
+ }, {
234
+ $addFields: {
235
+ selectable: {
236
+ $cond: {
237
+ if: '$term',
238
+ then: {
239
+ $eq: [
240
+ '$term.calculationStatus',
241
+ 'CALCULATED',
242
+ ],
243
+ },
244
+ else: true,
245
+ },
246
+ },
247
+ },
248
+ },
249
+ ]);
250
+ }
251
+ async getChargeTransactionsForAccrual(productIds, reportDate) {
252
+ if (productIds.length === 0) {
253
+ return [];
254
+ }
255
+ const transactionsFilter = {
256
+ productIds: productIds,
257
+ start: (0, dayjs_1.default)(reportDate).utcOffset(0).startOf('month').toDate(),
258
+ end: (0, dayjs_1.default)(reportDate).utcOffset(0).endOf('month').toDate(),
259
+ };
260
+ return await this.loanChargesService.getLoanStatementsForProduct(transactionsFilter);
261
+ }
262
+ async getChargeTransactionsForPayments(productIds, reportDate) {
263
+ const start = (0, dayjs_1.default)(reportDate).utcOffset(0).startOf('day').toDate();
264
+ const end = (0, dayjs_1.default)(reportDate).utcOffset(0).endOf('day').toDate();
265
+ const payments = await this.loanPaymentsService.getPaymentsForPeriod(productIds, start, end);
266
+ if (!payments.length) {
267
+ return [];
268
+ }
269
+ const transactionIds = payments.reduce((acc, payment) => [...acc, ...payment.paid.map((p) => p.statementId)], []);
270
+ const transactionsFilter = { productIds, transactionIds, start, end };
271
+ return await this.loanChargesService.getLoanStatementsForIdsAndCharge(transactionsFilter);
272
+ }
273
+ async getPrincipalTransactionsForPayments(productId, reportDate) {
274
+ const start = (0, dayjs_1.default)(reportDate).utcOffset(0).startOf('day').toDate();
275
+ const end = (0, dayjs_1.default)(reportDate).utcOffset(0).endOf('day').toDate();
276
+ const payments = await this.loanPaymentsService.getPaymentsForPeriod([productId], start, end);
277
+ if (!payments.length) {
278
+ return {};
279
+ }
280
+ return payments.reduce((acc, payment) => {
281
+ const settlementCode = payment.settlementCode ? payment.settlementCode : null;
282
+ const amount = payment.loanTransactions.reduce((acc, transaction) => new decimal_js_1.default(acc).add(transaction.amount).toNumber(), 0);
283
+ return {
284
+ ...acc,
285
+ [settlementCode]: amount,
286
+ };
287
+ }, {});
288
+ }
289
+ async getQuickbooksReport(params) {
290
+ const reportErrorsSet = new Set();
291
+ await Promise.all(params.productIds.map(async (productId) => {
292
+ const product = await this.loanChargesService.getLoanProductById(productId);
293
+ if (product.type === loan_types_enum_1.ELoanTypes.TERM) {
294
+ const termLoan = await TermLoan_model_1.TermLoanModel.findOne({ productId, actual: true }).lean();
295
+ if (termLoan && termLoan.calculationStatus !== TermLoan_model_1.ETermLoanStatus.CALCULATED) {
296
+ reportErrorsSet.add(`${product.name} is not calculated`);
297
+ }
298
+ }
299
+ }));
300
+ if (reportErrorsSet.size > 0) {
301
+ return { reportData: [], reportErrors: Array.from(reportErrorsSet) };
302
+ }
303
+ const { reportType, productIds, chargeTypes, reportDate } = params;
304
+ const reportDateFormatted = (0, dayjs_1.default)(reportDate).utcOffset(0).format('MM/DD/YYYY').toUpperCase();
305
+ const reportDateTrFormatted = (0, dayjs_1.default)(reportDate).utcOffset(0).format(transactionsDateFormat).toUpperCase();
306
+ const currentDateTrFormatted = (0, dayjs_1.default)(new Date).utcOffset(0).format(transactionsDateFormat).toUpperCase();
307
+ const isAccrual = reportType === 'accrual';
308
+ const mainData = [];
309
+ const trTemplate = {
310
+ service: 'SPL',
311
+ id: '',
312
+ type: 'GENERAL JOURNAL',
313
+ date: reportDateFormatted,
314
+ account: '',
315
+ class: '',
316
+ amount: 0,
317
+ document: '',
318
+ memo: '',
319
+ };
320
+ await Promise.all(productIds.map(async (productId) => {
321
+ const product = await this.loanChargesService.getLoanProductById(productId);
322
+ const charges = await this.loanChargesService.getLoanChargeForProduct(productId);
323
+ const filteredCharges = charges.filter((charge) => chargeTypes.includes(charge.chargeType));
324
+ const productBrokers = await this.brokersService.getProductBrokers(productId);
325
+ const borrower = await Borrower_model_1.BorrowerModel.findById(product.borrowerId).lean();
326
+ const allTransactions = isAccrual
327
+ ? await this.getChargeTransactionsForAccrual([productId], reportDate)
328
+ : await this.getChargeTransactionsForPayments([productId], reportDate);
329
+ await Promise.all(filteredCharges.map(async (charge) => {
330
+ const chargeTransactions = allTransactions.filter((tr) => tr.chargeId.toString() === charge._id.toString());
331
+ if (!chargeTransactions.length) {
332
+ return;
333
+ }
334
+ const totalAmountGroups = isAccrual
335
+ ? { [charge.PLCode]: chargeTransactions.reduce((acc, tr) => new decimal_js_1.default(acc).add(tr.amount).toNumber(), 0) }
336
+ : chargeTransactions.reduce((acc, tr) => {
337
+ if (tr.settlementCode) {
338
+ return {
339
+ ...acc,
340
+ [tr.settlementCode]: new decimal_js_1.default(acc[tr.settlementCode] || 0).add(tr.amount).toNumber(),
341
+ };
342
+ }
343
+ return {
344
+ ...acc,
345
+ [charge.PLCode]: new decimal_js_1.default(acc[charge.PLCode] || 0).add(tr.amount).toNumber(),
346
+ };
347
+ }, {});
348
+ await Promise.all(Object.entries(totalAmountGroups).map(async ([PLCode, totalAmountValue]) => {
349
+ if (totalAmountValue === 0) {
350
+ return;
351
+ }
352
+ let totalAmount = product.isParticipant ? -totalAmountValue : totalAmountValue;
353
+ totalAmount = isAccrual ? totalAmount : -totalAmount;
354
+ const quickbooksAccountBS = await QuickbooksAccount_model_1.QuickbooksAccount.findOne({ accountCode: charge.code }).lean();
355
+ const quickbooksAccountPL = await QuickbooksAccount_model_1.QuickbooksAccount.findOne({ accountCode: PLCode }).lean();
356
+ if (!quickbooksAccountBS || !quickbooksAccountPL) {
357
+ if (!quickbooksAccountBS) {
358
+ reportErrorsSet.add(charge.code);
359
+ }
360
+ if (!quickbooksAccountPL) {
361
+ reportErrorsSet.add(PLCode);
362
+ }
363
+ return;
364
+ }
365
+ const tr = {
366
+ ...trTemplate,
367
+ productId,
368
+ class: borrower.code,
369
+ memo: `${borrower.code} ${product.isParticipant ? 'PARTICIPANT' : ''} ${reports_db_1.EChargeType[charge.chargeType].toUpperCase()} ${product.type.toUpperCase()} - TRANS: ${reportDateTrFormatted} - POST: ${currentDateTrFormatted}`,
370
+ };
371
+ tr.account = quickbooksAccountBS.fullName;
372
+ tr.amount = totalAmount;
373
+ mainData.push({ ...tr });
374
+ tr.account = quickbooksAccountPL.fullName;
375
+ tr.amount = -totalAmount;
376
+ mainData.push({ ...tr });
377
+ if (chargeTypes.includes('BROKERS') && isAccrual) {
378
+ const handleFee = async (broker, shareName) => {
379
+ const quickbooksAccountBrokerBS = await QuickbooksAccount_model_1.QuickbooksAccount.findOne({ accountCode: broker.BSCode }).lean();
380
+ const quickbooksAccountBrokerPL = await QuickbooksAccount_model_1.QuickbooksAccount.findOne({ accountCode: broker.PLCode }).lean();
381
+ if (!quickbooksAccountBrokerBS || !quickbooksAccountBrokerPL) {
382
+ if (!quickbooksAccountBrokerBS) {
383
+ reportErrorsSet.add(broker.BSCode);
384
+ }
385
+ if (!quickbooksAccountBrokerPL) {
386
+ reportErrorsSet.add(broker.PLCode);
387
+ }
388
+ return;
389
+ }
390
+ const tr = {
391
+ ...trTemplate,
392
+ productId,
393
+ class: borrower.code,
394
+ amount: new decimal_js_1.default(-totalAmount).mul(broker[shareName]).toDP(2).toNumber(),
395
+ memo: `${borrower.code} ${reports_db_1.EChargeType[charge.chargeType].toUpperCase()} BROKER ${broker.order + 1}`,
396
+ };
397
+ tr.account = quickbooksAccountBrokerBS.fullName;
398
+ mainData.push({ ...tr });
399
+ tr.account = quickbooksAccountBrokerPL.fullName;
400
+ tr.amount = -tr.amount;
401
+ mainData.push({ ...tr });
402
+ };
403
+ const handlers = {
404
+ [loan_charge_type_enum_1.ELoanChargeType.ADMIN_FEE]: async (broker) => await handleFee(broker, 'adminShare'),
405
+ [loan_charge_type_enum_1.ELoanChargeType.INTEREST_FEE]: async (broker) => await handleFee(broker, 'interestShare'),
406
+ [loan_charge_type_enum_1.ELoanChargeType.OTHER]: async (broker) => await handleFee(broker, 'otherShare'),
407
+ };
408
+ await Promise.all(productBrokers.map(async (broker) => {
409
+ if (handlers[charge.chargeType]) {
410
+ await handlers[charge.chargeType](broker);
411
+ }
412
+ }));
413
+ }
414
+ }));
415
+ }));
416
+ const principalPayments = isAccrual || product.type === loan_types_enum_1.ELoanTypes.REVOLVER
417
+ ? {}
418
+ : await this.getPrincipalTransactionsForPayments(productId, reportDate);
419
+ await Promise.all(Object.entries(principalPayments).map(async ([settlementCode, amount]) => {
420
+ const tr = {
421
+ ...trTemplate,
422
+ productId,
423
+ class: borrower.code,
424
+ amount: product.isParticipant ? +amount : -+amount,
425
+ memo: `${borrower.code} ${product.isParticipant ? 'PARTICIPANT' : ''} PRINCIPAL PAID TERM - TRANS: ${reportDateTrFormatted} - POST: ${currentDateTrFormatted}`,
426
+ };
427
+ if (settlementCode === 'null') {
428
+ const products = await this.loanChargesService.getLoanProducts(borrower._id.toString());
429
+ const revolverProduct = products.find((product) => product.type === loan_types_enum_1.ELoanTypes.REVOLVER);
430
+ if (revolverProduct) {
431
+ settlementCode = revolverProduct.code;
432
+ }
433
+ }
434
+ const quickbooksAccountPaymentBS = await QuickbooksAccount_model_1.QuickbooksAccount.findOne({ accountCode: product.code }).lean();
435
+ const quickbooksAccountPaymentPL = await QuickbooksAccount_model_1.QuickbooksAccount.findOne({ accountCode: settlementCode }).lean();
436
+ if (!quickbooksAccountPaymentBS || !quickbooksAccountPaymentPL) {
437
+ if (!quickbooksAccountPaymentBS) {
438
+ reportErrorsSet.add(product.code);
439
+ }
440
+ if (!quickbooksAccountPaymentPL) {
441
+ reportErrorsSet.add(settlementCode);
442
+ }
443
+ return;
444
+ }
445
+ tr.account = quickbooksAccountPaymentBS.fullName;
446
+ tr.amount = -tr.amount;
447
+ mainData.push({ ...tr });
448
+ tr.amount = -tr.amount;
449
+ tr.account = quickbooksAccountPaymentPL.fullName;
450
+ mainData.push({ ...tr });
451
+ }));
452
+ }));
453
+ const groupedData = lodash_1.default.groupBy(mainData, (obj) => obj.service + obj.id + obj.type + obj.date + obj.account + obj.class + obj.document + obj.memo + obj.productId);
454
+ const mergedData = Object.keys(groupedData).reduce((acc, key) => {
455
+ const group = groupedData[key];
456
+ const mergedObject = {
457
+ account: group[0].account,
458
+ class: group[0].class,
459
+ date: group[0].date,
460
+ document: group[0].document,
461
+ memo: group[0].memo,
462
+ service: group[0].service,
463
+ type: group[0].type,
464
+ id: group[0].id,
465
+ amount: group.reduce((acc, curr) => new decimal_js_1.default(acc).add(+curr.amount).toNumber(), 0),
466
+ };
467
+ return [...acc, mergedObject];
468
+ }, []);
469
+ const reportData = (lodash_1.default.orderBy(mergedData, ['class', 'memo', 'account'], ['asc', 'asc', 'asc'])).filter((record) => record.amount !== 0);
470
+ if (reportData.length > 0) {
471
+ reportData[0].service = 'TRNS';
472
+ }
473
+ return { reportData, reportErrors: Array.from(reportErrorsSet).map((code) => `No account for ${code}`) };
474
+ }
475
+ async getQuickbooksCashReport(params) {
476
+ const reportErrorsSet = new Set();
477
+ const { reportType, productIds, chargeTypes, reportDate } = params;
478
+ const reportDateFormatted = (0, dayjs_1.default)(reportDate).utcOffset(0).format('MM/DD/YYYY').toUpperCase();
479
+ const reportDateTrFormatted = (0, dayjs_1.default)(reportDate).utcOffset(0).format(transactionsDateFormat).toUpperCase();
480
+ const startDate = (0, dayjs_1.default)(reportDate).utcOffset(0).startOf('day').toDate();
481
+ const endDate = (0, dayjs_1.default)(reportDate).utcOffset(0).endOf('day').toDate();
482
+ const transactions = await this.bankUploadedTransactionsService.getUploadedBankTransactions(startDate, endDate);
483
+ const { references, products } = await this.cashAllocationService.getAllCashAllocations();
484
+ const allAccounts = await this.getAllAccounts();
485
+ const companyAccounts = allAccounts.filter((acc) => acc.companyId?.toString() === params.companyId);
486
+ const banks = await this.banksService.getBanks();
487
+ const banksMap = new Map();
488
+ banks.forEach((bank) => banksMap.set(bank.bankAccountNumber, bank));
489
+ const reportData = transactions
490
+ .reduce((acc, transaction) => {
491
+ // if (!transaction.isConverted) { // TODO only for converted?
492
+ // return acc;
493
+ // }
494
+ if (transaction.splitTransactions.length) {
495
+ const restTransaction = { ...transaction, splitMemo: '' };
496
+ const splitTransactions = transaction.splitTransactions.map((splitTransaction) => {
497
+ restTransaction.amount = new decimal_js_1.default(restTransaction.amount).sub(splitTransaction.amount).toNumber();
498
+ return {
499
+ ...transaction,
500
+ reference: splitTransaction.reference,
501
+ amount: splitTransaction.amount,
502
+ splitMemo: splitTransaction.memo ?? '',
503
+ };
504
+ });
505
+ if (restTransaction.amount !== 0) {
506
+ return [...acc, restTransaction, ...splitTransactions];
507
+ }
508
+ return [...acc, ...splitTransactions];
509
+ }
510
+ return [...acc, { ...transaction, splitMemo: '' }];
511
+ }, [])
512
+ .reduce((acc, transaction) => {
513
+ const foundReference = references.find((ref) => transaction.reference.toLowerCase().includes(ref.reference.toLowerCase()));
514
+ if (!foundReference || !foundReference.cashAllocationProductId) {
515
+ return acc;
516
+ }
517
+ const foundProduct = products.find((product) => product._id.toString() === foundReference.cashAllocationProductId.toString());
518
+ const accounts = foundProduct.accounts[params.companyId];
519
+ if (!accounts) {
520
+ return acc;
521
+ }
522
+ const findAccountForBank = () => {
523
+ const foundBank = banksMap.get(transaction.accountNumber);
524
+ if (!foundBank) {
525
+ return null;
526
+ }
527
+ const accountCodeId = foundBank.ledgerAccountCodes[params.companyId];
528
+ if (!accountCodeId) {
529
+ return null;
530
+ }
531
+ const account = companyAccounts.find((account) => account._id.toString() === accountCodeId.toString());
532
+ return account;
533
+ };
534
+ if (!accounts.accountId1 || !accounts.accountId2) {
535
+ return acc;
536
+ }
537
+ const account1 = accounts.accountId1 === 'BANK'
538
+ ? findAccountForBank()
539
+ : companyAccounts.find((acc) => acc._id.toString() === accounts.accountId1.toString());
540
+ if (!account1) {
541
+ return acc;
542
+ }
543
+ const account2 = accounts.accountId2 === 'BANK'
544
+ ? findAccountForBank()
545
+ : companyAccounts.find((acc) => acc._id.toString() === accounts.accountId2.toString());
546
+ if (!account2) {
547
+ return acc;
548
+ }
549
+ const reportTransactions = {
550
+ type: 'GENERAL JOURNAL',
551
+ date: (0, dayjs_1.default)(transaction.date).format(IIFDateFormat),
552
+ class: foundProduct.class,
553
+ amount: transaction.amount,
554
+ document: '',
555
+ location: foundProduct.location,
556
+ id: '',
557
+ service: 'SPL',
558
+ };
559
+ const reportTransactions1 = {
560
+ ...reportTransactions,
561
+ account: account1?.fullName ?? 'BANK',
562
+ amount: -reportTransactions.amount,
563
+ memo: +reportTransactions.amount > 0 ? foundProduct.DRMemo : foundProduct.CRMemo,
564
+ };
565
+ const reportTransactions2 = {
566
+ ...reportTransactions,
567
+ account: account2?.fullName ?? 'BANK',
568
+ amount: reportTransactions.amount,
569
+ memo: +reportTransactions.amount > 0 ? foundProduct.DRMemo : foundProduct.CRMemo,
570
+ };
571
+ return [...acc, reportTransactions1, reportTransactions2];
572
+ }, []);
573
+ if (reportData.length > 0) {
574
+ reportData[0].service = 'TRNS';
575
+ }
576
+ return { reportData, reportErrors: Array.from(reportErrorsSet).map((code) => `No account for ${code}`) };
577
+ }
578
+ convertQuickbooksReport(reportData, format, memo) {
579
+ switch (format) {
580
+ case 'IIF': {
581
+ const fullReport = [...headersIIF, ...reportData, ...IIF];
582
+ let iifContent = '';
583
+ const getReportString = (transaction) => {
584
+ const fields = [
585
+ transaction.service,
586
+ transaction.id,
587
+ transaction.type,
588
+ transaction.date,
589
+ transaction.account,
590
+ transaction.class,
591
+ transaction.amount,
592
+ transaction.document,
593
+ transaction.memo,
594
+ ];
595
+ const joinedString = fields.join('\t');
596
+ iifContent += `${joinedString}\n`;
597
+ };
598
+ fullReport.forEach(getReportString);
599
+ return iifContent;
600
+ }
601
+ case 'CSV': {
602
+ const ref = `REF${Math.floor(Math.random() * (999 - 100 + 1)) + 100}`;
603
+ const qboReport = reportData.map((transaction) => ({
604
+ journalNumber: `${transaction.date} ${ref}`,
605
+ journalDate: transaction.date,
606
+ memo,
607
+ account: transaction.account,
608
+ amount: transaction.amount,
609
+ description: transaction.memo,
610
+ name: '',
611
+ location: transaction.location,
612
+ class: transaction.class,
613
+ }));
614
+ const fullReport = [headersCSV(), ...qboReport];
615
+ return JSON.stringify({ fullReport });
616
+ }
617
+ }
618
+ }
619
+ async reassignAccounts() {
620
+ const companies = await this.companiesService.getCompanies();
621
+ const accounts = await QuickbooksAccount_model_1.QuickbooksAccount.find().lean();
622
+ for (const [index, company] of companies.entries()) {
623
+ if (index === 0) {
624
+ await Promise.all(accounts.map(async (account) => {
625
+ await QuickbooksAccount_model_1.QuickbooksAccount.findByIdAndUpdate(account._id, { companyId: company._id });
626
+ }));
627
+ }
628
+ else {
629
+ await Promise.all(accounts.map(async (account) => {
630
+ const { _id, ...rest } = account;
631
+ console.log(rest);
632
+ const newAccount = new QuickbooksAccount_model_1.QuickbooksAccount({ ...rest });
633
+ newAccount.companyId = company._id;
634
+ await newAccount.save();
635
+ }));
636
+ }
637
+ }
638
+ }
639
+ }
640
+ exports.QuickbooksService = QuickbooksService;