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