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,517 @@
1
+ import Joi from 'joi';
2
+ import mongoose from 'mongoose';
3
+ import dayjs from 'dayjs';
4
+ import _ from 'lodash';
5
+ import Decimal from 'decimal.js';
6
+
7
+ import { rawDataToDTO } from '../helpers/db-data.helper';
8
+ import { ISelectedMonth } from '../helpers/date.helper';
9
+
10
+ import {
11
+ FinancialSpreading,
12
+ FinancialSpreadingDTO,
13
+ financialSpreadingParamsValidationSchema,
14
+ financialSpreadingViewValidationSchema,
15
+ IFinancialSpreading,
16
+ IFinancialSpreadingParams,
17
+ IFinancialSpreadingUpload,
18
+ IFinancialSpreadingView,
19
+ IFinancialSpreadingViewWithDeepData,
20
+ } from '../models/FinancialSpreading.model';
21
+ import {
22
+ EFinanceSpreadingBSTotal,
23
+ EFinanceSpreadingPLTotal,
24
+ EFinancialSpreadingType,
25
+ financeSpreadingLists,
26
+ FinancialSpreadingSheet,
27
+ FinancialSpreadingSheetDTO,
28
+ financialSpreadingSheetViewValidationSchema,
29
+ financialSpreadingTotalDictionary,
30
+ IFinancialSpreadingSheet,
31
+ IFinancialSpreadingSheetView,
32
+ } from '../models/FinancialSpreadingSheet.model';
33
+ import { IExcelDataCellWithStyles, UploadsService } from './uploads.service';
34
+
35
+ export const getShiftedMonth = (month: ISelectedMonth, shift: number) => {
36
+ const nextMonth = dayjs().utcOffset(0).year(month.year).month(month.month - 1).add(shift, 'month');
37
+ return { year: nextMonth.year(), month: nextMonth.month() + 1 };
38
+ };
39
+
40
+ const rowStyleMap = {
41
+ orangeOnGray: { font: { italic: true, color: { rgb: 'EC5B00' } }, fill: { fgColor: { rgb: 'D3D3D3' } } },
42
+ whiteOnBlack: { font: { color: { rgb: 'FFFFFF' } }, fill: { fgColor: { rgb: '000000' } } },
43
+ };
44
+
45
+ const rowStyles = {
46
+ 'GROSS_MARGIN': rowStyleMap.orangeOnGray,
47
+ 'OPERATING_MARGIN': rowStyleMap.orangeOnGray,
48
+ 'INCOME_FROM_OPERATIONS': rowStyleMap.whiteOnBlack,
49
+ 'PRE_TAX_INCOME': rowStyleMap.whiteOnBlack,
50
+ 'NET_INCOME': rowStyleMap.whiteOnBlack,
51
+ 'TOTAL_NON_CURRENT_ASSETS': rowStyleMap.whiteOnBlack,
52
+ 'TOTAL_CURRENT_LIABILITIES': rowStyleMap.whiteOnBlack,
53
+ 'LONG_TERM_LIABILITIES': rowStyleMap.whiteOnBlack,
54
+ 'TOTAL_CURRENT_ASSET': rowStyleMap.whiteOnBlack,
55
+ 'TOTAL_ASSETS': rowStyleMap.whiteOnBlack,
56
+ 'TOTAL_LIABILITIES': rowStyleMap.whiteOnBlack,
57
+ };
58
+
59
+ export class FinancialSpreadingService {
60
+
61
+ constructor(
62
+ private readonly uploadsService: UploadsService,
63
+ ) {
64
+ }
65
+
66
+ clearData(rawData: IFinancialSpreading[], rawSheets: IFinancialSpreadingSheet[]) {
67
+ const data = rawDataToDTO<FinancialSpreadingDTO, IFinancialSpreading>(FinancialSpreadingDTO, rawData);
68
+ const sheets = rawDataToDTO<FinancialSpreadingSheetDTO, IFinancialSpreadingSheet>(FinancialSpreadingSheetDTO, rawSheets);
69
+ return { data, sheets };
70
+ }
71
+
72
+ async getLastMonth(borrowerId: string): Promise<ISelectedMonth> {
73
+ const lastMonthData = await FinancialSpreading.aggregate<IFinancialSpreading>([
74
+ {
75
+ $match: { 'borrowerId': new mongoose.Types.ObjectId(borrowerId) },
76
+ }, {
77
+ $sort: { 'year': -1, 'month': -1 },
78
+ }, {
79
+ $limit: 1,
80
+ },
81
+ ]);
82
+ if (lastMonthData.length === 0) {
83
+ return { year: 2024, month: 6 };
84
+ }
85
+ return getShiftedMonth(lastMonthData[0], 1);
86
+ }
87
+
88
+ async addNewMonth(params: IFinancialSpreadingParams) {
89
+ const newMonth = await this.getLastMonth(params.borrowerId);
90
+ await Promise.all([EFinancialSpreadingType.PROFIT_LOSS, EFinancialSpreadingType.BALANCE_SHEET].map(async (type) => {
91
+ const allSheets = await this.getCreateAllBorrowerSheet({ ...params, financialSpreadingType: type });
92
+ await Promise.all(allSheets.map(async (sheet) => {
93
+ const modelInstance = new FinancialSpreading({
94
+ borrowerId: params.borrowerId,
95
+ amount: 0,
96
+ sheetId: sheet._id, ...newMonth,
97
+ });
98
+ await modelInstance.save();
99
+ }));
100
+ }));
101
+ return newMonth;
102
+ }
103
+
104
+ async clearMonth(params: IFinancialSpreadingParams) {
105
+ const monthAllSpreading = await FinancialSpreading.find({
106
+ borrowerId: params.borrowerId,
107
+ month: params.selectedMonth.month,
108
+ year: params.selectedMonth.year,
109
+ });
110
+ await Promise.all(monthAllSpreading.map(async (spreading) => {
111
+ spreading.amount = 0;
112
+ await spreading.save();
113
+ }));
114
+ const selectedMonth: ISelectedMonth = { ...params.selectedMonth };
115
+ return selectedMonth;
116
+ }
117
+
118
+ async resetAll(params: IFinancialSpreadingParams) {
119
+ await FinancialSpreading.deleteMany({ borrowerId: params.borrowerId });
120
+ await FinancialSpreadingSheet.deleteMany({ borrowerId: params.borrowerId });
121
+ const selectedMonth: ISelectedMonth = { ...params.selectedMonth };
122
+ return selectedMonth;
123
+ }
124
+
125
+ async resetSheets() {
126
+ await FinancialSpreadingSheet.deleteMany({});
127
+ await FinancialSpreading.deleteMany({});
128
+ }
129
+
130
+ async getFinancialSpreadingData(params: IFinancialSpreadingParams, monthDeep = 3) {
131
+ const validationRes = financialSpreadingParamsValidationSchema.validate(params);
132
+ if (validationRes.error) {
133
+ console.error(validationRes.error);
134
+ return { data: [], sheets: [] };
135
+ }
136
+ const range = Array.from({ length: monthDeep }, (_, i) => i + 1);
137
+ const shifts = range.reduce((acc, curr) => {
138
+ acc[`minus_${curr}`] = -curr;
139
+ return acc;
140
+ }, { 'amount': 0 });
141
+ const rawSheets = await this.getCreateAllBorrowerSheet(params);
142
+ const rawData = await Promise.all(rawSheets.map(async (sheet) => {
143
+ const combinedData: IFinancialSpreadingView = {
144
+ _id: '',
145
+ borrowerId: params.borrowerId,
146
+ sheetId: sheet._id.toString(),
147
+ year: params.selectedMonth.year,
148
+ month: params.selectedMonth.month,
149
+ amount: 0,
150
+ minus_1: 0,
151
+ minus_2: 0,
152
+ minus_3: 0,
153
+ };
154
+ await Promise.all(Object.entries(shifts).map(async ([shiftName, shiftValue]) => {
155
+ const filter = {
156
+ borrowerId: params.borrowerId,
157
+ sheetId: sheet._id,
158
+ ...getShiftedMonth(params.selectedMonth, shiftValue),
159
+ };
160
+ const foundData = await FinancialSpreading.findOne(filter).lean();
161
+ if (shiftValue === 0) {
162
+ combinedData._id = foundData ? foundData._id.toString() : `new_${sheet._id}`;
163
+ }
164
+ combinedData[shiftName] = foundData ? foundData.amount : 0;
165
+ }));
166
+ return combinedData as unknown as IFinancialSpreading;
167
+ }));
168
+ return this.clearData(rawData, rawSheets);
169
+ }
170
+
171
+ async updateFinancialSpreadingData(params: IFinancialSpreadingParams, data: IFinancialSpreadingView[], sheets: IFinancialSpreadingSheetView[]) {
172
+ const warnings: string[] = [];
173
+
174
+ const editableSheets = sheets.filter((sheet) => !sheet.isTotal);
175
+ const editableSheetIds = editableSheets.map((sheet) => sheet._id);
176
+ const sheetsValidationResult = Joi.array().items(financialSpreadingSheetViewValidationSchema).validate(editableSheets, { abortEarly: false });
177
+ if (sheetsValidationResult.error) {
178
+ return { success: false, data, sheets, message: 'Invalid sheets' };
179
+ }
180
+
181
+ if (params.financialSpreadingType === EFinancialSpreadingType.BALANCE_SHEET) {
182
+ const totals: { [totalType: string]: number } = {};
183
+ await Promise.all(editableSheets.map(async (sheet) => {
184
+ const foundData = data.find((dataRow) => dataRow.sheetId === sheet._id);
185
+ if (totals[sheet.rowType]) {
186
+ totals[sheet.rowType] = new Decimal(totals[sheet.rowType]).add(foundData.amount).toNumber();
187
+ } else {
188
+ totals[sheet.rowType] = foundData.amount;
189
+ }
190
+ }));
191
+ const calculatedTotals = this.calculateBS(totals);
192
+ if (calculatedTotals[EFinanceSpreadingBSTotal.CHECK] !== 0) {
193
+ warnings.push('Check must be equal 0');
194
+ }
195
+ }
196
+
197
+ const originalSheets = await FinancialSpreadingSheet.find({
198
+ borrowerId: params.borrowerId,
199
+ isTotal: false,
200
+ financialSpreadingType: params.financialSpreadingType,
201
+ });
202
+ const redundantSheetIdSet = new Set(originalSheets.map((sheet) => sheet._id.toString()));
203
+
204
+ const sheetMap: { [viewSheetId: string]: string } = {};
205
+ await Promise.all(editableSheets.map(async (sheet) => {
206
+ if (sheet._id.includes('new_')) {
207
+ const newSheet = await this.createNewSheet(sheet);
208
+ sheetMap[sheet._id] = newSheet._id.toString();
209
+ } else {
210
+ redundantSheetIdSet.delete(sheet._id);
211
+ await FinancialSpreadingSheet
212
+ .findByIdAndUpdate(sheet._id, {
213
+ name: sheet.name,
214
+ order: sheet.order,
215
+ suborder: sheet.suborder,
216
+ rowType: sheet.rowType,
217
+ }, { new: true })
218
+ .lean();
219
+ }
220
+ }));
221
+
222
+ const editableData = data.filter((dataRow) => editableSheetIds.includes(dataRow.sheetId));
223
+ const validationResult = Joi.array().items(financialSpreadingViewValidationSchema).validate(editableData, { abortEarly: false });
224
+ if (validationResult.error) {
225
+ console.error(validationResult.error);
226
+ return { success: false, data, sheets, message: 'Invalid data' };
227
+ }
228
+ await Promise.all(editableData.map(async item => {
229
+ const { _id, ...rest } = item;
230
+ if (_id.includes('new_')) {
231
+ if (rest.sheetId.includes('new_')) {
232
+ rest.sheetId = sheetMap[rest.sheetId];
233
+ }
234
+ await FinancialSpreading
235
+ .findOneAndUpdate(
236
+ { borrowerId: rest.borrowerId, year: rest.year, month: rest.month, sheetId: rest.sheetId },
237
+ { amount: rest.amount },
238
+ { new: true, upsert: true },
239
+ );
240
+ } else {
241
+ await FinancialSpreading
242
+ .findByIdAndUpdate(
243
+ _id,
244
+ rest,
245
+ { new: true, upsert: true },
246
+ );
247
+ }
248
+ }));
249
+ await this.deleteRedundantSheets(Array.from(redundantSheetIdSet));
250
+ await this.calculateTotals(params);
251
+ const warningsString = warnings.length > 0 ? `Data saved but has errors: ${warnings.join(', ')}` : '';
252
+ return { success: true, message: warningsString };
253
+ }
254
+
255
+ async calculateTotals(params: IFinancialSpreadingParams) {
256
+ const allSheets = await this.getAllBorrowerSheets(params);
257
+ const totalSheets = allSheets.filter((sheet) => sheet.isTotal);
258
+ const rowSheets = allSheets.filter((sheet) => !sheet.isTotal);
259
+ const totals: { [totalType: string]: number } = {};
260
+ await Promise.all(totalSheets.map(async (totalSheet) => {
261
+ const sumRows = rowSheets.filter((simpleSheet) => simpleSheet.rowType === totalSheet.rowType);
262
+ const data = await FinancialSpreading.find({
263
+ borrowerId: params.borrowerId,
264
+ year: params.selectedMonth.year,
265
+ month: params.selectedMonth.month,
266
+ sheetId: { $in: sumRows.map((row) => row._id) },
267
+ }).lean();
268
+ const totalAmount = data.reduce((acc, d) => new Decimal(acc).add(d.amount).toNumber(), 0);
269
+ await FinancialSpreading.findOneAndUpdate({
270
+ borrowerId: params.borrowerId,
271
+ year: params.selectedMonth.year,
272
+ month: params.selectedMonth.month,
273
+ sheetId: totalSheet._id,
274
+ }, { amount: totalAmount });
275
+ totals[totalSheet.rowType] = totalAmount;
276
+ }));
277
+
278
+ const calculationMap = {
279
+ [EFinancialSpreadingType.PROFIT_LOSS]: this.calculatePL,
280
+ [EFinancialSpreadingType.BALANCE_SHEET]: this.calculateBS,
281
+ };
282
+
283
+ const updatedCalculation = calculationMap[params.financialSpreadingType](totals);
284
+
285
+ await Promise.all(totalSheets.map(async (sheet) => {
286
+ await FinancialSpreading.findOneAndUpdate({
287
+ borrowerId: params.borrowerId,
288
+ year: params.selectedMonth.year,
289
+ month: params.selectedMonth.month,
290
+ sheetId: sheet._id,
291
+ },
292
+ { amount: updatedCalculation[sheet.rowType] },
293
+ { upsert: true },
294
+ );
295
+ }));
296
+ }
297
+
298
+ private calculatePL(totals: { [totalType: string]: number }) {
299
+ totals[EFinanceSpreadingPLTotal.GROSS_PROFIT] = new Decimal(totals[EFinanceSpreadingPLTotal.SALES]).sub(totals[EFinanceSpreadingPLTotal.COST_OF_SALES]).toNumber();
300
+ totals[EFinanceSpreadingPLTotal.GROSS_MARGIN] = totals[EFinanceSpreadingPLTotal.SALES] === 0
301
+ ? 0
302
+ : new Decimal(totals[EFinanceSpreadingPLTotal.GROSS_PROFIT]).div(totals[EFinanceSpreadingPLTotal.SALES]).mul(100).toDecimalPlaces(2).toNumber();
303
+ totals[EFinanceSpreadingPLTotal.INCOME_FROM_OPERATIONS] = new Decimal(totals[EFinanceSpreadingPLTotal.GROSS_PROFIT]).sub(totals[EFinanceSpreadingPLTotal.OPERATING_EXPENSES]).toNumber();
304
+ totals[EFinanceSpreadingPLTotal.OPERATING_MARGIN] = totals[EFinanceSpreadingPLTotal.SALES] === 0
305
+ ? 0
306
+ : new Decimal(totals[EFinanceSpreadingPLTotal.INCOME_FROM_OPERATIONS]).div(totals[EFinanceSpreadingPLTotal.SALES]).toDecimalPlaces(2).toNumber();
307
+ totals[EFinanceSpreadingPLTotal.PRE_TAX_INCOME] = new Decimal(totals[EFinanceSpreadingPLTotal.INCOME_FROM_OPERATIONS])
308
+ .sub(totals[EFinanceSpreadingPLTotal.NON_OPERATING_EXPENSES])
309
+ .add(totals[EFinanceSpreadingPLTotal.NON_OPERATING_INCOME])
310
+ .sub(totals[EFinanceSpreadingPLTotal.FINANCING_COSTS])
311
+ .sub(totals[EFinanceSpreadingPLTotal.DEPRECIATION_AMORTIZATION])
312
+ .toNumber();
313
+ totals[EFinanceSpreadingPLTotal.NET_INCOME] = new Decimal(totals[EFinanceSpreadingPLTotal.PRE_TAX_INCOME]).sub(totals[EFinanceSpreadingPLTotal.TAX]).toNumber();
314
+ return totals;
315
+ }
316
+
317
+ private calculateBS(totals: { [totalType: string]: number }) {
318
+ totals[EFinanceSpreadingBSTotal.TOTAL_CURRENT_ASSET] = new Decimal(totals[EFinanceSpreadingBSTotal.CASH_EQUIVALENTS])
319
+ .add(totals[EFinanceSpreadingBSTotal.TRADE_RECEIVABLES])
320
+ .add(totals[EFinanceSpreadingBSTotal.INVENTORY])
321
+ .add(totals[EFinanceSpreadingBSTotal.OTHER_CURRENT_ASSETS])
322
+ .toNumber();
323
+ totals[EFinanceSpreadingBSTotal.TOTAL_NON_CURRENT_ASSETS] = new Decimal(totals[EFinanceSpreadingBSTotal.FIXED_ASSETS])
324
+ .add(totals[EFinanceSpreadingBSTotal.OTHER_NON_CURRENT_ASSETS])
325
+ .toNumber();
326
+ totals[EFinanceSpreadingBSTotal.TOTAL_ASSETS] = new Decimal(totals[EFinanceSpreadingBSTotal.TOTAL_CURRENT_ASSET])
327
+ .add(totals[EFinanceSpreadingBSTotal.TOTAL_NON_CURRENT_ASSETS])
328
+ .toNumber();
329
+ totals[EFinanceSpreadingBSTotal.TOTAL_CURRENT_LIABILITIES] = new Decimal(totals[EFinanceSpreadingBSTotal.ACCOUNTS_PAYABLE])
330
+ .add(totals[EFinanceSpreadingBSTotal.OTHER_CURRENT_LIABILITIES])
331
+ .toNumber();
332
+ totals[EFinanceSpreadingBSTotal.LONG_TERM_LIABILITIES] = new Decimal(totals[EFinanceSpreadingBSTotal.COMPANY_DEBT])
333
+ .add(totals[EFinanceSpreadingBSTotal.OTHER_DEBT])
334
+ .add(totals[EFinanceSpreadingBSTotal.OTHER_LONG_TERM_LIABILITIES])
335
+ .toNumber();
336
+ totals[EFinanceSpreadingBSTotal.TOTAL_LIABILITIES] = new Decimal(totals[EFinanceSpreadingBSTotal.TOTAL_CURRENT_LIABILITIES])
337
+ .add(totals[EFinanceSpreadingBSTotal.LONG_TERM_LIABILITIES])
338
+ .toNumber();
339
+ const preCheck = new Decimal(totals[EFinanceSpreadingBSTotal.RETAINED_EARNINGS])
340
+ .add(totals[EFinanceSpreadingBSTotal.EQUITY_RESERVES])
341
+ .toNumber();
342
+ totals[EFinanceSpreadingBSTotal.CHECK] = new Decimal(totals[EFinanceSpreadingBSTotal.TOTAL_ASSETS])
343
+ .sub(totals[EFinanceSpreadingBSTotal.TOTAL_LIABILITIES])
344
+ .sub(preCheck)
345
+ .toNumber();
346
+ return totals;
347
+ }
348
+
349
+ async createNewSheet(sheet: IFinancialSpreadingSheetView) {
350
+ const allDates = await FinancialSpreading.aggregate([
351
+ { $match: { borrowerId: new mongoose.Types.ObjectId(sheet.borrowerId) } },
352
+ { $group: { _id: { year: '$year', month: '$month' } } },
353
+ ]);
354
+ const totalSheet = await FinancialSpreadingSheet.findOne({
355
+ 'borrowerId': new mongoose.Types.ObjectId(sheet.borrowerId),
356
+ 'financialSpreadingType': sheet.financialSpreadingType,
357
+ 'rowType': sheet.rowType,
358
+ 'isTotal': true,
359
+ }).lean();
360
+ const lastSheets = await FinancialSpreadingSheet.aggregate<IFinancialSpreadingSheet>([
361
+ {
362
+ $match: {
363
+ 'borrowerId': new mongoose.Types.ObjectId(sheet.borrowerId),
364
+ 'financialSpreadingType': sheet.financialSpreadingType,
365
+ 'rowType': sheet.rowType,
366
+ 'isTotal': false,
367
+ },
368
+ },
369
+ ]);
370
+ const order = totalSheet.order;
371
+ const suborder = lastSheets.length;
372
+ const uniqueDates: { year: number, month: number }[] = allDates.map((r) => r._id);
373
+ const { _id, ...rest } = sheet;
374
+ const newSheet = new FinancialSpreadingSheet({ ...rest, order, suborder });
375
+ const newSheetData = await newSheet.save();
376
+ await Promise.all(uniqueDates.map(async (uniqueDate) => {
377
+ const newFinanceSpreading = new FinancialSpreading({
378
+ sheetId: newSheetData._id,
379
+ borrowerId: sheet.borrowerId,
380
+ amount: 0,
381
+ ...uniqueDate,
382
+ });
383
+ await newFinanceSpreading.save();
384
+ }));
385
+ return newSheetData;
386
+ }
387
+
388
+ async deleteRedundantSheets(sheetIds: string[]) {
389
+ await FinancialSpreading.deleteMany({ sheetId: { $in: sheetIds.map((id) => new mongoose.Types.ObjectId(id)) } });
390
+ await FinancialSpreadingSheet.deleteMany({ _id: { $in: sheetIds.map((id) => new mongoose.Types.ObjectId(id)) } });
391
+ }
392
+
393
+ private async getAllBorrowerSheets(params: IFinancialSpreadingParams) {
394
+ const allSheets = await FinancialSpreadingSheet.find({
395
+ borrowerId: params.borrowerId,
396
+ financialSpreadingType: params.financialSpreadingType,
397
+ }).lean();
398
+ return _.sortBy(allSheets, ['order', 'isTotal', 'suborder']);
399
+ }
400
+
401
+ async getCreateAllBorrowerSheet(params: IFinancialSpreadingParams) {
402
+ const allSheets = await this.getAllBorrowerSheets(params);
403
+ if (allSheets.length) {
404
+ return allSheets;
405
+ }
406
+ const totalsMap = {
407
+ [EFinancialSpreadingType.PROFIT_LOSS]: EFinanceSpreadingPLTotal,
408
+ [EFinancialSpreadingType.BALANCE_SHEET]: EFinanceSpreadingBSTotal,
409
+ };
410
+ await Promise.all(Object.entries(financeSpreadingLists[params.financialSpreadingType]).map(async ([totalKey, isCalculated], order) => {
411
+ const newPartialRow: Omit<IFinancialSpreadingSheet, 'isTotal'> = {
412
+ borrowerId: new mongoose.Types.ObjectId(params.borrowerId),
413
+ financialSpreadingType: params.financialSpreadingType,
414
+ name: financialSpreadingTotalDictionary[totalKey],
415
+ rowType: totalsMap[params.financialSpreadingType][totalKey],
416
+ isCalculated,
417
+ order,
418
+ suborder: 0,
419
+ };
420
+ if (!isCalculated) {
421
+ const newRow: IFinancialSpreadingSheet = {
422
+ ...newPartialRow,
423
+ name: financialSpreadingTotalDictionary[totalKey].toLowerCase(),
424
+ isTotal: false,
425
+ };
426
+ const newRowItem = new FinancialSpreadingSheet(newRow);
427
+ await newRowItem.save();
428
+ }
429
+ const newTotalRow: IFinancialSpreadingSheet = {
430
+ ...newPartialRow,
431
+ isTotal: true,
432
+ };
433
+ const newTotalRowItem = new FinancialSpreadingSheet(newTotalRow);
434
+ await newTotalRowItem.save();
435
+ }));
436
+ return this.getAllBorrowerSheets(params);
437
+ }
438
+
439
+ async getExcelFile(params: IFinancialSpreadingParams) {
440
+ const monthDeep = 11;
441
+
442
+ const fullData = {
443
+ [EFinancialSpreadingType.PROFIT_LOSS]: [],
444
+ [EFinancialSpreadingType.BALANCE_SHEET]: [],
445
+ };
446
+
447
+ const range = Array.from({ length: monthDeep }, (_, i) => i + 1).reverse();
448
+ const oldMonths = range.reduce((acc, shiftValue) => [...acc, getShiftedMonth(params.selectedMonth, -shiftValue)], []);
449
+ const monthsHeader = [...oldMonths, params.selectedMonth].map((month) => dayjs(new Date(month.year, month.month)).utcOffset(0).format('MM/YYYY'));
450
+ const headers = ['', '', ...monthsHeader];
451
+ const fullHeaders = headers.map((header) => (<IExcelDataCellWithStyles>{
452
+ v: header,
453
+ s: { font: { bold: true } },
454
+ }));
455
+
456
+ await Promise.all([EFinancialSpreadingType.PROFIT_LOSS, EFinancialSpreadingType.BALANCE_SHEET].map(async (financialSpreadingType) => {
457
+ const financialSpreadingData = await this.getFinancialSpreadingData(
458
+ { ...params, financialSpreadingType },
459
+ monthDeep,
460
+ );
461
+
462
+ const sheetsView = financialSpreadingData.sheets as unknown[] as IFinancialSpreadingSheetView[];
463
+ const someData = (financialSpreadingData.data as unknown as IFinancialSpreadingViewWithDeepData[]).reduce((acc, rowData) => {
464
+ const foundSheet = sheetsView.find((sheet) => sheet._id === rowData.sheetId);
465
+ const oldData = range.reduce((acc, rangeValue) => [...acc, rowData[`minus_${rangeValue}`]], []);
466
+ const totalStyle = foundSheet.isTotal ? rowStyles[foundSheet.rowType] ?? {} : {};
467
+ const row: IExcelDataCellWithStyles[] = [
468
+ { v: foundSheet.isTotal ? foundSheet.name : '', s: { font: { bold: true } } },
469
+ { v: foundSheet.isTotal ? '' : foundSheet.name, s: { font: { italic: true } } },
470
+ ...oldData.map((data) => ({ v: data, t: 'n' })),
471
+ { v: rowData.amount, t: 'n' },
472
+ ];
473
+ const rowWithStyles = row.map((cell) => ({ ...cell, s: _.merge(cell.s, totalStyle) }));
474
+ return [...acc, rowWithStyles];
475
+ }, []);
476
+ fullData[financialSpreadingType] = [fullHeaders, ...someData];
477
+ }));
478
+
479
+ return await this.uploadsService.convertDataToFileWithStyleOld({
480
+ 'PROFIT LOSS': fullData[EFinancialSpreadingType.PROFIT_LOSS],
481
+ 'BALANCE SHEET': fullData[EFinancialSpreadingType.BALANCE_SHEET],
482
+ }, { width: { 'PROFIT LOSS': { 'A': 5 }, 'BALANCE SHEET': { 'A': 5 } } });
483
+ }
484
+
485
+ async uploadData(data: IFinancialSpreadingUpload[], params: IFinancialSpreadingParams) {
486
+ await Promise.all(data.map(async (item) => {
487
+ const { _id, ...rest } = item;
488
+ if (item.sheetId.includes('new_')) {
489
+ const sheet: IFinancialSpreadingSheetView = {
490
+ _id: null,
491
+ borrowerId: params.borrowerId,
492
+ financialSpreadingType: params.financialSpreadingType,
493
+ isCalculated: false,
494
+ isTotal: false,
495
+ name: item.title,
496
+ order: 0,
497
+ rowType: item.sheetType,
498
+ suborder: 0,
499
+ };
500
+ const newSheet = await this.createNewSheet(sheet);
501
+ rest.sheetId = newSheet._id.toString();
502
+ }
503
+ await FinancialSpreading
504
+ .findOneAndUpdate(
505
+ {
506
+ borrowerId: params.borrowerId,
507
+ year: params.selectedMonth.year,
508
+ month: params.selectedMonth.month,
509
+ sheetId: rest.sheetId,
510
+ },
511
+ { amount: rest.amount },
512
+ { upsert: true },
513
+ );
514
+ }));
515
+ await this.calculateTotals(params);
516
+ }
517
+ }
@@ -0,0 +1,5 @@
1
+ export declare class GlobalsService {
2
+ getGlobalSetting(settingName: string): Promise<{
3
+ [x: string]: any;
4
+ }>;
5
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GlobalsService = void 0;
4
+ const globals_repository_1 = require("../repositories/globals.repository");
5
+ class GlobalsService {
6
+ async getGlobalSetting(settingName) {
7
+ const globalsRepository = new globals_repository_1.GlobalsRepository();
8
+ return await globalsRepository.getSetting(settingName);
9
+ }
10
+ }
11
+ exports.GlobalsService = GlobalsService;
@@ -0,0 +1,8 @@
1
+ import { GlobalsRepository } from '../repositories/globals.repository';
2
+
3
+ export class GlobalsService {
4
+ async getGlobalSetting(settingName: string) {
5
+ const globalsRepository: GlobalsRepository = new GlobalsRepository();
6
+ return await globalsRepository.getSetting(settingName);
7
+ }
8
+ }
@@ -0,0 +1,39 @@
1
+ /// <reference types="mongoose/types/aggregate" />
2
+ /// <reference types="mongoose/types/callback" />
3
+ /// <reference types="mongoose/types/collection" />
4
+ /// <reference types="mongoose/types/connection" />
5
+ /// <reference types="mongoose/types/cursor" />
6
+ /// <reference types="mongoose/types/document" />
7
+ /// <reference types="mongoose/types/error" />
8
+ /// <reference types="mongoose/types/expressions" />
9
+ /// <reference types="mongoose/types/helpers" />
10
+ /// <reference types="mongoose/types/middlewares" />
11
+ /// <reference types="mongoose/types/indexes" />
12
+ /// <reference types="mongoose/types/models" />
13
+ /// <reference types="mongoose/types/mongooseoptions" />
14
+ /// <reference types="mongoose/types/pipelinestage" />
15
+ /// <reference types="mongoose/types/populate" />
16
+ /// <reference types="mongoose/types/query" />
17
+ /// <reference types="mongoose/types/schemaoptions" />
18
+ /// <reference types="mongoose/types/schematypes" />
19
+ /// <reference types="mongoose/types/session" />
20
+ /// <reference types="mongoose/types/types" />
21
+ /// <reference types="mongoose/types/utility" />
22
+ /// <reference types="mongoose/types/validation" />
23
+ /// <reference types="mongoose/types/virtuals" />
24
+ /// <reference types="mongoose" />
25
+ /// <reference types="mongoose/types/inferschematype" />
26
+ import { IBorrowerGroupWithId } from '../interfaces/group.interface';
27
+ import { IMappedGroup } from '../models/MappedGroup.model';
28
+ export declare class GroupsService {
29
+ createBorrowerGroups(borrowerId: string, groupType: string, groups: IBorrowerGroupWithId[]): Promise<void>;
30
+ getBorrowerGroups(borrowerId: string, relationshipGroups: string | string[]): Promise<{
31
+ [x: string]: any;
32
+ }>;
33
+ createMappedGroups(borrowerId: string, groupType: string, groups: IMappedGroup[]): Promise<void>;
34
+ getMappedGroups(borrowerId: string, groupTypes: string | string[]): Promise<{
35
+ [x: string]: (import("mongoose").Document<unknown, {}, import("../models/MappedGroup.model").IMappedGroupDocument> & import("../models/MappedGroup.model").IMappedGroupDocument & {
36
+ _id: import("mongoose").Types.ObjectId;
37
+ })[];
38
+ }>;
39
+ }
@@ -0,0 +1,65 @@
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.GroupsService = void 0;
7
+ const groups_db_1 = require("../db/groups.db");
8
+ const MappedGroup_model_1 = __importDefault(require("../models/MappedGroup.model"));
9
+ class GroupsService {
10
+ async createBorrowerGroups(borrowerId, groupType, groups) {
11
+ const groupIds = groups.map((group) => group._id);
12
+ const allExistedGroups = await groups_db_1.groupsMap[groupType].Model.find({ borrowerId }).lean();
13
+ await Promise.all(allExistedGroups.map(async (group) => {
14
+ if (!groupIds.includes(group.id)) {
15
+ await groups_db_1.groupsMap[groupType].Model.findByIdAndDelete(group.id);
16
+ }
17
+ }));
18
+ await Promise.all(groups.map(async (group) => {
19
+ if (!group._id) {
20
+ const newGroup = new groups_db_1.groupsMap[groupType].Model(group);
21
+ await newGroup.save();
22
+ }
23
+ else {
24
+ await groups_db_1.groupsMap[groupType].Model.findByIdAndUpdate(group._id, group);
25
+ }
26
+ }));
27
+ }
28
+ async getBorrowerGroups(borrowerId, relationshipGroups) {
29
+ if (typeof relationshipGroups == 'string') {
30
+ relationshipGroups = [relationshipGroups];
31
+ }
32
+ const allCustomerGroups = await Promise.all(relationshipGroups.map(async (groupName) => {
33
+ const groups = await groups_db_1.groupsMap[groupName].Model.find({ borrowerId }).sort({ 'createdAt': 1 });
34
+ return { [groupName]: groups };
35
+ }));
36
+ return allCustomerGroups.reduce((acc, group) => {
37
+ return { ...acc, ...group };
38
+ }, {});
39
+ }
40
+ async createMappedGroups(borrowerId, groupType, groups) {
41
+ await MappedGroup_model_1.default.deleteMany({ borrowerId, groupType });
42
+ await Promise.all(groups.map(async (group) => {
43
+ const newMappedGroup = new MappedGroup_model_1.default({
44
+ borrowerId,
45
+ group1: group.group1,
46
+ group2: group.group2,
47
+ groupType: groupType,
48
+ });
49
+ await newMappedGroup.save();
50
+ }));
51
+ }
52
+ async getMappedGroups(borrowerId, groupTypes) {
53
+ if (typeof groupTypes == 'string') {
54
+ groupTypes = [groupTypes];
55
+ }
56
+ const allMappedGroups = await Promise.all(groupTypes.map(async (groupType) => {
57
+ const groups = await MappedGroup_model_1.default.find({ borrowerId, groupType });
58
+ return { [groupType]: groups };
59
+ }));
60
+ return allMappedGroups.reduce((acc, group) => {
61
+ return { ...acc, ...group };
62
+ }, {});
63
+ }
64
+ }
65
+ exports.GroupsService = GroupsService;