@zeniai/client-epic-state 4.19.97 → 4.19.99-beta0ND

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 (251) hide show
  1. package/lib/commonStateTypes/animations.d.ts +1 -1
  2. package/lib/commonStateTypes/coaBalance/coaBalanceType.d.ts +2 -0
  3. package/lib/commonStateTypes/coaBalance/coaBalanceType.js +6 -0
  4. package/lib/commonStateTypes/currencyHelper.d.ts +3 -0
  5. package/lib/commonStateTypes/currencyHelper.js +6 -1
  6. package/lib/commonStateTypes/reduceFetchState.d.ts +9 -0
  7. package/lib/commonStateTypes/reduceFetchState.js +26 -0
  8. package/lib/entity/account/accountPayload.d.ts +2 -0
  9. package/lib/entity/account/accountPayload.js +2 -0
  10. package/lib/entity/account/accountState.d.ts +2 -0
  11. package/lib/entity/aiCfo/aiCfoSelector.d.ts +1 -2
  12. package/lib/entity/billPay/billTransaction/billTransactionState.d.ts +2 -2
  13. package/lib/entity/customer/customerState.d.ts +0 -2
  14. package/lib/entity/customer/customerState.js +0 -5
  15. package/lib/entity/depositAccount/depositAccount.d.ts +1 -1
  16. package/lib/entity/depositAccount/depositAccount.js +8 -1
  17. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +35 -0
  18. package/lib/entity/jeSchedules/jeSchedulesPayload.js +44 -0
  19. package/lib/entity/jeSchedules/jeSchedulesSelector.d.ts +2 -1
  20. package/lib/entity/jeSchedules/jeSchedulesSelector.js +2 -1
  21. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +13 -0
  22. package/lib/entity/reimbursement/reimbursementPayload.d.ts +2 -0
  23. package/lib/entity/reimbursement/reimbursementPayload.js +7 -0
  24. package/lib/entity/reimbursement/reimbursementState.d.ts +2 -0
  25. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  26. package/lib/entity/snackbar/snackbarTypes.js +1 -0
  27. package/lib/entity/task/taskPayload.d.ts +1 -0
  28. package/lib/entity/task/taskPayload.js +1 -0
  29. package/lib/entity/task/taskState.d.ts +1 -0
  30. package/lib/entity/tenant/tenantPayload.d.ts +1 -0
  31. package/lib/entity/tenant/tenantReducer.js +1 -0
  32. package/lib/entity/tenant/tenantSelector.d.ts +1 -0
  33. package/lib/entity/tenant/tenantSelector.js +9 -1
  34. package/lib/entity/tenant/tenantState.d.ts +1 -0
  35. package/lib/entity/transaction/payloadTypes/transactionPayload.d.ts +3 -0
  36. package/lib/entity/transaction/payloadTypes/transactionPayload.js +11 -0
  37. package/lib/entity/transaction/stateTypes/transaction.d.ts +3 -0
  38. package/lib/entity/transaction/stateTypes/transactionLine.d.ts +1 -1
  39. package/lib/entity/userGroups/userGroupsPayload.d.ts +7 -0
  40. package/lib/entity/userGroups/userGroupsPayload.js +10 -0
  41. package/lib/entity/userGroups/userGroupsReducer.d.ts +8 -0
  42. package/lib/entity/userGroups/userGroupsReducer.js +29 -0
  43. package/lib/entity/userGroups/userGroupsSelector.d.ts +4 -0
  44. package/lib/entity/userGroups/userGroupsSelector.js +12 -0
  45. package/lib/entity/userGroups/userGroupsState.d.ts +9 -0
  46. package/lib/entity/userGroups/userGroupsState.js +2 -0
  47. package/lib/epic.d.ts +13 -1
  48. package/lib/epic.js +13 -1
  49. package/lib/esm/commonStateTypes/coaBalance/coaBalanceType.js +5 -0
  50. package/lib/esm/commonStateTypes/currencyHelper.js +5 -0
  51. package/lib/esm/commonStateTypes/reduceFetchState.js +25 -0
  52. package/lib/esm/entity/account/accountPayload.js +2 -0
  53. package/lib/esm/entity/customer/customerState.js +1 -4
  54. package/lib/esm/entity/depositAccount/depositAccount.js +8 -1
  55. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +44 -0
  56. package/lib/esm/entity/jeSchedules/jeSchedulesSelector.js +2 -1
  57. package/lib/esm/entity/reimbursement/reimbursementPayload.js +7 -0
  58. package/lib/esm/entity/snackbar/snackbarTypes.js +1 -0
  59. package/lib/esm/entity/task/taskPayload.js +1 -0
  60. package/lib/esm/entity/tenant/tenantReducer.js +1 -0
  61. package/lib/esm/entity/tenant/tenantSelector.js +7 -0
  62. package/lib/esm/entity/transaction/payloadTypes/transactionPayload.js +11 -0
  63. package/lib/esm/entity/userGroups/userGroupsPayload.js +7 -0
  64. package/lib/esm/entity/userGroups/userGroupsReducer.js +25 -0
  65. package/lib/esm/entity/userGroups/userGroupsSelector.js +8 -0
  66. package/lib/esm/entity/userGroups/userGroupsState.js +1 -0
  67. package/lib/esm/epic.js +13 -1
  68. package/lib/esm/index.js +25 -16
  69. package/lib/esm/reducer.js +6 -0
  70. package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +82 -1
  71. package/lib/esm/view/aiCfoView/aiCfoViewSelector.js +8 -2
  72. package/lib/esm/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.js +29 -0
  73. package/lib/esm/view/arAgingView/arAgingReport/arAgingReducer.js +1 -1
  74. package/lib/esm/view/arAgingView/arAgingReport/arAgingSelector.js +1 -1
  75. package/lib/esm/view/classList/fetchClassListEpic.js +9 -2
  76. package/lib/esm/view/commonVendorView/vendorView/vendorViewSelector.js +18 -5
  77. package/lib/esm/view/commonVendorView/vendorsTabVendorView/vendorsTabVendorViewSelector.js +6 -2
  78. package/lib/esm/view/expenseAutomationView/bulkUploadTiming.js +10 -0
  79. package/lib/esm/view/expenseAutomationView/epics/accountRecon/saveReconciliationReviewEpic.js +8 -3
  80. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.js +29 -0
  81. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/confirmBulkUploadMatchEpic.js +49 -0
  82. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchDetailsEpic.js +40 -0
  83. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js +47 -0
  84. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +61 -0
  85. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchMoreBatchDetailsEpic.js +33 -0
  86. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.js +56 -0
  87. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +77 -0
  88. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/uploadMissingReceiptSuccessEpic.js +7 -5
  89. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +79 -0
  90. package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/uploadTransactionReceiptSuccessEpic.js +24 -0
  91. package/lib/esm/view/expenseAutomationView/helpers/saveTransactionHelper.js +2 -2
  92. package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +2 -2
  93. package/lib/esm/view/expenseAutomationView/payload/missingReceiptsPayload.js +189 -1
  94. package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +17 -1
  95. package/lib/esm/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +433 -2
  96. package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +23 -1
  97. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +50 -3
  98. package/lib/esm/view/expenseAutomationView/selectors/missingReceiptsSelector.js +245 -2
  99. package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +2 -1
  100. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +17 -1
  101. package/lib/esm/view/expenseAutomationView/types/missingReceiptsViewState.js +44 -0
  102. package/lib/esm/view/expenseAutomationView/types/transactionsViewState.js +2 -1
  103. package/lib/esm/view/financeStatement/financeStatementReducer.js +11 -8
  104. package/lib/esm/view/financeStatement/financeStatementSelector.js +24 -9
  105. package/lib/esm/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelector.js +322 -0
  106. package/lib/esm/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelectorTypes.js +9 -0
  107. package/lib/esm/view/profitAndLossClassesView/profitAndLossClassesViewReducer.js +6 -1
  108. package/lib/esm/view/profitAndLossClassesView/profitAndLossClassesViewSelector.js +2 -29
  109. package/lib/esm/view/profitAndLossClassesView/profitAndLossForTimeframeClassesViewEpic.js +7 -5
  110. package/lib/esm/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +201 -0
  111. package/lib/esm/view/reportUIOptions/updateReportUIOptionCOABalancesRangeEpic.js +9 -7
  112. package/lib/esm/view/spendManagement/billPay/billList/billListSelector.js +10 -0
  113. package/lib/esm/view/spendManagement/billPay/billList/billListState.js +1 -0
  114. package/lib/esm/view/spendManagement/billPay/billPayReview/billPayReviewSelector.js +7 -3
  115. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewSelector.js +5 -5
  116. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPayApproversDetailsEpic.js +7 -2
  117. package/lib/esm/view/spendManagement/billPay/editBillView/editBillViewSelector.js +13 -6
  118. package/lib/esm/view/spendManagement/chargeCards/chargeCardList/chargeCardList.js +1 -0
  119. package/lib/esm/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.js +2 -0
  120. package/lib/esm/view/spendManagement/reimbursement/editRemiView/editRemiViewSelector.js +7 -4
  121. package/lib/esm/view/spendManagement/reimbursement/remiListView/remiListSelector.js +12 -0
  122. package/lib/esm/view/spendManagement/reimbursement/remiListView/remiListState.js +1 -0
  123. package/lib/esm/view/taskManager/taskDetailView/taskDetailSelector.js +3 -3
  124. package/lib/esm/view/taskManager/taskListView/epics/bulkUpdateTaskListEpic.js +1 -0
  125. package/lib/esm/view/taskManager/taskListView/taskListSelector.js +3 -1
  126. package/lib/esm/view/transactionDetail/epics/saveTransactionHelper.js +2 -2
  127. package/lib/esm/view/transactionDetail/transactionDetailLocalDataHelper.js +16 -14
  128. package/lib/esm/view/userGroupListView/userGroupListViewReducer.js +65 -0
  129. package/lib/esm/view/userGroupListView/userGroupListViewSelector.js +16 -0
  130. package/lib/esm/view/userGroupListView/userGroupListViewState.js +1 -0
  131. package/lib/esm/view/userListView/fetchUserListByTypeEpic.js +11 -0
  132. package/lib/esm/zeniAPI.js +0 -2
  133. package/lib/index.d.ts +31 -21
  134. package/lib/index.js +102 -34
  135. package/lib/reducer.d.ts +6 -0
  136. package/lib/reducer.js +6 -0
  137. package/lib/tsconfig.typecheck.tsbuildinfo +1 -0
  138. package/lib/view/aiCfoView/aiCfoViewPayload.d.ts +7 -0
  139. package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +15 -1
  140. package/lib/view/aiCfoView/aiCfoViewReducer.js +83 -2
  141. package/lib/view/aiCfoView/aiCfoViewSelector.d.ts +4 -1
  142. package/lib/view/aiCfoView/aiCfoViewSelector.js +9 -2
  143. package/lib/view/aiCfoView/aiCfoViewState.d.ts +18 -1
  144. package/lib/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.d.ts +8 -0
  145. package/lib/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.js +33 -0
  146. package/lib/view/arAgingView/arAgingReport/arAgingReducer.js +2 -2
  147. package/lib/view/arAgingView/arAgingReport/arAgingSelector.js +5 -5
  148. package/lib/view/auditReportView/auditReportViewState.d.ts +1 -1
  149. package/lib/view/classList/fetchClassListEpic.d.ts +1 -1
  150. package/lib/view/classList/fetchClassListEpic.js +8 -1
  151. package/lib/view/commonVendorView/vendorView/vendorViewSelector.d.ts +1 -0
  152. package/lib/view/commonVendorView/vendorView/vendorViewSelector.js +18 -5
  153. package/lib/view/commonVendorView/vendorsTabVendorView/vendorsTabVendorViewSelector.d.ts +1 -0
  154. package/lib/view/commonVendorView/vendorsTabVendorView/vendorsTabVendorViewSelector.js +6 -2
  155. package/lib/view/expenseAutomationView/bulkUploadTiming.d.ts +10 -0
  156. package/lib/view/expenseAutomationView/bulkUploadTiming.js +13 -0
  157. package/lib/view/expenseAutomationView/epics/accountRecon/saveReconciliationReviewEpic.js +8 -3
  158. package/lib/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.d.ts +18 -0
  159. package/lib/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.js +33 -0
  160. package/lib/view/expenseAutomationView/epics/missingReceipts/confirmBulkUploadMatchEpic.d.ts +7 -0
  161. package/lib/view/expenseAutomationView/epics/missingReceipts/confirmBulkUploadMatchEpic.js +53 -0
  162. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchDetailsEpic.d.ts +8 -0
  163. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchDetailsEpic.js +44 -0
  164. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.d.ts +7 -0
  165. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js +51 -0
  166. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.d.ts +8 -0
  167. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +65 -0
  168. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMoreBatchDetailsEpic.d.ts +8 -0
  169. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMoreBatchDetailsEpic.js +37 -0
  170. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.d.ts +9 -0
  171. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.js +61 -0
  172. package/lib/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.d.ts +14 -0
  173. package/lib/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +81 -0
  174. package/lib/view/expenseAutomationView/epics/missingReceipts/uploadMissingReceiptSuccessEpic.js +7 -5
  175. package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.d.ts +25 -0
  176. package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +85 -0
  177. package/lib/view/expenseAutomationView/epics/transactionCategorization/uploadTransactionReceiptSuccessEpic.d.ts +7 -0
  178. package/lib/view/expenseAutomationView/epics/transactionCategorization/uploadTransactionReceiptSuccessEpic.js +28 -0
  179. package/lib/view/expenseAutomationView/helpers/saveTransactionHelper.js +2 -2
  180. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  181. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +2 -2
  182. package/lib/view/expenseAutomationView/payload/missingReceiptsPayload.d.ts +118 -0
  183. package/lib/view/expenseAutomationView/payload/missingReceiptsPayload.js +201 -0
  184. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +2 -2
  185. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +18 -2
  186. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +76 -3
  187. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +434 -2
  188. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +11 -3
  189. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +24 -2
  190. package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +2 -0
  191. package/lib/view/expenseAutomationView/selectorTypes/missingReceiptsSelectorTypes.d.ts +69 -1
  192. package/lib/view/expenseAutomationView/selectorTypes/transactionsViewSelectorTypes.d.ts +1 -0
  193. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +50 -3
  194. package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.d.ts +1 -1
  195. package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.js +244 -1
  196. package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +2 -1
  197. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +5 -0
  198. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +19 -0
  199. package/lib/view/expenseAutomationView/types/missingReceiptsViewState.d.ts +142 -0
  200. package/lib/view/expenseAutomationView/types/missingReceiptsViewState.js +54 -1
  201. package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +2 -1
  202. package/lib/view/expenseAutomationView/types/transactionsViewState.js +2 -1
  203. package/lib/view/financeStatement/financeStatementReducer.js +11 -8
  204. package/lib/view/financeStatement/financeStatementSelector.d.ts +2 -0
  205. package/lib/view/financeStatement/financeStatementSelector.js +24 -9
  206. package/lib/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelector.d.ts +13 -0
  207. package/lib/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelector.js +326 -0
  208. package/lib/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelectorTypes.d.ts +111 -0
  209. package/lib/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelectorTypes.js +13 -0
  210. package/lib/view/profitAndLossClassesView/profitAndLossClassesViewReducer.d.ts +4 -2
  211. package/lib/view/profitAndLossClassesView/profitAndLossClassesViewReducer.js +7 -2
  212. package/lib/view/profitAndLossClassesView/profitAndLossClassesViewSelector.js +2 -29
  213. package/lib/view/profitAndLossClassesView/profitAndLossClassesViewState.d.ts +4 -0
  214. package/lib/view/profitAndLossClassesView/profitAndLossForTimeframeClassesViewEpic.js +7 -5
  215. package/lib/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.d.ts +6 -0
  216. package/lib/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +204 -0
  217. package/lib/view/reportUIOptions/updateReportUIOptionCOABalancesRangeEpic.js +8 -6
  218. package/lib/view/scheduleView/scheduleListView/scheduleListTypes.d.ts +1 -1
  219. package/lib/view/spendManagement/billPay/billList/billListSelector.js +10 -0
  220. package/lib/view/spendManagement/billPay/billList/billListState.d.ts +1 -1
  221. package/lib/view/spendManagement/billPay/billList/billListState.js +1 -0
  222. package/lib/view/spendManagement/billPay/billPayReview/billPayReviewSelector.js +7 -3
  223. package/lib/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewSelector.js +5 -5
  224. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPayApproversDetailsEpic.js +7 -2
  225. package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.js +13 -6
  226. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.d.ts +1 -1
  227. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.js +1 -0
  228. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.js +2 -0
  229. package/lib/view/spendManagement/reimbursement/editRemiView/editRemiViewSelector.js +6 -3
  230. package/lib/view/spendManagement/reimbursement/remiListView/remiListSelector.d.ts +1 -0
  231. package/lib/view/spendManagement/reimbursement/remiListView/remiListSelector.js +12 -0
  232. package/lib/view/spendManagement/reimbursement/remiListView/remiListState.d.ts +1 -1
  233. package/lib/view/spendManagement/reimbursement/remiListView/remiListState.js +1 -0
  234. package/lib/view/taskManager/taskDetailView/taskDetailSelector.js +3 -3
  235. package/lib/view/taskManager/taskListView/epics/bulkUpdateTaskListEpic.d.ts +1 -0
  236. package/lib/view/taskManager/taskListView/epics/bulkUpdateTaskListEpic.js +1 -0
  237. package/lib/view/taskManager/taskListView/taskListSelector.d.ts +2 -0
  238. package/lib/view/taskManager/taskListView/taskListSelector.js +3 -1
  239. package/lib/view/transactionDetail/epics/saveTransactionHelper.js +2 -2
  240. package/lib/view/transactionDetail/transactionDetailLocalDataHelper.js +16 -14
  241. package/lib/view/userGroupListView/userGroupListViewReducer.d.ts +23 -0
  242. package/lib/view/userGroupListView/userGroupListViewReducer.js +69 -0
  243. package/lib/view/userGroupListView/userGroupListViewSelector.d.ts +7 -0
  244. package/lib/view/userGroupListView/userGroupListViewSelector.js +20 -0
  245. package/lib/view/userGroupListView/userGroupListViewState.d.ts +8 -0
  246. package/lib/view/userGroupListView/userGroupListViewState.js +2 -0
  247. package/lib/view/userListView/fetchUserListByTypeEpic.d.ts +3 -1
  248. package/lib/view/userListView/fetchUserListByTypeEpic.js +11 -0
  249. package/lib/view/userListView/userListViewPayload.d.ts +2 -0
  250. package/lib/zeniAPI.js +0 -2
  251. package/package.json +2 -2
@@ -0,0 +1,322 @@
1
+ import { toAmountWC } from '../../commonStateTypes/amount';
2
+ import { getSummationFreeRangeTotalBalance } from '../../commonStateTypes/coaBalance/additionalBalances/getSummationBalance';
3
+ import { defaultCustomerCurrency } from '../../commonStateTypes/currencyHelper';
4
+ import { reduceFetchStateParallelTimeframes } from '../../commonStateTypes/reduceFetchState';
5
+ import { getSectionClassesViewReport } from '../../entity/sectionClassesViewV2/sectionClassesViewSelector';
6
+ import { enrichProfitAndLossByClassHorizontalReport } from './profitAndLossHorizontalEnrichment';
7
+ export const profitAndLossHorizontalIdsInOrder = [
8
+ 'income',
9
+ 'cogs',
10
+ 'grossProfit',
11
+ 'expenses',
12
+ 'earningsBeforeInterestAndTax',
13
+ 'otherIncome',
14
+ 'otherExpenses',
15
+ 'netOtherIncome',
16
+ 'netIncome',
17
+ ];
18
+ const SECTION_TITLES = {
19
+ income: 'Income',
20
+ cogs: 'Cost of Goods Sold',
21
+ grossProfit: 'Gross Profit',
22
+ expenses: 'Expenses',
23
+ earningsBeforeInterestAndTax: 'Net Operating Income',
24
+ otherIncome: 'Other Income',
25
+ otherExpenses: 'Other Expenses',
26
+ netOtherIncome: 'Net Other Income',
27
+ netIncome: 'Net Income',
28
+ };
29
+ /** Sections fetched and pivoted for horizontal layout (excludes e.g. `netOperatingIncome`). */
30
+ const HORIZONTAL_PANDL_SECTION_IDS = [
31
+ 'income',
32
+ 'cogs',
33
+ 'expenses',
34
+ 'otherIncome',
35
+ 'otherExpenses',
36
+ ];
37
+ export const getProfitAndLossClassesHorizontalView = (filter, accountState, classState, sectionsState, profitAndLossClassesViewState, selectedPeriod) => {
38
+ const fetchState = reduceFetchStateParallelTimeframes([
39
+ profitAndLossClassesViewState.fetchState.month,
40
+ profitAndLossClassesViewState.fetchState.quarter,
41
+ profitAndLossClassesViewState.fetchState.year,
42
+ ]);
43
+ const reportId = 'profit_and_loss_by_classes';
44
+ // Build class columns from the class hierarchy (top-level only).
45
+ // Use `filter.classesToFilterOut` so PDF/Excel downloads (fresh store, empty UI state)
46
+ // respect `classes_to_filter_out` from the request; in-app `classFilter` mirrors uiState.
47
+ const classColumns = buildClassColumns(profitAndLossClassesViewState.classHierarchy, filter.classesToFilterOut);
48
+ const sections = {};
49
+ const calculatedSections = {};
50
+ let reportCurrency = defaultCustomerCurrency;
51
+ if (fetchState.fetchState === 'Completed' && selectedPeriod != null) {
52
+ // Get section reports using existing selector infrastructure
53
+ const sectionReports = {};
54
+ HORIZONTAL_PANDL_SECTION_IDS.forEach((sectionId) => {
55
+ sectionReports[sectionId] = getSectionClassesViewReport(accountState, classState, sectionsState, { reportId, sectionId }, filter);
56
+ });
57
+ reportCurrency =
58
+ profitAndLossClassesViewState.currency ?? defaultCustomerCurrency;
59
+ // Pivot each section from class→account to account→class
60
+ HORIZONTAL_PANDL_SECTION_IDS.forEach((sectionId) => {
61
+ const sectionReport = sectionReports[sectionId];
62
+ if (sectionReport != null) {
63
+ sections[sectionId] = pivotSectionToHorizontal(sectionReport, classColumns, SECTION_TITLES[sectionId] ?? sectionId, reportCurrency);
64
+ }
65
+ });
66
+ // Calculate derived sections
67
+ const incomeSection = sections['income'];
68
+ const cogsSection = sections['cogs'];
69
+ const expensesSection = sections['expenses'];
70
+ const otherIncomeSection = sections['otherIncome'];
71
+ const otherExpensesSection = sections['otherExpenses'];
72
+ // Gross Profit = Income - COGS
73
+ if (incomeSection != null && cogsSection != null) {
74
+ calculatedSections['grossProfit'] = computeCalculatedSection(incomeSection.classTotals, cogsSection.classTotals, incomeSection.sectionTotal, cogsSection.sectionTotal, 'subtract', SECTION_TITLES['grossProfit']);
75
+ }
76
+ // EBIT = Gross Profit - Expenses
77
+ const grossProfit = calculatedSections['grossProfit'];
78
+ if (grossProfit != null && expensesSection != null) {
79
+ calculatedSections['earningsBeforeInterestAndTax'] =
80
+ computeCalculatedSection(grossProfit.classTotals, expensesSection.classTotals, grossProfit.sectionTotal, expensesSection.sectionTotal, 'subtract', SECTION_TITLES['earningsBeforeInterestAndTax']);
81
+ }
82
+ // Net Other Income = Other Income - Other Expenses
83
+ if (otherIncomeSection != null && otherExpensesSection != null) {
84
+ calculatedSections['netOtherIncome'] = computeCalculatedSection(otherIncomeSection.classTotals, otherExpensesSection.classTotals, otherIncomeSection.sectionTotal, otherExpensesSection.sectionTotal, 'subtract', SECTION_TITLES['netOtherIncome']);
85
+ }
86
+ // Net Income = EBIT + Net Other Income
87
+ const ebit = calculatedSections['earningsBeforeInterestAndTax'];
88
+ const netOtherIncome = calculatedSections['netOtherIncome'];
89
+ if (ebit != null && netOtherIncome != null) {
90
+ calculatedSections['netIncome'] = computeCalculatedSection(ebit.classTotals, netOtherIncome.classTotals, ebit.sectionTotal, netOtherIncome.sectionTotal, 'add', SECTION_TITLES['netIncome']);
91
+ }
92
+ }
93
+ // Build synthetic header COABalances for rendering class names as column headers
94
+ const headerBalances = buildHeaderBalances(classColumns, filter.timeframe, selectedPeriod, reportCurrency);
95
+ const report = {
96
+ reportId,
97
+ reportTitle: 'Profit and Loss by Class',
98
+ firstMonthOfFY: profitAndLossClassesViewState.firstMonthOfFY,
99
+ fetchState: fetchState.fetchState,
100
+ bookCloseDate: profitAndLossClassesViewState.bookCloseDate,
101
+ dataAvailable: profitAndLossClassesViewState.dataAvailable,
102
+ selectedPeriod,
103
+ classColumns,
104
+ sections,
105
+ calculatedSections,
106
+ idsInOrder: profitAndLossHorizontalIdsInOrder,
107
+ uiState: profitAndLossClassesViewState.uiState,
108
+ headerBalances,
109
+ };
110
+ enrichProfitAndLossByClassHorizontalReport(report);
111
+ return report;
112
+ };
113
+ /**
114
+ * Build column definitions from class hierarchy (top-level classes only).
115
+ */
116
+ function buildClassColumns(classHierarchy, classesToFilterOut) {
117
+ const filteredIds = new Set(classesToFilterOut.map((id) => id[0]));
118
+ return classHierarchy
119
+ .filter((c) => !filteredIds.has(c.classId[0]))
120
+ .map((c) => ({
121
+ classId: c.classId[0],
122
+ className: c.className,
123
+ nestedClassId: c.classId,
124
+ qboId: c.qboId,
125
+ }))
126
+ .sort((a, b) => a.className.localeCompare(b.className, [], { sensitivity: 'base' }));
127
+ }
128
+ /**
129
+ * Pivot a section from class→account→balances to account→class→balance (single period).
130
+ */
131
+ function pivotSectionToHorizontal(section, classColumns, title, currency) {
132
+ // Map: accountId -> { accountName, classId -> balance }
133
+ const accountMap = new Map();
134
+ // Also track class totals
135
+ const classTotalMap = new Map();
136
+ classColumns.forEach((col) => classTotalMap.set(col.classId, 0));
137
+ // Iterate over each class in the section
138
+ section.classes.forEach((classReport) => {
139
+ const classId = classReport.id[0];
140
+ // Only process classes that are in our columns
141
+ if (!classTotalMap.has(classId)) {
142
+ return;
143
+ }
144
+ // Sum all sliced period balances (same slice as vertical columns; multi-period = range total)
145
+ const classBalance = sumBalancesInSlice(classReport.childrenBalancesTotal.balances);
146
+ classTotalMap.set(classId, classBalance);
147
+ // Iterate through accounts in this class
148
+ collectAccountsFromClass(classReport, classId, accountMap);
149
+ });
150
+ // Build account rows in COA tree order (same parent/child ordering as vertical P&L by class).
151
+ // Sorting by depth + name flattened the hierarchy and broke sub-account grouping.
152
+ const orderedIds = collectAccountIdsInTreeOrder(section, classColumns);
153
+ const usedIds = new Set();
154
+ const accounts = [];
155
+ const pushAccountRow = (accountId) => {
156
+ const accountData = accountMap.get(accountId);
157
+ if (accountData == null) {
158
+ return;
159
+ }
160
+ usedIds.add(accountId);
161
+ const classBalances = classColumns.map((col) => ({
162
+ classId: col.classId,
163
+ balance: toAmountWC(accountData.classBalances.get(col.classId) ?? 0, currency),
164
+ }));
165
+ const rowTotal = classBalances.reduce((sum, cb) => sum + cb.balance.amount, 0);
166
+ accounts.push({
167
+ accountId,
168
+ accountName: accountData.accountName,
169
+ accountType: accountData.accountType,
170
+ depth: accountData.depth,
171
+ classBalances,
172
+ rowTotal: toAmountWC(rowTotal, currency),
173
+ });
174
+ };
175
+ for (const id of orderedIds) {
176
+ pushAccountRow(id);
177
+ }
178
+ for (const accountId of accountMap.keys()) {
179
+ if (!usedIds.has(accountId)) {
180
+ pushAccountRow(accountId);
181
+ }
182
+ }
183
+ // Build class totals
184
+ const classTotals = classColumns.map((col) => ({
185
+ classId: col.classId,
186
+ balance: toAmountWC(classTotalMap.get(col.classId) ?? 0, currency),
187
+ }));
188
+ const sectionTotal = classTotals.reduce((sum, ct) => sum + ct.balance.amount, 0);
189
+ return {
190
+ title,
191
+ accounts,
192
+ classTotals,
193
+ sectionTotal: toAmountWC(sectionTotal, currency),
194
+ };
195
+ }
196
+ /**
197
+ * DFS account ids in the same order as vertical P&L by class, using the first class
198
+ * column that appears in this section as the canonical tree (structure is identical per class).
199
+ */
200
+ function collectAccountIdsInTreeOrder(section, classColumns) {
201
+ const ids = [];
202
+ const visitNested = (nested) => {
203
+ ids.push(nested.account.accountId);
204
+ nested.children.forEach(visitNested);
205
+ };
206
+ for (const col of classColumns) {
207
+ const classReport = section.classes.find((c) => c.id[0] === col.classId);
208
+ if (classReport == null) {
209
+ continue;
210
+ }
211
+ classReport.class.accounts.forEach(visitNested);
212
+ return ids;
213
+ }
214
+ return ids;
215
+ }
216
+ /**
217
+ * Recursively collect account balances from a NestedClassReportV2 into accountMap.
218
+ */
219
+ function collectAccountsFromClass(classReport, classId, accountMap) {
220
+ // Process accounts directly on this class (depth 2 matches vertical `AccountsSection` first level)
221
+ classReport.class.accounts.forEach((nestedAccount) => {
222
+ collectAccountsFromNestedAccount(nestedAccount, classId, accountMap, 2);
223
+ });
224
+ }
225
+ /**
226
+ * Recursively collect accounts from NestedAccountReport (handles sub-accounts).
227
+ */
228
+ function collectAccountsFromNestedAccount(nestedAccount, classId, accountMap, depth) {
229
+ const accountId = nestedAccount.account.accountId;
230
+ const accountName = nestedAccount.account.accountName;
231
+ const balance = sumBalancesInSlice(nestedAccount.account.balancesInTimeframe.balances);
232
+ if (!accountMap.has(accountId)) {
233
+ accountMap.set(accountId, {
234
+ accountName,
235
+ accountType: nestedAccount.account.accountType,
236
+ depth,
237
+ classBalances: new Map(),
238
+ });
239
+ }
240
+ const accountData = accountMap.get(accountId);
241
+ if (accountData == null) {
242
+ return;
243
+ }
244
+ accountData.depth = Math.max(accountData.depth, depth);
245
+ if (accountData.accountType == null &&
246
+ nestedAccount.account.accountType != null) {
247
+ accountData.accountType = nestedAccount.account.accountType;
248
+ }
249
+ const existing = accountData.classBalances.get(classId) ?? 0;
250
+ accountData.classBalances.set(classId, existing + balance);
251
+ // Process sub-accounts
252
+ nestedAccount.children.forEach((child) => {
253
+ collectAccountsFromNestedAccount(child, classId, accountMap, depth + 1);
254
+ });
255
+ }
256
+ /**
257
+ * Total `balance.amount` for the current COA slice (same aggregation as
258
+ * `getSummationFreeRangeTotalBalance`, used for class totals and account rows).
259
+ */
260
+ function sumBalancesInSlice(balances) {
261
+ if (balances.length === 0) {
262
+ return 0;
263
+ }
264
+ const summed = getSummationFreeRangeTotalBalance([...balances]);
265
+ return summed?.balance.amount ?? 0;
266
+ }
267
+ /**
268
+ * Compute a calculated section by adding or subtracting two sets of class totals.
269
+ */
270
+ function computeCalculatedSection(aTotals, bTotals, aTotal, bTotal, operation, title) {
271
+ const currency = {
272
+ currencyCode: aTotal.currencyCode,
273
+ currencySymbol: aTotal.currencySymbol,
274
+ };
275
+ const bTotalsMap = new Map(bTotals.map((b) => [b.classId, b.balance.amount]));
276
+ const classTotals = aTotals.map((a) => {
277
+ const bAmount = bTotalsMap.get(a.classId) ?? 0;
278
+ const resultAmount = operation === 'add'
279
+ ? a.balance.amount + bAmount
280
+ : a.balance.amount - bAmount;
281
+ return {
282
+ classId: a.classId,
283
+ balance: toAmountWC(resultAmount, currency),
284
+ };
285
+ });
286
+ const sectionTotalAmount = operation === 'add'
287
+ ? aTotal.amount + bTotal.amount
288
+ : aTotal.amount - bTotal.amount;
289
+ return {
290
+ title,
291
+ classTotals,
292
+ sectionTotal: toAmountWC(sectionTotalAmount, currency),
293
+ };
294
+ }
295
+ /**
296
+ * Build synthetic COABalance array for header rendering.
297
+ * One entry per class column + one for "Total".
298
+ */
299
+ function buildHeaderBalances(classColumns, timeframe, selectedPeriod, currency) {
300
+ if (selectedPeriod == null) {
301
+ return [];
302
+ }
303
+ const { endDate, startDate } = selectedPeriod;
304
+ const balances = classColumns.map((col) => ({
305
+ balance: toAmountWC(0, currency),
306
+ balanceTimeFrame: timeframe,
307
+ endDate,
308
+ startDate,
309
+ type: 'default',
310
+ label: col.className,
311
+ }));
312
+ // Add a "Total" column
313
+ balances.push({
314
+ balance: toAmountWC(0, currency),
315
+ balanceTimeFrame: timeframe,
316
+ endDate,
317
+ startDate,
318
+ type: 'default',
319
+ label: 'Total',
320
+ });
321
+ return balances;
322
+ }
@@ -0,0 +1,9 @@
1
+ /** Synthetic COABalance `id` for the horizontal class report Total column (transaction routing). */
2
+ export const HORIZONTAL_CLASS_TOTAL_BALANCE_ID = '__horizontal_total__';
3
+ export function isHorizontalAccountReportData(data) {
4
+ return (typeof data === 'object' &&
5
+ data !== null &&
6
+ 'depth' in data &&
7
+ typeof data.depth === 'number' &&
8
+ !('filter' in data));
9
+ }
@@ -23,6 +23,7 @@ export const initialState = {
23
23
  nodeCollapseState: {},
24
24
  scrollPosition: undefined,
25
25
  accountViewMode: 'account_group',
26
+ classViewLayout: 'vertical',
26
27
  classesToFilterOut: [],
27
28
  },
28
29
  firstMonthOfFY: 1,
@@ -94,6 +95,9 @@ const profitAndLossClassesView = createSlice({
94
95
  updateAccountViewMode(draft, action) {
95
96
  draft.uiState.accountViewMode = action.payload.viewMode;
96
97
  },
98
+ updateClassViewLayout(draft, action) {
99
+ draft.uiState.classViewLayout = action.payload.classViewLayout;
100
+ },
97
101
  resetProfitAndLossClassesNodeCollapseState(draft) {
98
102
  draft.uiState.nodeCollapseState = {};
99
103
  },
@@ -102,10 +106,11 @@ const profitAndLossClassesView = createSlice({
102
106
  },
103
107
  },
104
108
  });
105
- export const { fetchProfitAndLossClassesView, fetchProfitAndLossForTimeframeClassesView, updateProfitAndLossForTimeframeClassesView, updateProfitAndLossForTimeframeClassesViewFailure, updateClassesToFilterOut, updateProfitAndLossClassesViewUIState, updateAccountViewMode, resetProfitAndLossClassesNodeCollapseState, clearProfitAndLossClassesView, } = profitAndLossClassesView.actions;
109
+ export const { fetchProfitAndLossClassesView, fetchProfitAndLossForTimeframeClassesView, updateProfitAndLossForTimeframeClassesView, updateProfitAndLossForTimeframeClassesViewFailure, updateClassesToFilterOut, updateProfitAndLossClassesViewUIState, updateAccountViewMode, updateClassViewLayout, resetProfitAndLossClassesNodeCollapseState, clearProfitAndLossClassesView, } = profitAndLossClassesView.actions;
106
110
  export default profitAndLossClassesView.reducer;
107
111
  const doUpdatedProfitAndLossClassesView = (draft, timeframe, pandLReport) => {
108
112
  const report = mapReportPayloadV2ToReportV2(pandLReport.report);
113
+ draft.currency = report.currency;
109
114
  draft.dataAvailable = report.dataAvailable;
110
115
  draft.firstMonthOfFY = report.firstMonthOfFY;
111
116
  draft.bookCloseDate = report.bookCloseDate;
@@ -1,6 +1,7 @@
1
1
  import { getDifferenceOfBalancesGroupedByPeriod } from '../../commonStateTypes/coaBalance/classBalances/getDifferenceOfBalancesGroupedByPeriod';
2
2
  import { getSumOfBalancesByGroupedByPeriod } from '../../commonStateTypes/coaBalance/classBalances/getSumOfBalancesGroupedByPeriod';
3
3
  import { getCOABalances } from '../../commonStateTypes/coaBalance/coaBalance';
4
+ import { reduceFetchStateParallelTimeframes } from '../../commonStateTypes/reduceFetchState';
4
5
  import { getSectionClassesViewReport } from '../../entity/sectionClassesViewV2/sectionClassesViewSelector';
5
6
  import { ALL_PANDL_REPORT_VIEW_SECTION_IDS, } from './profitAndLossClassesViewSelectorTypes';
6
7
  export const profitAndLossIdsInOrder = [
@@ -15,7 +16,7 @@ export const profitAndLossIdsInOrder = [
15
16
  'netIncome',
16
17
  ];
17
18
  export const getProfitAndLossClassesView = (filter, accountState, classState, sectionsState, profitAndLossClassesViewState) => {
18
- const fetchState = reduceFetchState([
19
+ const fetchState = reduceFetchStateParallelTimeframes([
19
20
  profitAndLossClassesViewState.fetchState.month,
20
21
  profitAndLossClassesViewState.fetchState.quarter,
21
22
  profitAndLossClassesViewState.fetchState.year,
@@ -64,31 +65,3 @@ export const getProfitAndLossClassesView = (filter, accountState, classState, se
64
65
  idsInOrder: profitAndLossIdsInOrder,
65
66
  };
66
67
  };
67
- function reduceFetchState(fetchStateList) {
68
- const isAnyProgress = fetchStateList.reduce((prevValue, currentValue) => {
69
- return prevValue === true || currentValue.fetchState === 'In-Progress';
70
- }, false);
71
- const isAllCompleted = fetchStateList.reduce((prevValue, currentValue) => {
72
- return prevValue === true && currentValue.fetchState === 'Completed';
73
- }, true);
74
- const isAnyError = fetchStateList.reduce((prevValue, currentValue) => {
75
- return prevValue === true || currentValue.fetchState === 'Error';
76
- }, false);
77
- const error = fetchStateList.reduce((prevValue, currentValue) => {
78
- return prevValue ?? currentValue.error;
79
- }, undefined);
80
- let fetchState = 'Not-Started';
81
- if (isAnyProgress) {
82
- fetchState = 'In-Progress';
83
- }
84
- else if (isAllCompleted) {
85
- fetchState = 'Completed';
86
- }
87
- else if (isAnyError) {
88
- fetchState = 'Error';
89
- }
90
- return {
91
- fetchState,
92
- error,
93
- };
94
- }
@@ -24,11 +24,13 @@ export const fetchProfitAndLossForTimeframeClassesViewEpic = (actions$, _, zeniA
24
24
  .pipe(mergeMap((response) => {
25
25
  if (response.data != null && isSuccessResponse(response)) {
26
26
  const actions = [];
27
- actions.push(updateSectionClassesView(action.payload.timeframe, 'cogs', 'profit_and_loss_by_classes', response.data.report.cogs, response.data.report.classes, response.data.report.accounts, response.data.report.currency));
28
- actions.push(updateSectionClassesView(action.payload.timeframe, 'expenses', 'profit_and_loss_by_classes', response.data.report.expenses, response.data.report.classes, response.data.report.accounts, response.data.report.currency));
29
- actions.push(updateSectionClassesView(action.payload.timeframe, 'income', 'profit_and_loss_by_classes', response.data.report.income, response.data.report.classes, response.data.report.accounts, response.data.report.currency));
30
- actions.push(updateSectionClassesView(action.payload.timeframe, 'otherExpenses', 'profit_and_loss_by_classes', response.data.report.other_expenses, response.data.report.classes, response.data.report.accounts, response.data.report.currency));
31
- actions.push(updateSectionClassesView(action.payload.timeframe, 'otherIncome', 'profit_and_loss_by_classes', response.data.report.other_income, response.data.report.classes, response.data.report.accounts, response.data.report.currency));
27
+ const report = response.data.report;
28
+ const currency = report.currency;
29
+ actions.push(updateSectionClassesView(action.payload.timeframe, 'cogs', 'profit_and_loss_by_classes', report.cogs, report.classes, report.accounts, currency));
30
+ actions.push(updateSectionClassesView(action.payload.timeframe, 'expenses', 'profit_and_loss_by_classes', report.expenses, report.classes, report.accounts, currency));
31
+ actions.push(updateSectionClassesView(action.payload.timeframe, 'income', 'profit_and_loss_by_classes', report.income, report.classes, report.accounts, currency));
32
+ actions.push(updateSectionClassesView(action.payload.timeframe, 'otherExpenses', 'profit_and_loss_by_classes', report.other_expenses, report.classes, report.accounts, currency));
33
+ actions.push(updateSectionClassesView(action.payload.timeframe, 'otherIncome', 'profit_and_loss_by_classes', report.other_income, report.classes, report.accounts, currency));
32
34
  actions.push(updateProfitAndLossForTimeframeClassesView({
33
35
  timeframe: action.payload.timeframe,
34
36
  report: response.data,
@@ -0,0 +1,201 @@
1
+ import { defaultCustomerCurrency } from '../../commonStateTypes/currencyHelper';
2
+ import { HORIZONTAL_CLASS_TOTAL_BALANCE_ID, } from './profitAndLossClassesByClassHorizontalSelectorTypes';
3
+ /**
4
+ * Populates `sectionHeaderBalancesSlice`, and per-account `accountReportData`, so the
5
+ * web layer only maps selector output to tree nodes.
6
+ */
7
+ export function enrichProfitAndLossByClassHorizontalReport(report) {
8
+ if (report.fetchState !== 'Completed' || report.selectedPeriod == null) {
9
+ return;
10
+ }
11
+ for (const section of Object.values(report.sections)) {
12
+ if (section != null) {
13
+ enrichHorizontalSection(report, section);
14
+ }
15
+ }
16
+ for (const calc of Object.values(report.calculatedSections)) {
17
+ if (calc != null) {
18
+ enrichHorizontalCalculatedSection(report, calc);
19
+ }
20
+ }
21
+ }
22
+ function enrichHorizontalSection(report, section) {
23
+ const classAmounts = report.classColumns.map((col) => {
24
+ const total = section.classTotals.find((ct) => ct.classId === col.classId);
25
+ return total?.balance.amount ?? 0;
26
+ });
27
+ section.sectionHeaderBalancesSlice = buildHorizontalClassColumnBalancesSlice(report, classAmounts, section.sectionTotal.amount);
28
+ const childrenRowIndicesByParent = buildHorizontalAccountChildIndicesByParent(section.accounts);
29
+ const childrenRecord = {};
30
+ childrenRowIndicesByParent.forEach((childIndices, parentIndex) => {
31
+ childrenRecord[parentIndex] = childIndices;
32
+ });
33
+ section.treeLayout = {
34
+ rootAccountRowIndices: section.accounts
35
+ .map((_, i) => findHorizontalAccountParentIndex(section.accounts, i) === -1 ? i : -1)
36
+ .filter((i) => i >= 0),
37
+ childrenRowIndicesByParent: childrenRecord,
38
+ };
39
+ for (let i = 0; i < section.accounts.length; i++) {
40
+ const row = section.accounts[i];
41
+ const classRowAmounts = report.classColumns.map((col) => {
42
+ const cb = row.classBalances.find((b) => b.classId === col.classId);
43
+ return cb?.balance.amount ?? 0;
44
+ });
45
+ row.accountReportData = {
46
+ accountId: row.accountId,
47
+ accountName: row.accountName,
48
+ accountType: row.accountType,
49
+ depth: row.depth,
50
+ balancesInTimeframe: buildHorizontalClassColumnBalancesSlice(report, classRowAmounts, row.rowTotal.amount),
51
+ horizontalTreeView: buildHorizontalTreeView(section.accounts, i),
52
+ };
53
+ }
54
+ }
55
+ function enrichHorizontalCalculatedSection(report, calcSection) {
56
+ const classAmounts = report.classColumns.map((col) => {
57
+ const total = calcSection.classTotals.find((ct) => ct.classId === col.classId);
58
+ return total?.balance.amount ?? 0;
59
+ });
60
+ calcSection.sectionHeaderBalancesSlice =
61
+ buildHorizontalClassColumnBalancesSlice(report, classAmounts, calcSection.sectionTotal.amount);
62
+ }
63
+ function buildHorizontalClassColumnBalancesSlice(report, classAmounts, totalAmount) {
64
+ const fallback = defaultCustomerCurrency;
65
+ const firstHeader = report.headerBalances[0];
66
+ const currencyCode = firstHeader?.balance.currencyCode ?? fallback.currencyCode;
67
+ const currencySymbol = firstHeader?.balance.currencySymbol ?? fallback.currencySymbol;
68
+ const timeframe = firstHeader?.balanceTimeFrame ?? 'month';
69
+ const emptySlice = {
70
+ balances: [],
71
+ additionalBalances: [],
72
+ filter: {
73
+ firstMonthOfFY: report.firstMonthOfFY,
74
+ timeframe,
75
+ balancesRange: { numberOfPeriods: 0, orderBy: 'ascending_date' },
76
+ additionalBalances: [],
77
+ },
78
+ };
79
+ if (report.selectedPeriod == null) {
80
+ return emptySlice;
81
+ }
82
+ const { startDate, endDate } = report.selectedPeriod;
83
+ const balances = report.classColumns.map((col, i) => ({
84
+ balance: {
85
+ amount: classAmounts[i] ?? 0,
86
+ currencyCode,
87
+ currencySymbol,
88
+ },
89
+ balanceTimeFrame: timeframe,
90
+ startDate,
91
+ endDate,
92
+ type: 'default',
93
+ id: col.classId,
94
+ label: col.className,
95
+ }));
96
+ balances.push({
97
+ balance: {
98
+ amount: totalAmount,
99
+ currencyCode,
100
+ currencySymbol,
101
+ },
102
+ balanceTimeFrame: timeframe,
103
+ startDate,
104
+ endDate,
105
+ type: 'default',
106
+ id: HORIZONTAL_CLASS_TOTAL_BALANCE_ID,
107
+ label: 'Total',
108
+ });
109
+ return {
110
+ balances,
111
+ additionalBalances: [],
112
+ filter: {
113
+ firstMonthOfFY: report.firstMonthOfFY,
114
+ timeframe,
115
+ balancesRange: {
116
+ numberOfPeriods: balances.length,
117
+ orderBy: 'ascending_date',
118
+ },
119
+ additionalBalances: [],
120
+ },
121
+ };
122
+ }
123
+ function findHorizontalAccountParentIndex(dfsOrderedAccountRows, childRowIndex) {
124
+ const childDepth = dfsOrderedAccountRows[childRowIndex].depth;
125
+ if (childDepth <= 2) {
126
+ return -1;
127
+ }
128
+ for (let earlierRowIndex = childRowIndex - 1; earlierRowIndex >= 0; earlierRowIndex--) {
129
+ const earlierDepth = dfsOrderedAccountRows[earlierRowIndex].depth;
130
+ if (earlierDepth < childDepth) {
131
+ if (earlierDepth === childDepth - 1) {
132
+ return earlierRowIndex;
133
+ }
134
+ return -1;
135
+ }
136
+ }
137
+ return -1;
138
+ }
139
+ function getHorizontalAccountSiblingIndices(dfsOrderedAccountRows, rowIndex) {
140
+ const parentRowIndex = findHorizontalAccountParentIndex(dfsOrderedAccountRows, rowIndex);
141
+ const rowDepth = dfsOrderedAccountRows[rowIndex].depth;
142
+ const siblings = [];
143
+ for (let i = 0; i < dfsOrderedAccountRows.length; i++) {
144
+ if (dfsOrderedAccountRows[i].depth === rowDepth &&
145
+ findHorizontalAccountParentIndex(dfsOrderedAccountRows, i) ===
146
+ parentRowIndex) {
147
+ siblings.push(i);
148
+ }
149
+ }
150
+ return siblings;
151
+ }
152
+ function horizontalAccountHasChildRows(dfsOrderedAccountRows, parentRowIndex) {
153
+ return dfsOrderedAccountRows.some((_, rowIndex) => findHorizontalAccountParentIndex(dfsOrderedAccountRows, rowIndex) ===
154
+ parentRowIndex);
155
+ }
156
+ function buildHorizontalSubAccountAncestorMetadata(dfsOrderedAccountRows, currentRowIndex) {
157
+ const ancestorRowIndicesRootToLeaf = [];
158
+ let walkRowIndex = currentRowIndex;
159
+ while (walkRowIndex >= 0) {
160
+ ancestorRowIndicesRootToLeaf.unshift(walkRowIndex);
161
+ walkRowIndex = findHorizontalAccountParentIndex(dfsOrderedAccountRows, walkRowIndex);
162
+ }
163
+ return ancestorRowIndicesRootToLeaf.map((rowIndex) => {
164
+ const siblingIndices = getHorizontalAccountSiblingIndices(dfsOrderedAccountRows, rowIndex);
165
+ return {
166
+ depth: dfsOrderedAccountRows[rowIndex].depth - 2,
167
+ hasSibling: siblingIndices.length > 1,
168
+ hasChildren: horizontalAccountHasChildRows(dfsOrderedAccountRows, rowIndex),
169
+ isLastNode: rowIndex === siblingIndices[siblingIndices.length - 1],
170
+ name: dfsOrderedAccountRows[rowIndex].accountName,
171
+ };
172
+ });
173
+ }
174
+ function buildHorizontalAccountChildIndicesByParent(dfsOrderedAccountRows) {
175
+ const childIndicesByParentRowIndex = new Map();
176
+ for (let rowIndex = 0; rowIndex < dfsOrderedAccountRows.length; rowIndex++) {
177
+ const parentRowIndex = findHorizontalAccountParentIndex(dfsOrderedAccountRows, rowIndex);
178
+ if (parentRowIndex >= 0) {
179
+ let childRowIndices = childIndicesByParentRowIndex.get(parentRowIndex);
180
+ if (childRowIndices === undefined) {
181
+ childRowIndices = [];
182
+ childIndicesByParentRowIndex.set(parentRowIndex, childRowIndices);
183
+ }
184
+ childRowIndices.push(rowIndex);
185
+ }
186
+ }
187
+ return childIndicesByParentRowIndex;
188
+ }
189
+ function buildHorizontalTreeView(dfsOrderedAccountRows, currentRowIndex) {
190
+ const treeDepth = Math.max(0, dfsOrderedAccountRows[currentRowIndex].depth - 2);
191
+ const siblingIndices = getHorizontalAccountSiblingIndices(dfsOrderedAccountRows, currentRowIndex);
192
+ const hasChildren = horizontalAccountHasChildRows(dfsOrderedAccountRows, currentRowIndex);
193
+ return {
194
+ subAccountAncestorMetadata: buildHorizontalSubAccountAncestorMetadata(dfsOrderedAccountRows, currentRowIndex),
195
+ treeDepth,
196
+ hasChildren,
197
+ hasSiblings: siblingIndices.length > 1,
198
+ isLeaf: !hasChildren,
199
+ isLastNode: currentRowIndex === siblingIndices[siblingIndices.length - 1],
200
+ };
201
+ }
@@ -2,15 +2,19 @@ import { of } from 'rxjs';
2
2
  import { filter, switchMap } from 'rxjs/operators';
3
3
  import { updateCashInCashOutCOABalancesRange } from '../cashInCashOut/cashInCashOutReducer';
4
4
  import { updateCashPositionCOABalancesRange } from '../cashPosition/cashPositionReducer';
5
- import { initialFinanceStatementState, updateCOABalancesRange, } from '../financeStatement/financeStatementReducer';
5
+ import { updateCOABalancesRange } from '../financeStatement/financeStatementReducer';
6
6
  import { updateNetBurnOrIncomeCOABalancesRange } from '../netBurnOrIncome/netBurnOrIncomeReducer';
7
7
  import { updateOpExCOABalancesRange } from '../opEx/opExReducer';
8
8
  import { updateRevenueCOABalancesRange } from '../revenue/revenueReducer';
9
9
  import { updateReportUIOptionCOABalancesRange } from './reportUIOptionsReducer';
10
10
  export const updateReportUIOptionCOABalancesRangeEpic = (actions$, state$) => actions$.pipe(filter(updateReportUIOptionCOABalancesRange.match), switchMap((action) => {
11
- const thisPeriod = action.payload.selectedCOABalancesRange.thisPeriod;
12
- const orderBy = action.payload.selectedCOABalancesRange.orderBy;
13
- const highlightedNoOfPeriods = state$.value.reportUIOptionsState.isCompareModeOn === true ? 4 : 1;
11
+ const selectedRange = action.payload.selectedCOABalancesRange;
12
+ const thisPeriod = selectedRange.thisPeriod;
13
+ const orderBy = selectedRange.orderBy;
14
+ const numberOfPeriodsFromSelection = selectedRange.numberOfPeriods;
15
+ const highlightedNoOfPeriods = state$.value.reportUIOptionsState.isCompareModeOn === true
16
+ ? numberOfPeriodsFromSelection
17
+ : 1;
14
18
  const highlightedCOABalancesRange = action.payload.highlightedCOABalancesRange == null && thisPeriod != null
15
19
  ? {
16
20
  numberOfPeriods: highlightedNoOfPeriods,
@@ -62,9 +66,7 @@ export const updateReportUIOptionCOABalancesRangeEpic = (actions$, state$) => ac
62
66
  thisPeriod: action.payload.highlightedCOABalancesRange != null
63
67
  ? action.payload.highlightedCOABalancesRange.thisPeriod
64
68
  : thisPeriod,
65
- numberOfPeriods: state$.value.reportUIOptionsState.isCompareModeOn === true
66
- ? 4
67
- : initialFinanceStatementState.maxNumOfPeriodsToHighlight,
69
+ numberOfPeriods: numberOfPeriodsFromSelection,
68
70
  orderBy,
69
71
  }));
70
72
  }));