@zeniai/client-epic-state 5.1.94 → 5.1.95-betaAK0

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 (112) hide show
  1. package/lib/commonStateTypes/viewAndReport/reportIDHelper.d.ts +16 -0
  2. package/lib/commonStateTypes/viewAndReport/reportIDHelper.js +22 -1
  3. package/lib/commonStateTypes/viewAndReport/viewAndReport.d.ts +2 -2
  4. package/lib/commonStateTypes/viewAndReport/viewAndReport.js +2 -0
  5. package/lib/entity/accountGroup/accountGroupState.d.ts +1 -1
  6. package/lib/entity/class/classReducer.d.ts +4 -4
  7. package/lib/entity/class/classSelectorV2.d.ts +2 -1
  8. package/lib/entity/class/classSelectorV2.js +7 -7
  9. package/lib/entity/class/classState.d.ts +1 -1
  10. package/lib/entity/forecast/forecastState.d.ts +1 -1
  11. package/lib/entity/invoicing/invoicingCommonPayload.d.ts +9 -0
  12. package/lib/entity/invoicing/invoicingCommonPayload.js +7 -0
  13. package/lib/entity/sectionAccountsView/sectionAccountsView.d.ts +1 -1
  14. package/lib/entity/sectionClassesViewV2/sectionClassesView.d.ts +1 -1
  15. package/lib/entity/sectionClassesViewV2/sectionClassesViewReducer.d.ts +2 -2
  16. package/lib/entity/sectionClassesViewV2/sectionClassesViewSelector.d.ts +2 -1
  17. package/lib/entity/sectionClassesViewV2/sectionClassesViewSelector.js +3 -3
  18. package/lib/entity/sectionProjectView/sectionProjectView.d.ts +1 -1
  19. package/lib/entity/sectionProjectView/sectionProjectViewReducer.d.ts +2 -2
  20. package/lib/entity/sectionProjectView/sectionProjectViewSelector.d.ts +2 -1
  21. package/lib/entity/sectionProjectView/sectionProjectViewSelector.js +4 -4
  22. package/lib/epic.d.ts +5 -1
  23. package/lib/epic.js +5 -1
  24. package/lib/esm/commonStateTypes/viewAndReport/reportIDHelper.js +17 -0
  25. package/lib/esm/commonStateTypes/viewAndReport/viewAndReport.js +2 -0
  26. package/lib/esm/entity/class/classSelectorV2.js +7 -7
  27. package/lib/esm/entity/invoicing/invoicingCommonPayload.js +6 -0
  28. package/lib/esm/entity/sectionClassesViewV2/sectionClassesViewSelector.js +3 -3
  29. package/lib/esm/entity/sectionProjectView/sectionProjectViewSelector.js +4 -4
  30. package/lib/esm/epic.js +5 -1
  31. package/lib/esm/index.js +10 -4
  32. package/lib/esm/reducer.js +6 -0
  33. package/lib/esm/view/balanceSheetClassesView/balanceSheetClassesViewEpic.js +30 -0
  34. package/lib/esm/view/balanceSheetClassesView/balanceSheetClassesViewPayload.js +1 -0
  35. package/lib/esm/view/balanceSheetClassesView/balanceSheetClassesViewReducer.js +132 -0
  36. package/lib/esm/view/balanceSheetClassesView/balanceSheetClassesViewSelector.js +90 -0
  37. package/lib/esm/view/balanceSheetClassesView/balanceSheetClassesViewSelectorTypes.js +1 -0
  38. package/lib/esm/view/balanceSheetClassesView/balanceSheetClassesViewState.js +1 -0
  39. package/lib/esm/view/balanceSheetClassesView/balanceSheetForTimeframeClassesViewEpic.js +61 -0
  40. package/lib/esm/view/balanceSheetProjectView/balanceSheetForTimeframeProjectViewEpic.js +63 -0
  41. package/lib/esm/view/balanceSheetProjectView/balanceSheetProjectViewEpic.js +30 -0
  42. package/lib/esm/view/balanceSheetProjectView/balanceSheetProjectViewPayload.js +1 -0
  43. package/lib/esm/view/balanceSheetProjectView/balanceSheetProjectViewReducer.js +128 -0
  44. package/lib/esm/view/balanceSheetProjectView/balanceSheetProjectViewSelector.js +90 -0
  45. package/lib/esm/view/balanceSheetProjectView/balanceSheetProjectViewSelectorTypes.js +1 -0
  46. package/lib/esm/view/balanceSheetProjectView/balanceSheetProjectViewState.js +1 -0
  47. package/lib/esm/view/financeStatement/financeStatementSelector.js +21 -1
  48. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewPayload.js +16 -4
  49. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/invoicingSubscriptionFormConfig.js +34 -1
  50. package/lib/esm/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.js +5 -1
  51. package/lib/esm/view/profitAndLossProjectView/profitAndLossProjectViewReducer.js +7 -2
  52. package/lib/esm/view/spendManagement/spendManagementFilterHelpers.js +1 -1
  53. package/lib/index.d.ts +15 -5
  54. package/lib/index.js +76 -48
  55. package/lib/reducer.d.ts +6 -0
  56. package/lib/reducer.js +6 -0
  57. package/lib/view/auditReportView/auditReportViewState.d.ts +1 -1
  58. package/lib/view/balanceSheetClassesView/balanceSheetClassesViewEpic.d.ts +6 -0
  59. package/lib/view/balanceSheetClassesView/balanceSheetClassesViewEpic.js +34 -0
  60. package/lib/view/balanceSheetClassesView/balanceSheetClassesViewPayload.d.ts +20 -0
  61. package/lib/view/balanceSheetClassesView/balanceSheetClassesViewPayload.js +2 -0
  62. package/lib/view/balanceSheetClassesView/balanceSheetClassesViewReducer.d.ts +34 -0
  63. package/lib/view/balanceSheetClassesView/balanceSheetClassesViewReducer.js +136 -0
  64. package/lib/view/balanceSheetClassesView/balanceSheetClassesViewSelector.d.ts +7 -0
  65. package/lib/view/balanceSheetClassesView/balanceSheetClassesViewSelector.js +94 -0
  66. package/lib/view/balanceSheetClassesView/balanceSheetClassesViewSelectorTypes.d.ts +7 -0
  67. package/lib/view/balanceSheetClassesView/balanceSheetClassesViewSelectorTypes.js +2 -0
  68. package/lib/view/balanceSheetClassesView/balanceSheetClassesViewState.d.ts +23 -0
  69. package/lib/view/balanceSheetClassesView/balanceSheetClassesViewState.js +2 -0
  70. package/lib/view/balanceSheetClassesView/balanceSheetForTimeframeClassesViewEpic.d.ts +9 -0
  71. package/lib/view/balanceSheetClassesView/balanceSheetForTimeframeClassesViewEpic.js +66 -0
  72. package/lib/view/balanceSheetProjectView/balanceSheetForTimeframeProjectViewEpic.d.ts +10 -0
  73. package/lib/view/balanceSheetProjectView/balanceSheetForTimeframeProjectViewEpic.js +68 -0
  74. package/lib/view/balanceSheetProjectView/balanceSheetProjectViewEpic.d.ts +6 -0
  75. package/lib/view/balanceSheetProjectView/balanceSheetProjectViewEpic.js +34 -0
  76. package/lib/view/balanceSheetProjectView/balanceSheetProjectViewPayload.d.ts +20 -0
  77. package/lib/view/balanceSheetProjectView/balanceSheetProjectViewPayload.js +2 -0
  78. package/lib/view/balanceSheetProjectView/balanceSheetProjectViewReducer.d.ts +33 -0
  79. package/lib/view/balanceSheetProjectView/balanceSheetProjectViewReducer.js +132 -0
  80. package/lib/view/balanceSheetProjectView/balanceSheetProjectViewSelector.d.ts +7 -0
  81. package/lib/view/balanceSheetProjectView/balanceSheetProjectViewSelector.js +94 -0
  82. package/lib/view/balanceSheetProjectView/balanceSheetProjectViewSelectorTypes.d.ts +18 -0
  83. package/lib/view/balanceSheetProjectView/balanceSheetProjectViewSelectorTypes.js +2 -0
  84. package/lib/view/balanceSheetProjectView/balanceSheetProjectViewState.d.ts +22 -0
  85. package/lib/view/balanceSheetProjectView/balanceSheetProjectViewState.js +2 -0
  86. package/lib/view/billPayCard/billPayCardSelector.d.ts +1 -1
  87. package/lib/view/cardBalance/cardBalanceSelector.d.ts +1 -1
  88. package/lib/view/cashBalance/cashBalanceSelector.d.ts +1 -1
  89. package/lib/view/cashInCashOut/cashInCashOutSelector.d.ts +1 -1
  90. package/lib/view/cashPosition/cashPositionSelector.d.ts +1 -1
  91. package/lib/view/dashboard/dashboardReducer.d.ts +2 -2
  92. package/lib/view/financeStatement/financeStatementReducer.d.ts +1 -1
  93. package/lib/view/financeStatement/financeStatementSelector.d.ts +4 -0
  94. package/lib/view/financeStatement/financeStatementSelector.js +21 -1
  95. package/lib/view/globalMerchantView/globalMerchantViewReducer.d.ts +2 -2
  96. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewPayload.d.ts +4 -0
  97. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewPayload.js +15 -3
  98. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewState.d.ts +17 -0
  99. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/invoicingSubscriptionFormConfig.d.ts +7 -0
  100. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/invoicingSubscriptionFormConfig.js +37 -2
  101. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewPayload.d.ts +2 -1
  102. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.d.ts +1 -1
  103. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.js +4 -0
  104. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewState.d.ts +7 -1
  105. package/lib/view/profitAndLossProjectView/profitAndLossProjectViewReducer.d.ts +1 -0
  106. package/lib/view/profitAndLossProjectView/profitAndLossProjectViewReducer.js +7 -2
  107. package/lib/view/reimbursementCard/reimbursementCardSelector.d.ts +1 -1
  108. package/lib/view/reportsResync/reportsResyncReducer.d.ts +2 -2
  109. package/lib/view/spendManagement/spendManagementFilterHelpers.js +1 -1
  110. package/lib/view/tasksCard/tasksCardSelector.d.ts +1 -1
  111. package/lib/view/topEx/topExSelector.d.ts +1 -1
  112. package/package.json +1 -1
@@ -91,6 +91,8 @@ import auditReportView, { initialState as initialAuditReportViewState, } from '.
91
91
  import authentication, { initialState as initialAuthenticationViewState, } from './view/authenticationView/authenticationViewReducer';
92
92
  import entityAutoComplete, { initialState as initialEntityAutoCompleteState, } from './view/autoComplete/entityAutoCompleteReducer';
93
93
  import balanceSheet, { initialState as initialBalanceSheetState, } from './view/balanceSheet/balanceSheetReducer';
94
+ import balanceSheetClassesView, { initialState as initialBalanceSheetClassesViewState, } from './view/balanceSheetClassesView/balanceSheetClassesViewReducer';
95
+ import balanceSheetProjectView, { initialState as initialBalanceSheetProjectViewState, } from './view/balanceSheetProjectView/balanceSheetProjectViewReducer';
94
96
  import bankAccountView, { initialState as initialBankAccountView, } from './view/bankAccountView/bankAccountViewReducer';
95
97
  import billPayCard, { initialState as initialBillPayCardState, } from './view/billPayCard/billPayCardReducer';
96
98
  import cardBalance, { initialState as initialCardBalanceState, } from './view/cardBalance/cardBalanceReducer';
@@ -377,6 +379,8 @@ const initialViewsState = {
377
379
  auditReportViewState: initialAuditReportViewState,
378
380
  authenticationViewState: initialAuthenticationViewState,
379
381
  autotransferRulesState: initialAutotransferRulesState,
382
+ balanceSheetClassesViewState: initialBalanceSheetClassesViewState,
383
+ balanceSheetProjectViewState: initialBalanceSheetProjectViewState,
380
384
  balanceSheetState: initialBalanceSheetState,
381
385
  bankAccountViewState: initialBankAccountView,
382
386
  billDetailViewState: initialBillDetailViewState,
@@ -671,6 +675,8 @@ const viewReducers = {
671
675
  auditReportViewState: auditReportView,
672
676
  authenticationViewState: authentication,
673
677
  autotransferRulesState: autotransferRules,
678
+ balanceSheetClassesViewState: balanceSheetClassesView,
679
+ balanceSheetProjectViewState: balanceSheetProjectView,
674
680
  balanceSheetState: balanceSheet,
675
681
  bankAccountViewState: bankAccountView,
676
682
  billDetailViewState: billDetailView,
@@ -0,0 +1,30 @@
1
+ import { from } from 'rxjs';
2
+ import { filter, switchMap } from 'rxjs/operators';
3
+ import { fetchBalanceSheetClassesView, fetchBalanceSheetForTimeframeClassesView, } from './balanceSheetClassesViewReducer';
4
+ export const fetchBalanceSheetClassesViewEpic = (actions$, state) => actions$.pipe(filter(fetchBalanceSheetClassesView.match), switchMap((action) => {
5
+ const { cacheOverride } = action.payload;
6
+ if (cacheOverride === true) {
7
+ return from([
8
+ fetchBalanceSheetForTimeframeClassesView('month', true),
9
+ fetchBalanceSheetForTimeframeClassesView('quarter', true),
10
+ fetchBalanceSheetForTimeframeClassesView('year', true),
11
+ ]);
12
+ }
13
+ else {
14
+ const fetchActions = [];
15
+ const classFetchState = state.value.balanceSheetClassesViewState.fetchState;
16
+ if (classFetchState['month'].fetchState !== 'In-Progress' &&
17
+ classFetchState['month'].fetchState !== 'Completed') {
18
+ fetchActions.push(fetchBalanceSheetForTimeframeClassesView('month'));
19
+ }
20
+ if (classFetchState['quarter'].fetchState !== 'In-Progress' &&
21
+ classFetchState['quarter'].fetchState !== 'Completed') {
22
+ fetchActions.push(fetchBalanceSheetForTimeframeClassesView('quarter'));
23
+ }
24
+ if (classFetchState['year'].fetchState !== 'In-Progress' &&
25
+ classFetchState['year'].fetchState !== 'Completed') {
26
+ fetchActions.push(fetchBalanceSheetForTimeframeClassesView('year'));
27
+ }
28
+ return from(fetchActions);
29
+ }
30
+ }));
@@ -0,0 +1,132 @@
1
+ import { createSlice } from '@reduxjs/toolkit';
2
+ import { mapReportPayloadV2ToReportV2 } from '../../commonPayloadTypes/v2/viewAndReportPayloadv2';
3
+ import { geNestedClassIDHierarchyForReport } from '../../commonStateTypes/classesView/getNestedClassIDHierarchyForReport';
4
+ import { toClassMetadata } from '../../entity/class/classPayload';
5
+ import { clearAll } from '../../rootActions';
6
+ export const initialState = {
7
+ classHierarchy: [],
8
+ bookCloseDate: undefined,
9
+ fetchState: {
10
+ month: {
11
+ fetchState: 'Not-Started',
12
+ error: undefined,
13
+ },
14
+ quarter: {
15
+ fetchState: 'Not-Started',
16
+ error: undefined,
17
+ },
18
+ year: {
19
+ fetchState: 'Not-Started',
20
+ error: undefined,
21
+ },
22
+ },
23
+ uiState: {
24
+ nodeCollapseState: {},
25
+ scrollPosition: undefined,
26
+ accountViewMode: 'account_group',
27
+ classesToFilterOut: [],
28
+ },
29
+ firstMonthOfFY: 1,
30
+ reportId: 'balance_sheet_by_classes',
31
+ reportTitle: 'balance_sheet_by_classes',
32
+ };
33
+ const balanceSheetClassesView = createSlice({
34
+ name: 'balanceSheetClassesView',
35
+ initialState,
36
+ reducers: {
37
+ fetchBalanceSheetClassesView: {
38
+ prepare(cacheOverride = false) {
39
+ return { payload: { cacheOverride } };
40
+ },
41
+ reducer(
42
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
43
+ _draft,
44
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
45
+ _action) {
46
+ // nothing to do here
47
+ },
48
+ },
49
+ fetchBalanceSheetForTimeframeClassesView: {
50
+ prepare(timeframe, cacheOverride = false) {
51
+ return { payload: { timeframe, cacheOverride } };
52
+ },
53
+ reducer(draft, action) {
54
+ const timeframe = action.payload.timeframe;
55
+ draft.fetchState[timeframe].fetchState = 'In-Progress';
56
+ draft.fetchState[timeframe].error = undefined;
57
+ },
58
+ },
59
+ updateBalanceSheetForTimeframeClassesView(draft, action) {
60
+ doUpdateBalanceSheetClassesView(draft, action.payload.timeframe, action.payload.report);
61
+ },
62
+ updateBalanceSheetForTimeframeClassesViewFailure: {
63
+ prepare(error, timeframe) {
64
+ return {
65
+ payload: {
66
+ error,
67
+ timeframe,
68
+ },
69
+ };
70
+ },
71
+ reducer(draft, action) {
72
+ draft.fetchState[action.payload.timeframe] = {
73
+ fetchState: 'Error',
74
+ error: action.payload.error,
75
+ };
76
+ },
77
+ },
78
+ updateBalanceSheetClassesToFilterOut(draft, action) {
79
+ draft.uiState.classesToFilterOut = action.payload.classesToFilterOut;
80
+ },
81
+ updateBalanceSheetClassesViewUIState(draft, action) {
82
+ const { nodeCollapseState, scrollPosition, resetLeftScroll } = action.payload;
83
+ if (nodeCollapseState != null) {
84
+ draft.uiState.nodeCollapseState = Object.assign({}, draft.uiState.nodeCollapseState, {
85
+ [nodeCollapseState.nodeId]: nodeCollapseState.isCollapsed,
86
+ });
87
+ }
88
+ // Mutually exclusive: resetLeftScroll clears only scrollLeft from the
89
+ // recorded position, scrollPosition replaces the whole record.
90
+ if (resetLeftScroll === true && draft.uiState.scrollPosition != null) {
91
+ draft.uiState.scrollPosition.scrollLeft = undefined;
92
+ }
93
+ else if (scrollPosition != null) {
94
+ draft.uiState.scrollPosition = scrollPosition;
95
+ }
96
+ },
97
+ updateBalanceSheetClassesViewAccountViewMode(draft, action) {
98
+ draft.uiState.accountViewMode = action.payload.viewMode;
99
+ },
100
+ resetBalanceSheetClassesNodeCollapseState(draft) {
101
+ draft.uiState.nodeCollapseState = {};
102
+ },
103
+ clearBalanceSheetClassesView(draft) {
104
+ Object.assign(draft, initialState);
105
+ },
106
+ },
107
+ extraReducers: (builder) => {
108
+ builder.addCase(clearAll, (draft) => {
109
+ Object.assign(draft, initialState);
110
+ });
111
+ },
112
+ });
113
+ export const { fetchBalanceSheetClassesView, fetchBalanceSheetForTimeframeClassesView, updateBalanceSheetForTimeframeClassesView, updateBalanceSheetForTimeframeClassesViewFailure, updateBalanceSheetClassesToFilterOut, updateBalanceSheetClassesViewUIState, updateBalanceSheetClassesViewAccountViewMode, resetBalanceSheetClassesNodeCollapseState, clearBalanceSheetClassesView, } = balanceSheetClassesView.actions;
114
+ export default balanceSheetClassesView.reducer;
115
+ const doUpdateBalanceSheetClassesView = (draft, timeframe, balanceSheetReport) => {
116
+ const report = mapReportPayloadV2ToReportV2(balanceSheetReport.report);
117
+ draft.currency = report.currency;
118
+ draft.dataAvailable = report.dataAvailable;
119
+ draft.firstMonthOfFY = report.firstMonthOfFY;
120
+ draft.bookCloseDate = report.bookCloseDate;
121
+ draft.status = report.status;
122
+ draft.fetchState[timeframe].fetchState = 'Completed';
123
+ draft.fetchState[timeframe].error = undefined;
124
+ const classMetadata = balanceSheetReport.report.classes.map((eachClass) => toClassMetadata(eachClass));
125
+ // Populated once and then left alone, so a per-timeframe response cannot
126
+ // clobber a hierarchy built from a full one. A class added mid-session is
127
+ // therefore not picked up until the store is cleared, even by a hard refresh —
128
+ // the same trade-off profitAndLossClassesViewReducer makes.
129
+ if (draft.classHierarchy.length <= 0) {
130
+ draft.classHierarchy = geNestedClassIDHierarchyForReport(classMetadata);
131
+ }
132
+ };
@@ -0,0 +1,90 @@
1
+ import { newAdditionalBalancesOptions } from '../../commonStateTypes/coaBalance/additionalBalances/getAdditionalBalances';
2
+ import { getSumOfBalancesByGroupedByPeriod } from '../../commonStateTypes/coaBalance/classBalances/getSumOfBalancesGroupedByPeriod';
3
+ import { getCOABalances } from '../../commonStateTypes/coaBalance/coaBalance';
4
+ import { reduceFetchStateParallelTimeframes } from '../../commonStateTypes/reduceFetchState';
5
+ import { getSectionClassesViewReport } from '../../entity/sectionClassesViewV2/sectionClassesViewSelector';
6
+ import { ALL_BALANCE_SHEET_REPORT_VIEW_ASSET_IDS, ALL_BALANCE_SHEET_REPORT_VIEW_EQUITY_IDS, ALL_BALANCE_SHEET_REPORT_VIEW_LIABILITY_IDS, ALL_BALANCE_SHEET_REPORT_VIEW_SECTION_IDS, balanceSheetSectionIdsInOrder, } from '../balanceSheet/balanceSheetSelectorTypes';
7
+ // The section-id constants and the display order are both module-level, so the
8
+ // sorted groupings are computed once instead of on every selector call.
9
+ const byDisplayOrder = (a, b) => balanceSheetSectionIdsInOrder.indexOf(a) -
10
+ balanceSheetSectionIdsInOrder.indexOf(b);
11
+ const ASSET_IDS_IN_ORDER = [...ALL_BALANCE_SHEET_REPORT_VIEW_ASSET_IDS].sort(byDisplayOrder);
12
+ const LIABILITY_IDS_IN_ORDER = [
13
+ ...ALL_BALANCE_SHEET_REPORT_VIEW_LIABILITY_IDS,
14
+ ].sort(byDisplayOrder);
15
+ const EQUITY_IDS_IN_ORDER = [...ALL_BALANCE_SHEET_REPORT_VIEW_EQUITY_IDS].sort(byDisplayOrder);
16
+ export const getBalanceSheetClassesView = (filter, accountState, classState, sectionsState, balanceSheetClassesViewState) => {
17
+ const fetchState = reduceFetchStateParallelTimeframes([
18
+ balanceSheetClassesViewState.fetchState.month,
19
+ balanceSheetClassesViewState.fetchState.quarter,
20
+ balanceSheetClassesViewState.fetchState.year,
21
+ ]);
22
+ const reportId = 'balance_sheet_by_classes';
23
+ const sections = {};
24
+ const calculatedSections = {};
25
+ if (fetchState.fetchState === 'Completed') {
26
+ // Balance Sheet balances are point-in-time, so the extra columns must be
27
+ // read as snapshots rather than period sums.
28
+ const additionalBalancesOptions = newAdditionalBalancesOptions(true);
29
+ ALL_BALANCE_SHEET_REPORT_VIEW_SECTION_IDS.forEach((sectionId) => {
30
+ sections[`${sectionId}`] = getSectionClassesViewReport(accountState, classState, sectionsState, {
31
+ reportId,
32
+ sectionId,
33
+ }, filter, additionalBalancesOptions);
34
+ });
35
+ const totalCurrentAssetsBalancesByPeriod = getSumOfBalancesByGroupedByPeriod([
36
+ sections['cashAndEquivalents'].sectionBalancesTotalByPeriod,
37
+ sections['accountsReceiable'].sectionBalancesTotalByPeriod,
38
+ sections['otherCurrentAssets'].sectionBalancesTotalByPeriod,
39
+ ]);
40
+ calculatedSections['totalCurrentAssets'] = getCOABalances(totalCurrentAssetsBalancesByPeriod, filter, additionalBalancesOptions);
41
+ const totalAssetsBalancesByPeriod = getSumOfBalancesByGroupedByPeriod([
42
+ totalCurrentAssetsBalancesByPeriod ?? {},
43
+ sections['fixedAssets'].sectionBalancesTotalByPeriod,
44
+ sections['otherAssets'].sectionBalancesTotalByPeriod,
45
+ ]);
46
+ calculatedSections['totalAssets'] = getCOABalances(totalAssetsBalancesByPeriod, filter, additionalBalancesOptions);
47
+ const totalCurrentLiabilitiesBalancesByPeriod = getSumOfBalancesByGroupedByPeriod([
48
+ sections['accountsPayable'].sectionBalancesTotalByPeriod,
49
+ sections['creditCards'].sectionBalancesTotalByPeriod,
50
+ sections['otherCurrentLiabilities'].sectionBalancesTotalByPeriod,
51
+ ]);
52
+ calculatedSections['totalCurrentLiabilities'] = getCOABalances(totalCurrentLiabilitiesBalancesByPeriod, filter, additionalBalancesOptions);
53
+ calculatedSections['totalNonCurrentLiabilities'] = getCOABalances(sections['longTermLiabilities'].sectionBalancesTotalByPeriod, filter, additionalBalancesOptions);
54
+ const totalLiabilitiesBalancesByPeriod = getSumOfBalancesByGroupedByPeriod([
55
+ totalCurrentLiabilitiesBalancesByPeriod ?? {},
56
+ sections['longTermLiabilities'].sectionBalancesTotalByPeriod,
57
+ ]);
58
+ calculatedSections['totalLiabilities'] = getCOABalances(totalLiabilitiesBalancesByPeriod, filter, additionalBalancesOptions);
59
+ calculatedSections['totalEquity'] = getCOABalances(sections['equity'].sectionBalancesTotalByPeriod, filter, additionalBalancesOptions);
60
+ const liabilitiesAndEquityBalancesByPeriod = getSumOfBalancesByGroupedByPeriod([
61
+ totalLiabilitiesBalancesByPeriod ?? {},
62
+ sections['equity'].sectionBalancesTotalByPeriod,
63
+ ]);
64
+ calculatedSections['liabilitiesAndEquity'] = getCOABalances(liabilitiesAndEquityBalancesByPeriod, filter, additionalBalancesOptions);
65
+ }
66
+ const classHierarchy = balanceSheetClassesViewState.classHierarchy;
67
+ return {
68
+ sections,
69
+ calculatedSections,
70
+ reportId: balanceSheetClassesViewState.reportId,
71
+ reportTitle: balanceSheetClassesViewState.reportTitle,
72
+ firstMonthOfFY: balanceSheetClassesViewState.firstMonthOfFY,
73
+ dataAvailable: balanceSheetClassesViewState.dataAvailable,
74
+ bookCloseDate: balanceSheetClassesViewState.bookCloseDate,
75
+ version: balanceSheetClassesViewState.version,
76
+ status: balanceSheetClassesViewState.status,
77
+ fetchState: fetchState.fetchState,
78
+ error: fetchState.error,
79
+ filter,
80
+ uiState: balanceSheetClassesViewState.uiState,
81
+ classHierarchy,
82
+ classesToFilterOut: balanceSheetClassesViewState.uiState.classesToFilterOut,
83
+ idsInOrder: balanceSheetSectionIdsInOrder,
84
+ rootSectionsWithSubSectionIds: {
85
+ assets: ASSET_IDS_IN_ORDER,
86
+ liabilities: LIABILITY_IDS_IN_ORDER,
87
+ equity: EQUITY_IDS_IN_ORDER,
88
+ },
89
+ };
90
+ };
@@ -0,0 +1,61 @@
1
+ import { from, of } from 'rxjs';
2
+ import { catchError, filter, mergeMap } from 'rxjs/operators';
3
+ import { updateSectionClassesView } from '../../entity/sectionClassesViewV2/sectionClassesViewReducer';
4
+ import { createZeniAPIStatus, isSuccessResponse } from '../../responsePayload';
5
+ import { toSectionId } from '../balanceSheet/balanceSheetPayload';
6
+ import { fetchBalanceSheetForTimeframeClassesView, updateBalanceSheetForTimeframeClassesView, updateBalanceSheetForTimeframeClassesViewFailure, } from './balanceSheetClassesViewReducer';
7
+ const getTimeSeriesGroup = (timeframe) => {
8
+ switch (timeframe) {
9
+ case 'month':
10
+ return 'months';
11
+ case 'quarter':
12
+ return 'quarters';
13
+ case 'year':
14
+ return 'years';
15
+ }
16
+ };
17
+ export const reportIdUniqueKey = () => 'balance_sheet_by_classes';
18
+ export const fetchBalanceSheetForTimeframeClassesViewEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchBalanceSheetForTimeframeClassesView.match), mergeMap((action) => {
19
+ const queryValue = {
20
+ // The report endpoint rejects a falsey is_full_response, so it is fixed.
21
+ is_full_response: true,
22
+ time_series_groups: [getTimeSeriesGroup(action.payload.timeframe)],
23
+ is_group_by_class: true,
24
+ // Only sent when refreshing: the flag makes the backend bypass its saved
25
+ // report and regenerate, so a normal lookup must not carry it.
26
+ ...(action.payload.cacheOverride === true
27
+ ? { is_hard_refresh: true }
28
+ : {}),
29
+ };
30
+ return zeniAPI
31
+ .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/2.0/reports/balance_sheet?query=${encodeURIComponent(JSON.stringify(queryValue))}`)
32
+ .pipe(mergeMap((response) => {
33
+ if (response.data != null && isSuccessResponse(response)) {
34
+ const actions = [];
35
+ const { report } = response.data;
36
+ const currency = report.currency;
37
+ actions.push(updateSectionClassesView(action.payload.timeframe, toSectionId('cash_and_equivalents'), reportIdUniqueKey(), report.assets.current_assets.cash_and_equivalents, report.classes, report.accounts, currency));
38
+ actions.push(updateSectionClassesView(action.payload.timeframe, toSectionId('accounts_receivable'), reportIdUniqueKey(), report.assets.current_assets.accounts_receivable, report.classes, report.accounts, currency));
39
+ actions.push(updateSectionClassesView(action.payload.timeframe, toSectionId('other_current_assets'), reportIdUniqueKey(), report.assets.current_assets.other_current_assets, report.classes, report.accounts, currency));
40
+ actions.push(updateSectionClassesView(action.payload.timeframe, toSectionId('fixed_assets'), reportIdUniqueKey(), report.assets.fixed_assets, report.classes, report.accounts, currency));
41
+ actions.push(updateSectionClassesView(action.payload.timeframe, toSectionId('other_assets'), reportIdUniqueKey(), report.assets.other_assets, report.classes, report.accounts, currency));
42
+ actions.push(updateSectionClassesView(action.payload.timeframe, toSectionId('accounts_payable'), reportIdUniqueKey(), report.liabilities.current_liabilities.accounts_payable, report.classes, report.accounts, currency));
43
+ actions.push(updateSectionClassesView(action.payload.timeframe, toSectionId('credit_cards'), reportIdUniqueKey(), report.liabilities.current_liabilities.credit_cards, report.classes, report.accounts, currency));
44
+ actions.push(updateSectionClassesView(action.payload.timeframe, toSectionId('other_current_liabilities'), reportIdUniqueKey(), report.liabilities.current_liabilities
45
+ .other_current_liabilities, report.classes, report.accounts, currency));
46
+ actions.push(updateSectionClassesView(action.payload.timeframe, toSectionId('long_term_liabilities'), reportIdUniqueKey(), report.liabilities.long_term_liabilities, report.classes, report.accounts, currency));
47
+ actions.push(updateSectionClassesView(action.payload.timeframe, toSectionId('equity'), reportIdUniqueKey(), report.equity, report.classes, report.accounts, currency));
48
+ actions.push(updateBalanceSheetForTimeframeClassesView({
49
+ timeframe: action.payload.timeframe,
50
+ report: response.data,
51
+ }));
52
+ return from(actions);
53
+ }
54
+ else {
55
+ return of(updateBalanceSheetForTimeframeClassesViewFailure(response.status, action.payload.timeframe));
56
+ }
57
+ }), catchError((error) => of(updateBalanceSheetForTimeframeClassesViewFailure(createZeniAPIStatus('Unexpected Error', 'Balance Sheet by Class REST API call errored out: ' +
58
+ (error instanceof Error
59
+ ? error.message
60
+ : JSON.stringify(error))), action.payload.timeframe))));
61
+ }));
@@ -0,0 +1,63 @@
1
+ import { from, of } from 'rxjs';
2
+ import { catchError, filter, mergeMap } from 'rxjs/operators';
3
+ import { updateProjects } from '../../entity/project/projectReducer';
4
+ import { updateSectionProjectView } from '../../entity/sectionProjectView/sectionProjectViewReducer';
5
+ import { createZeniAPIStatus, isSuccessResponse } from '../../responsePayload';
6
+ import { toSectionId } from '../balanceSheet/balanceSheetPayload';
7
+ import { fetchBalanceSheetForTimeframeProjectView, updateBalanceSheetForTimeframeProjectView, updateBalanceSheetForTimeframeProjectViewFailure, } from './balanceSheetProjectViewReducer';
8
+ const getTimeSeriesGroup = (timeframe) => {
9
+ switch (timeframe) {
10
+ case 'month':
11
+ return 'months';
12
+ case 'quarter':
13
+ return 'quarters';
14
+ case 'year':
15
+ return 'years';
16
+ }
17
+ };
18
+ export const reportIdUniqueKey = () => 'balance_sheet_by_projects';
19
+ export const fetchBalanceSheetForTimeframeProjectViewEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchBalanceSheetForTimeframeProjectView.match), mergeMap((action) => {
20
+ const queryValue = {
21
+ // The report endpoint rejects a falsey is_full_response, so it is fixed.
22
+ is_full_response: true,
23
+ time_series_groups: [getTimeSeriesGroup(action.payload.timeframe)],
24
+ is_group_by_project: true,
25
+ // Only sent when refreshing: the flag makes the backend bypass its saved
26
+ // report and regenerate, so a normal lookup must not carry it.
27
+ ...(action.payload.cacheOverride === true
28
+ ? { is_hard_refresh: true }
29
+ : {}),
30
+ };
31
+ return zeniAPI
32
+ .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/2.0/reports/balance_sheet?query=${encodeURIComponent(JSON.stringify(queryValue))}`)
33
+ .pipe(mergeMap((response) => {
34
+ if (response.data != null && isSuccessResponse(response)) {
35
+ const actions = [];
36
+ const { report } = response.data;
37
+ const currency = report.currency;
38
+ actions.push(updateProjects(report.projects));
39
+ actions.push(updateSectionProjectView(action.payload.timeframe, toSectionId('cash_and_equivalents'), reportIdUniqueKey(), report.assets.current_assets.cash_and_equivalents, report.accounts, currency));
40
+ actions.push(updateSectionProjectView(action.payload.timeframe, toSectionId('accounts_receivable'), reportIdUniqueKey(), report.assets.current_assets.accounts_receivable, report.accounts, currency));
41
+ actions.push(updateSectionProjectView(action.payload.timeframe, toSectionId('other_current_assets'), reportIdUniqueKey(), report.assets.current_assets.other_current_assets, report.accounts, currency));
42
+ actions.push(updateSectionProjectView(action.payload.timeframe, toSectionId('fixed_assets'), reportIdUniqueKey(), report.assets.fixed_assets, report.accounts, currency));
43
+ actions.push(updateSectionProjectView(action.payload.timeframe, toSectionId('other_assets'), reportIdUniqueKey(), report.assets.other_assets, report.accounts, currency));
44
+ actions.push(updateSectionProjectView(action.payload.timeframe, toSectionId('accounts_payable'), reportIdUniqueKey(), report.liabilities.current_liabilities.accounts_payable, report.accounts, currency));
45
+ actions.push(updateSectionProjectView(action.payload.timeframe, toSectionId('credit_cards'), reportIdUniqueKey(), report.liabilities.current_liabilities.credit_cards, report.accounts, currency));
46
+ actions.push(updateSectionProjectView(action.payload.timeframe, toSectionId('other_current_liabilities'), reportIdUniqueKey(), report.liabilities.current_liabilities
47
+ .other_current_liabilities, report.accounts, currency));
48
+ actions.push(updateSectionProjectView(action.payload.timeframe, toSectionId('long_term_liabilities'), reportIdUniqueKey(), report.liabilities.long_term_liabilities, report.accounts, currency));
49
+ actions.push(updateSectionProjectView(action.payload.timeframe, toSectionId('equity'), reportIdUniqueKey(), report.equity, report.accounts, currency));
50
+ actions.push(updateBalanceSheetForTimeframeProjectView({
51
+ timeframe: action.payload.timeframe,
52
+ report: response.data,
53
+ }));
54
+ return from(actions);
55
+ }
56
+ else {
57
+ return of(updateBalanceSheetForTimeframeProjectViewFailure(response.status, action.payload.timeframe));
58
+ }
59
+ }), catchError((error) => of(updateBalanceSheetForTimeframeProjectViewFailure(createZeniAPIStatus('Unexpected Error', 'Balance Sheet by Project REST API call errored out: ' +
60
+ (error instanceof Error
61
+ ? error.message
62
+ : JSON.stringify(error))), action.payload.timeframe))));
63
+ }));
@@ -0,0 +1,30 @@
1
+ import { from } from 'rxjs';
2
+ import { filter, switchMap } from 'rxjs/operators';
3
+ import { fetchBalanceSheetForTimeframeProjectView, fetchBalanceSheetProjectView, } from './balanceSheetProjectViewReducer';
4
+ export const fetchBalanceSheetProjectViewEpic = (actions$, state) => actions$.pipe(filter(fetchBalanceSheetProjectView.match), switchMap((action) => {
5
+ const { cacheOverride } = action.payload;
6
+ if (cacheOverride === true) {
7
+ return from([
8
+ fetchBalanceSheetForTimeframeProjectView('month', true),
9
+ fetchBalanceSheetForTimeframeProjectView('quarter', true),
10
+ fetchBalanceSheetForTimeframeProjectView('year', true),
11
+ ]);
12
+ }
13
+ else {
14
+ const fetchActions = [];
15
+ const projectFetchState = state.value.balanceSheetProjectViewState.fetchState;
16
+ if (projectFetchState['month'].fetchState !== 'In-Progress' &&
17
+ projectFetchState['month'].fetchState !== 'Completed') {
18
+ fetchActions.push(fetchBalanceSheetForTimeframeProjectView('month'));
19
+ }
20
+ if (projectFetchState['quarter'].fetchState !== 'In-Progress' &&
21
+ projectFetchState['quarter'].fetchState !== 'Completed') {
22
+ fetchActions.push(fetchBalanceSheetForTimeframeProjectView('quarter'));
23
+ }
24
+ if (projectFetchState['year'].fetchState !== 'In-Progress' &&
25
+ projectFetchState['year'].fetchState !== 'Completed') {
26
+ fetchActions.push(fetchBalanceSheetForTimeframeProjectView('year'));
27
+ }
28
+ return from(fetchActions);
29
+ }
30
+ }));
@@ -0,0 +1,128 @@
1
+ import { createSlice } from '@reduxjs/toolkit';
2
+ import { mapReportPayloadV2ToReportV2 } from '../../commonPayloadTypes/v2/viewAndReportPayloadv2';
3
+ import { clearAll } from '../../rootActions';
4
+ export const initialState = {
5
+ bookCloseDate: undefined,
6
+ fetchState: {
7
+ month: {
8
+ fetchState: 'Not-Started',
9
+ error: undefined,
10
+ },
11
+ quarter: {
12
+ fetchState: 'Not-Started',
13
+ error: undefined,
14
+ },
15
+ year: {
16
+ fetchState: 'Not-Started',
17
+ error: undefined,
18
+ },
19
+ },
20
+ firstMonthOfFY: 1,
21
+ projectIds: [],
22
+ reportId: 'balance_sheet_by_projects',
23
+ reportTitle: 'balance_sheet_by_projects',
24
+ uiState: {
25
+ accountViewMode: 'account_group',
26
+ nodeCollapseState: {},
27
+ projectsToFilterOut: [],
28
+ scrollPosition: undefined,
29
+ },
30
+ };
31
+ const balanceSheetProjectView = createSlice({
32
+ name: 'balanceSheetProjectView',
33
+ initialState,
34
+ reducers: {
35
+ fetchBalanceSheetProjectView: {
36
+ prepare(cacheOverride = false) {
37
+ return { payload: { cacheOverride } };
38
+ },
39
+ reducer(
40
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
41
+ _draft,
42
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
43
+ _action) {
44
+ // nothing to do here
45
+ },
46
+ },
47
+ fetchBalanceSheetForTimeframeProjectView: {
48
+ prepare(timeframe, cacheOverride = false) {
49
+ return { payload: { timeframe, cacheOverride } };
50
+ },
51
+ reducer(draft, action) {
52
+ const timeframe = action.payload.timeframe;
53
+ draft.fetchState[timeframe].fetchState = 'In-Progress';
54
+ draft.fetchState[timeframe].error = undefined;
55
+ },
56
+ },
57
+ updateBalanceSheetForTimeframeProjectView(draft, action) {
58
+ doUpdateBalanceSheetProjectView(draft, action.payload.timeframe, action.payload.report);
59
+ },
60
+ updateBalanceSheetForTimeframeProjectViewFailure: {
61
+ prepare(error, timeframe) {
62
+ return {
63
+ payload: {
64
+ error,
65
+ timeframe,
66
+ },
67
+ };
68
+ },
69
+ reducer(draft, action) {
70
+ draft.fetchState[action.payload.timeframe] = {
71
+ fetchState: 'Error',
72
+ error: action.payload.error,
73
+ };
74
+ },
75
+ },
76
+ updateBalanceSheetProjectsToFilterOut(draft, action) {
77
+ draft.uiState.projectsToFilterOut = action.payload.projectsToFilterOut;
78
+ },
79
+ updateBalanceSheetProjectViewUIState(draft, action) {
80
+ const { nodeCollapseState, scrollPosition, resetLeftScroll } = action.payload;
81
+ if (nodeCollapseState != null) {
82
+ draft.uiState.nodeCollapseState = Object.assign({}, draft.uiState.nodeCollapseState, {
83
+ [nodeCollapseState.nodeId]: nodeCollapseState.isCollapsed,
84
+ });
85
+ }
86
+ // Mutually exclusive: resetLeftScroll clears only scrollLeft from the
87
+ // recorded position, scrollPosition replaces the whole record.
88
+ if (resetLeftScroll === true && draft.uiState.scrollPosition != null) {
89
+ draft.uiState.scrollPosition.scrollLeft = undefined;
90
+ }
91
+ else if (scrollPosition != null) {
92
+ draft.uiState.scrollPosition = scrollPosition;
93
+ }
94
+ },
95
+ updateBalanceSheetProjectViewAccountViewMode(draft, action) {
96
+ draft.uiState.accountViewMode = action.payload.viewMode;
97
+ },
98
+ resetBalanceSheetProjectNodeCollapseState(draft) {
99
+ draft.uiState.nodeCollapseState = {};
100
+ },
101
+ clearBalanceSheetProjectView(draft) {
102
+ Object.assign(draft, initialState);
103
+ },
104
+ },
105
+ extraReducers: (builder) => {
106
+ builder.addCase(clearAll, (draft) => {
107
+ Object.assign(draft, initialState);
108
+ });
109
+ },
110
+ });
111
+ export const { fetchBalanceSheetProjectView, fetchBalanceSheetForTimeframeProjectView, updateBalanceSheetForTimeframeProjectView, updateBalanceSheetForTimeframeProjectViewFailure, updateBalanceSheetProjectsToFilterOut, updateBalanceSheetProjectViewUIState, updateBalanceSheetProjectViewAccountViewMode, resetBalanceSheetProjectNodeCollapseState, clearBalanceSheetProjectView, } = balanceSheetProjectView.actions;
112
+ export default balanceSheetProjectView.reducer;
113
+ const doUpdateBalanceSheetProjectView = (draft, timeframe, balanceSheetReport) => {
114
+ const report = mapReportPayloadV2ToReportV2(balanceSheetReport.report);
115
+ draft.currency = report.currency;
116
+ draft.dataAvailable = report.dataAvailable;
117
+ draft.firstMonthOfFY = report.firstMonthOfFY;
118
+ draft.bookCloseDate = report.bookCloseDate;
119
+ draft.status = report.status;
120
+ draft.fetchState[timeframe].fetchState = 'Completed';
121
+ draft.fetchState[timeframe].error = undefined;
122
+ // Populated once, as with classHierarchy in the classes view: a project added
123
+ // mid-session is not picked up until the store is cleared, even by a hard
124
+ // refresh. Matches profitAndLossProjectViewReducer.
125
+ if (draft.projectIds.length <= 0) {
126
+ draft.projectIds = balanceSheetReport.report.projects.map((project) => project.accounting_project_id);
127
+ }
128
+ };