@zeniai/client-epic-state 5.2.30 → 5.2.31
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.
- package/lib/commonStateTypes/coaBalance/classBalances/getSumOfBalancesGroupedByPeriod.js +16 -3
- package/lib/commonStateTypes/viewAndReport/reportIDHelper.d.ts +6 -0
- package/lib/commonStateTypes/viewAndReport/reportIDHelper.js +12 -1
- package/lib/commonStateTypes/viewAndReport/viewAndReport.d.ts +2 -2
- package/lib/commonStateTypes/viewAndReport/viewAndReport.js +2 -0
- package/lib/entity/accountGroup/accountGroupState.d.ts +1 -1
- package/lib/entity/class/classReducer.d.ts +4 -4
- package/lib/entity/class/classState.d.ts +1 -1
- package/lib/entity/forecast/forecastState.d.ts +1 -1
- package/lib/entity/sectionAccountsView/sectionAccountsView.d.ts +1 -1
- package/lib/entity/sectionClassesViewV2/sectionClassesView.d.ts +1 -1
- package/lib/entity/sectionClassesViewV2/sectionClassesViewEpic.js +2 -1
- package/lib/entity/sectionClassesViewV2/sectionClassesViewReducer.d.ts +2 -2
- package/lib/entity/sectionProjectView/sectionProjectView.d.ts +1 -1
- package/lib/entity/sectionProjectView/sectionProjectViewReducer.d.ts +2 -2
- package/lib/epic.d.ts +5 -1
- package/lib/epic.js +8 -0
- package/lib/esm/commonStateTypes/coaBalance/classBalances/getSumOfBalancesGroupedByPeriod.js +16 -3
- package/lib/esm/commonStateTypes/viewAndReport/reportIDHelper.js +7 -0
- package/lib/esm/commonStateTypes/viewAndReport/viewAndReport.js +2 -0
- package/lib/esm/entity/sectionClassesViewV2/sectionClassesViewEpic.js +2 -1
- package/lib/esm/epic.js +8 -0
- package/lib/esm/index.js +7 -3
- package/lib/esm/reducer.js +6 -0
- package/lib/esm/view/cashFlow/cashFlowGroupedSectionOrder.js +47 -0
- package/lib/esm/view/cashFlowClassesView/cashFlowClassesViewEpic.js +30 -0
- package/lib/esm/view/cashFlowClassesView/cashFlowClassesViewPayload.js +1 -0
- package/lib/esm/view/cashFlowClassesView/cashFlowClassesViewReducer.js +129 -0
- package/lib/esm/view/cashFlowClassesView/cashFlowClassesViewSelector.js +53 -0
- package/lib/esm/view/cashFlowClassesView/cashFlowClassesViewSelectorTypes.js +1 -0
- package/lib/esm/view/cashFlowClassesView/cashFlowClassesViewState.js +1 -0
- package/lib/esm/view/cashFlowClassesView/cashFlowForTimeframeClassesViewEpic.js +55 -0
- package/lib/esm/view/cashFlowProjectView/cashFlowForTimeframeProjectViewEpic.js +57 -0
- package/lib/esm/view/cashFlowProjectView/cashFlowProjectViewEpic.js +30 -0
- package/lib/esm/view/cashFlowProjectView/cashFlowProjectViewPayload.js +1 -0
- package/lib/esm/view/cashFlowProjectView/cashFlowProjectViewReducer.js +125 -0
- package/lib/esm/view/cashFlowProjectView/cashFlowProjectViewSelector.js +54 -0
- package/lib/esm/view/cashFlowProjectView/cashFlowProjectViewSelectorTypes.js +1 -0
- package/lib/esm/view/cashFlowProjectView/cashFlowProjectViewState.js +1 -0
- package/lib/esm/view/financeStatement/financeStatementSelector.js +21 -1
- package/lib/index.d.ts +11 -3
- package/lib/index.js +71 -48
- package/lib/reducer.d.ts +2 -0
- package/lib/reducer.js +6 -0
- package/lib/rootStateTypes.d.ts +4 -0
- package/lib/view/auditReportView/auditReportViewState.d.ts +1 -1
- package/lib/view/billPayCard/billPayCardSelector.d.ts +1 -1
- package/lib/view/cardBalance/cardBalanceSelector.d.ts +1 -1
- package/lib/view/cashBalance/cashBalanceSelector.d.ts +1 -1
- package/lib/view/cashFlow/cashFlowGroupedSectionOrder.d.ts +15 -0
- package/lib/view/cashFlow/cashFlowGroupedSectionOrder.js +50 -0
- package/lib/view/cashFlowClassesView/cashFlowClassesViewEpic.d.ts +6 -0
- package/lib/view/cashFlowClassesView/cashFlowClassesViewEpic.js +34 -0
- package/lib/view/cashFlowClassesView/cashFlowClassesViewPayload.d.ts +14 -0
- package/lib/view/cashFlowClassesView/cashFlowClassesViewPayload.js +2 -0
- package/lib/view/cashFlowClassesView/cashFlowClassesViewReducer.d.ts +34 -0
- package/lib/view/cashFlowClassesView/cashFlowClassesViewReducer.js +133 -0
- package/lib/view/cashFlowClassesView/cashFlowClassesViewSelector.d.ts +7 -0
- package/lib/view/cashFlowClassesView/cashFlowClassesViewSelector.js +57 -0
- package/lib/view/cashFlowClassesView/cashFlowClassesViewSelectorTypes.d.ts +15 -0
- package/lib/view/cashFlowClassesView/cashFlowClassesViewSelectorTypes.js +2 -0
- package/lib/view/cashFlowClassesView/cashFlowClassesViewState.d.ts +23 -0
- package/lib/view/cashFlowClassesView/cashFlowClassesViewState.js +2 -0
- package/lib/view/cashFlowClassesView/cashFlowForTimeframeClassesViewEpic.d.ts +9 -0
- package/lib/view/cashFlowClassesView/cashFlowForTimeframeClassesViewEpic.js +60 -0
- package/lib/view/cashFlowProjectView/cashFlowForTimeframeProjectViewEpic.d.ts +10 -0
- package/lib/view/cashFlowProjectView/cashFlowForTimeframeProjectViewEpic.js +62 -0
- package/lib/view/cashFlowProjectView/cashFlowProjectViewEpic.d.ts +6 -0
- package/lib/view/cashFlowProjectView/cashFlowProjectViewEpic.js +34 -0
- package/lib/view/cashFlowProjectView/cashFlowProjectViewPayload.d.ts +14 -0
- package/lib/view/cashFlowProjectView/cashFlowProjectViewPayload.js +2 -0
- package/lib/view/cashFlowProjectView/cashFlowProjectViewReducer.d.ts +33 -0
- package/lib/view/cashFlowProjectView/cashFlowProjectViewReducer.js +129 -0
- package/lib/view/cashFlowProjectView/cashFlowProjectViewSelector.d.ts +7 -0
- package/lib/view/cashFlowProjectView/cashFlowProjectViewSelector.js +58 -0
- package/lib/view/cashFlowProjectView/cashFlowProjectViewSelectorTypes.d.ts +19 -0
- package/lib/view/cashFlowProjectView/cashFlowProjectViewSelectorTypes.js +2 -0
- package/lib/view/cashFlowProjectView/cashFlowProjectViewState.d.ts +22 -0
- package/lib/view/cashFlowProjectView/cashFlowProjectViewState.js +2 -0
- package/lib/view/cashInCashOut/cashInCashOutSelector.d.ts +1 -1
- package/lib/view/cashPosition/cashPositionSelector.d.ts +1 -1
- package/lib/view/dashboard/dashboardReducer.d.ts +2 -2
- package/lib/view/financeStatement/financeStatementReducer.d.ts +1 -1
- package/lib/view/financeStatement/financeStatementSelector.d.ts +4 -0
- package/lib/view/financeStatement/financeStatementSelector.js +21 -1
- package/lib/view/globalMerchantView/globalMerchantViewReducer.d.ts +2 -2
- package/lib/view/reimbursementCard/reimbursementCardSelector.d.ts +1 -1
- package/lib/view/reportsResync/reportsResyncReducer.d.ts +2 -2
- package/lib/view/tasksCard/tasksCardSelector.d.ts +1 -1
- package/lib/view/topEx/topExSelector.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,129 @@
|
|
|
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: 'cash_flow_by_classes',
|
|
31
|
+
reportTitle: 'cash_flow_by_classes',
|
|
32
|
+
};
|
|
33
|
+
const cashFlowClassesView = createSlice({
|
|
34
|
+
name: 'cashFlowClassesView',
|
|
35
|
+
initialState,
|
|
36
|
+
reducers: {
|
|
37
|
+
fetchCashFlowClassesView: {
|
|
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
|
+
fetchCashFlowForTimeframeClassesView: {
|
|
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
|
+
updateCashFlowForTimeframeClassesView(draft, action) {
|
|
60
|
+
doUpdateCashFlowClassesView(draft, action.payload.timeframe, action.payload.report);
|
|
61
|
+
},
|
|
62
|
+
updateCashFlowForTimeframeClassesViewFailure: {
|
|
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
|
+
updateCashFlowClassesToFilterOut(draft, action) {
|
|
79
|
+
draft.uiState.classesToFilterOut = action.payload.classesToFilterOut;
|
|
80
|
+
},
|
|
81
|
+
updateCashFlowClassesViewUIState(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
|
+
updateCashFlowClassesViewAccountViewMode(draft, action) {
|
|
98
|
+
draft.uiState.accountViewMode = action.payload.viewMode;
|
|
99
|
+
},
|
|
100
|
+
resetCashFlowClassesNodeCollapseState(draft) {
|
|
101
|
+
draft.uiState.nodeCollapseState = {};
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
extraReducers: (builder) => {
|
|
105
|
+
builder.addCase(clearAll, (draft) => {
|
|
106
|
+
Object.assign(draft, initialState);
|
|
107
|
+
});
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
export const { fetchCashFlowClassesView, fetchCashFlowForTimeframeClassesView, updateCashFlowForTimeframeClassesView, updateCashFlowForTimeframeClassesViewFailure, updateCashFlowClassesToFilterOut, updateCashFlowClassesViewUIState, updateCashFlowClassesViewAccountViewMode, resetCashFlowClassesNodeCollapseState, } = cashFlowClassesView.actions;
|
|
111
|
+
export default cashFlowClassesView.reducer;
|
|
112
|
+
const doUpdateCashFlowClassesView = (draft, timeframe, cashFlowReport) => {
|
|
113
|
+
const report = mapReportPayloadV2ToReportV2(cashFlowReport.report);
|
|
114
|
+
draft.currency = report.currency;
|
|
115
|
+
draft.dataAvailable = report.dataAvailable;
|
|
116
|
+
draft.firstMonthOfFY = report.firstMonthOfFY;
|
|
117
|
+
draft.bookCloseDate = report.bookCloseDate;
|
|
118
|
+
draft.status = report.status;
|
|
119
|
+
draft.fetchState[timeframe].fetchState = 'Completed';
|
|
120
|
+
draft.fetchState[timeframe].error = undefined;
|
|
121
|
+
const classMetadata = cashFlowReport.report.classes.map((eachClass) => toClassMetadata(eachClass));
|
|
122
|
+
// Populated once and then left alone, so a per-timeframe response cannot
|
|
123
|
+
// clobber a hierarchy built from a full one. A class added mid-session is
|
|
124
|
+
// therefore not picked up until the store is cleared, even by a hard refresh —
|
|
125
|
+
// the same trade-off profitAndLossClassesViewReducer makes.
|
|
126
|
+
if (draft.classHierarchy.length <= 0) {
|
|
127
|
+
draft.classHierarchy = geNestedClassIDHierarchyForReport(classMetadata);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { getCOABalances } from '../../commonStateTypes/coaBalance/getCOABalancesSlice';
|
|
2
|
+
import { reduceFetchStateParallelTimeframes } from '../../commonStateTypes/reduceFetchState';
|
|
3
|
+
import { getSectionClassesViewReport } from '../../entity/sectionClassesViewV2/sectionClassesViewSelector';
|
|
4
|
+
import { CASH_FLOW_GROUPED_BREAKDOWN_IDS, CASH_FLOW_GROUPED_CALCULATED_IDS, CASH_FLOW_GROUPED_FINANCING_IDS_IN_ORDER, CASH_FLOW_GROUPED_IDS_IN_ORDER, CASH_FLOW_GROUPED_INVESTING_IDS_IN_ORDER, CASH_FLOW_GROUPED_OPERATING_IDS_IN_ORDER, } from '../cashFlow/cashFlowGroupedSectionOrder';
|
|
5
|
+
export const getCashFlowClassesView = (filter, accountState, classState, sectionsState, cashFlowClassesViewState) => {
|
|
6
|
+
const fetchState = reduceFetchStateParallelTimeframes([
|
|
7
|
+
cashFlowClassesViewState.fetchState.month,
|
|
8
|
+
cashFlowClassesViewState.fetchState.quarter,
|
|
9
|
+
cashFlowClassesViewState.fetchState.year,
|
|
10
|
+
]);
|
|
11
|
+
const reportId = 'cash_flow_by_classes';
|
|
12
|
+
const sections = {};
|
|
13
|
+
const calculatedSections = {};
|
|
14
|
+
if (fetchState.fetchState === 'Completed') {
|
|
15
|
+
CASH_FLOW_GROUPED_BREAKDOWN_IDS.forEach((sectionId) => {
|
|
16
|
+
sections[sectionId] = getSectionClassesViewReport(accountState, classState, sectionsState, { reportId, sectionId }, filter);
|
|
17
|
+
});
|
|
18
|
+
// These come back grouped, so each figure is read through the section layer
|
|
19
|
+
// and arrives already pruned by the class/project picker — the same source
|
|
20
|
+
// the breakdown rows above render from, so the two can never disagree.
|
|
21
|
+
CASH_FLOW_GROUPED_CALCULATED_IDS.forEach((calculatedSectionId) => {
|
|
22
|
+
calculatedSections[calculatedSectionId] = getCOABalances(
|
|
23
|
+
// Already built by the breakdown loop above; rebuilding it would repeat
|
|
24
|
+
// the whole section walk on every recompute.
|
|
25
|
+
sections[calculatedSectionId].sectionBalancesTotalByPeriod, filter);
|
|
26
|
+
});
|
|
27
|
+
calculatedSections['investingActivitiesTotal'] = getCOABalances(sections['investingActivities'].sectionBalancesTotalByPeriod, filter);
|
|
28
|
+
calculatedSections['financingActivitiesTotal'] = getCOABalances(sections['financingActivities'].sectionBalancesTotalByPeriod, filter);
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
sections,
|
|
32
|
+
calculatedSections,
|
|
33
|
+
fetchState: fetchState.fetchState,
|
|
34
|
+
error: fetchState.error,
|
|
35
|
+
filter,
|
|
36
|
+
uiState: cashFlowClassesViewState.uiState,
|
|
37
|
+
classHierarchy: cashFlowClassesViewState.classHierarchy,
|
|
38
|
+
classesToFilterOut: cashFlowClassesViewState.uiState.classesToFilterOut,
|
|
39
|
+
reportId: cashFlowClassesViewState.reportId,
|
|
40
|
+
reportTitle: cashFlowClassesViewState.reportTitle,
|
|
41
|
+
firstMonthOfFY: cashFlowClassesViewState.firstMonthOfFY,
|
|
42
|
+
dataAvailable: cashFlowClassesViewState.dataAvailable,
|
|
43
|
+
bookCloseDate: cashFlowClassesViewState.bookCloseDate,
|
|
44
|
+
version: cashFlowClassesViewState.version,
|
|
45
|
+
status: cashFlowClassesViewState.status,
|
|
46
|
+
idsInOrder: CASH_FLOW_GROUPED_IDS_IN_ORDER,
|
|
47
|
+
rootSectionsWithSubSectionIds: {
|
|
48
|
+
operatingActivities: CASH_FLOW_GROUPED_OPERATING_IDS_IN_ORDER,
|
|
49
|
+
investingActivities: CASH_FLOW_GROUPED_INVESTING_IDS_IN_ORDER,
|
|
50
|
+
financingActivities: CASH_FLOW_GROUPED_FINANCING_IDS_IN_ORDER,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
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 { toCashFlowReportViewID } from '../cashFlow/cashFlowPayload';
|
|
6
|
+
import { fetchCashFlowForTimeframeClassesView, updateCashFlowForTimeframeClassesView, updateCashFlowForTimeframeClassesViewFailure, } from './cashFlowClassesViewReducer';
|
|
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 = () => 'cash_flow_by_classes';
|
|
18
|
+
export const fetchCashFlowForTimeframeClassesViewEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchCashFlowForTimeframeClassesView.match), mergeMap((action) => {
|
|
19
|
+
const queryValue = {
|
|
20
|
+
is_full_response: true,
|
|
21
|
+
time_series_groups: [getTimeSeriesGroup(action.payload.timeframe)],
|
|
22
|
+
is_group_by_class: true,
|
|
23
|
+
// Only sent when refreshing: the flag makes the backend bypass its saved
|
|
24
|
+
// report and regenerate, so a normal lookup must not carry it.
|
|
25
|
+
...(action.payload.cacheOverride === true
|
|
26
|
+
? { is_hard_refresh: true }
|
|
27
|
+
: {}),
|
|
28
|
+
};
|
|
29
|
+
return zeniAPI
|
|
30
|
+
.getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/2.0/reports/cash_flow?query=${encodeURIComponent(JSON.stringify(queryValue))}`)
|
|
31
|
+
.pipe(mergeMap((response) => {
|
|
32
|
+
if (response.data != null && isSuccessResponse(response)) {
|
|
33
|
+
const actions = [];
|
|
34
|
+
const { report } = response.data;
|
|
35
|
+
const currency = report.currency;
|
|
36
|
+
actions.push(updateSectionClassesView(action.payload.timeframe, toCashFlowReportViewID('adjustments'), reportIdUniqueKey(), report.operating_activities.adjustments, report.classes, report.accounts, currency));
|
|
37
|
+
actions.push(updateSectionClassesView(action.payload.timeframe, toCashFlowReportViewID('investing_activities'), reportIdUniqueKey(), report.investing_activities, report.classes, report.accounts, currency));
|
|
38
|
+
actions.push(updateSectionClassesView(action.payload.timeframe, toCashFlowReportViewID('financing_activities'), reportIdUniqueKey(), report.financing_activities, report.classes, report.accounts, currency));
|
|
39
|
+
actions.push(updateSectionClassesView(action.payload.timeframe, toCashFlowReportViewID('net_income'), reportIdUniqueKey(), report.operating_activities.net_income, report.classes, report.accounts, currency));
|
|
40
|
+
actions.push(updateSectionClassesView(action.payload.timeframe, toCashFlowReportViewID('operating_activities'), reportIdUniqueKey(), report.operating_activities, report.classes, report.accounts, currency));
|
|
41
|
+
actions.push(updateSectionClassesView(action.payload.timeframe, toCashFlowReportViewID('change_in_cash_and_equivalents'), reportIdUniqueKey(), report.change_in_cash_and_equivalents, report.classes, report.accounts, currency));
|
|
42
|
+
actions.push(updateCashFlowForTimeframeClassesView({
|
|
43
|
+
timeframe: action.payload.timeframe,
|
|
44
|
+
report: response.data,
|
|
45
|
+
}));
|
|
46
|
+
return from(actions);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
return of(updateCashFlowForTimeframeClassesViewFailure(response.status, action.payload.timeframe));
|
|
50
|
+
}
|
|
51
|
+
}), catchError((error) => of(updateCashFlowForTimeframeClassesViewFailure(createZeniAPIStatus('Unexpected Error', 'Cash Flow by Class REST API call errored out: ' +
|
|
52
|
+
(error instanceof Error
|
|
53
|
+
? error.message
|
|
54
|
+
: JSON.stringify(error))), action.payload.timeframe))));
|
|
55
|
+
}));
|
|
@@ -0,0 +1,57 @@
|
|
|
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 { toCashFlowReportViewID } from '../cashFlow/cashFlowPayload';
|
|
7
|
+
import { fetchCashFlowForTimeframeProjectView, updateCashFlowForTimeframeProjectView, updateCashFlowForTimeframeProjectViewFailure, } from './cashFlowProjectViewReducer';
|
|
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 = () => 'cash_flow_by_projects';
|
|
19
|
+
export const fetchCashFlowForTimeframeProjectViewEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchCashFlowForTimeframeProjectView.match), mergeMap((action) => {
|
|
20
|
+
const queryValue = {
|
|
21
|
+
is_full_response: true,
|
|
22
|
+
time_series_groups: [getTimeSeriesGroup(action.payload.timeframe)],
|
|
23
|
+
is_group_by_project: 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/cash_flow?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(updateProjects(report.projects));
|
|
38
|
+
actions.push(updateSectionProjectView(action.payload.timeframe, toCashFlowReportViewID('adjustments'), reportIdUniqueKey(), report.operating_activities.adjustments, report.accounts, currency));
|
|
39
|
+
actions.push(updateSectionProjectView(action.payload.timeframe, toCashFlowReportViewID('investing_activities'), reportIdUniqueKey(), report.investing_activities, report.accounts, currency));
|
|
40
|
+
actions.push(updateSectionProjectView(action.payload.timeframe, toCashFlowReportViewID('financing_activities'), reportIdUniqueKey(), report.financing_activities, report.accounts, currency));
|
|
41
|
+
actions.push(updateSectionProjectView(action.payload.timeframe, toCashFlowReportViewID('net_income'), reportIdUniqueKey(), report.operating_activities.net_income, report.accounts, currency));
|
|
42
|
+
actions.push(updateSectionProjectView(action.payload.timeframe, toCashFlowReportViewID('operating_activities'), reportIdUniqueKey(), report.operating_activities, report.accounts, currency));
|
|
43
|
+
actions.push(updateSectionProjectView(action.payload.timeframe, toCashFlowReportViewID('change_in_cash_and_equivalents'), reportIdUniqueKey(), report.change_in_cash_and_equivalents, report.accounts, currency));
|
|
44
|
+
actions.push(updateCashFlowForTimeframeProjectView({
|
|
45
|
+
timeframe: action.payload.timeframe,
|
|
46
|
+
report: response.data,
|
|
47
|
+
}));
|
|
48
|
+
return from(actions);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
return of(updateCashFlowForTimeframeProjectViewFailure(response.status, action.payload.timeframe));
|
|
52
|
+
}
|
|
53
|
+
}), catchError((error) => of(updateCashFlowForTimeframeProjectViewFailure(createZeniAPIStatus('Unexpected Error', 'Cash Flow by Project REST API call errored out: ' +
|
|
54
|
+
(error instanceof Error
|
|
55
|
+
? error.message
|
|
56
|
+
: JSON.stringify(error))), action.payload.timeframe))));
|
|
57
|
+
}));
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { from } from 'rxjs';
|
|
2
|
+
import { filter, switchMap } from 'rxjs/operators';
|
|
3
|
+
import { fetchCashFlowForTimeframeProjectView, fetchCashFlowProjectView, } from './cashFlowProjectViewReducer';
|
|
4
|
+
export const fetchCashFlowProjectViewEpic = (actions$, state) => actions$.pipe(filter(fetchCashFlowProjectView.match), switchMap((action) => {
|
|
5
|
+
const { cacheOverride } = action.payload;
|
|
6
|
+
if (cacheOverride === true) {
|
|
7
|
+
return from([
|
|
8
|
+
fetchCashFlowForTimeframeProjectView('month', true),
|
|
9
|
+
fetchCashFlowForTimeframeProjectView('quarter', true),
|
|
10
|
+
fetchCashFlowForTimeframeProjectView('year', true),
|
|
11
|
+
]);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
const fetchActions = [];
|
|
15
|
+
const projectFetchState = state.value.cashFlowProjectViewState.fetchState;
|
|
16
|
+
if (projectFetchState['month'].fetchState !== 'In-Progress' &&
|
|
17
|
+
projectFetchState['month'].fetchState !== 'Completed') {
|
|
18
|
+
fetchActions.push(fetchCashFlowForTimeframeProjectView('month'));
|
|
19
|
+
}
|
|
20
|
+
if (projectFetchState['quarter'].fetchState !== 'In-Progress' &&
|
|
21
|
+
projectFetchState['quarter'].fetchState !== 'Completed') {
|
|
22
|
+
fetchActions.push(fetchCashFlowForTimeframeProjectView('quarter'));
|
|
23
|
+
}
|
|
24
|
+
if (projectFetchState['year'].fetchState !== 'In-Progress' &&
|
|
25
|
+
projectFetchState['year'].fetchState !== 'Completed') {
|
|
26
|
+
fetchActions.push(fetchCashFlowForTimeframeProjectView('year'));
|
|
27
|
+
}
|
|
28
|
+
return from(fetchActions);
|
|
29
|
+
}
|
|
30
|
+
}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,125 @@
|
|
|
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: 'cash_flow_by_projects',
|
|
23
|
+
reportTitle: 'cash_flow_by_projects',
|
|
24
|
+
uiState: {
|
|
25
|
+
accountViewMode: 'account_group',
|
|
26
|
+
nodeCollapseState: {},
|
|
27
|
+
projectsToFilterOut: [],
|
|
28
|
+
scrollPosition: undefined,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
const cashFlowProjectView = createSlice({
|
|
32
|
+
name: 'cashFlowProjectView',
|
|
33
|
+
initialState,
|
|
34
|
+
reducers: {
|
|
35
|
+
fetchCashFlowProjectView: {
|
|
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
|
+
fetchCashFlowForTimeframeProjectView: {
|
|
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
|
+
updateCashFlowForTimeframeProjectView(draft, action) {
|
|
58
|
+
doUpdateCashFlowProjectView(draft, action.payload.timeframe, action.payload.report);
|
|
59
|
+
},
|
|
60
|
+
updateCashFlowForTimeframeProjectViewFailure: {
|
|
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
|
+
updateCashFlowProjectsToFilterOut(draft, action) {
|
|
77
|
+
draft.uiState.projectsToFilterOut = action.payload.projectsToFilterOut;
|
|
78
|
+
},
|
|
79
|
+
updateCashFlowProjectViewUIState(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
|
+
updateCashFlowProjectViewAccountViewMode(draft, action) {
|
|
96
|
+
draft.uiState.accountViewMode = action.payload.viewMode;
|
|
97
|
+
},
|
|
98
|
+
resetCashFlowProjectNodeCollapseState(draft) {
|
|
99
|
+
draft.uiState.nodeCollapseState = {};
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
extraReducers: (builder) => {
|
|
103
|
+
builder.addCase(clearAll, (draft) => {
|
|
104
|
+
Object.assign(draft, initialState);
|
|
105
|
+
});
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
export const { fetchCashFlowProjectView, fetchCashFlowForTimeframeProjectView, updateCashFlowForTimeframeProjectView, updateCashFlowForTimeframeProjectViewFailure, updateCashFlowProjectsToFilterOut, updateCashFlowProjectViewUIState, updateCashFlowProjectViewAccountViewMode, resetCashFlowProjectNodeCollapseState, } = cashFlowProjectView.actions;
|
|
109
|
+
export default cashFlowProjectView.reducer;
|
|
110
|
+
const doUpdateCashFlowProjectView = (draft, timeframe, cashFlowReport) => {
|
|
111
|
+
const report = mapReportPayloadV2ToReportV2(cashFlowReport.report);
|
|
112
|
+
draft.currency = report.currency;
|
|
113
|
+
draft.dataAvailable = report.dataAvailable;
|
|
114
|
+
draft.firstMonthOfFY = report.firstMonthOfFY;
|
|
115
|
+
draft.bookCloseDate = report.bookCloseDate;
|
|
116
|
+
draft.status = report.status;
|
|
117
|
+
draft.fetchState[timeframe].fetchState = 'Completed';
|
|
118
|
+
draft.fetchState[timeframe].error = undefined;
|
|
119
|
+
// Populated once, as with classHierarchy in the classes view: a project added
|
|
120
|
+
// mid-session is not picked up until the store is cleared, even by a hard
|
|
121
|
+
// refresh. Matches profitAndLossProjectViewReducer.
|
|
122
|
+
if (draft.projectIds.length <= 0) {
|
|
123
|
+
draft.projectIds = cashFlowReport.report.projects.map((project) => project.accounting_project_id);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { getCOABalances } from '../../commonStateTypes/coaBalance/getCOABalancesSlice';
|
|
2
|
+
import { reduceFetchStateParallelTimeframes } from '../../commonStateTypes/reduceFetchState';
|
|
3
|
+
import { getProjectsByIds } from '../../entity/project/projectSelector';
|
|
4
|
+
import { getSectionProjectViewReport } from '../../entity/sectionProjectView/sectionProjectViewSelector';
|
|
5
|
+
import { CASH_FLOW_GROUPED_BREAKDOWN_IDS, CASH_FLOW_GROUPED_CALCULATED_IDS, CASH_FLOW_GROUPED_FINANCING_IDS_IN_ORDER, CASH_FLOW_GROUPED_IDS_IN_ORDER, CASH_FLOW_GROUPED_INVESTING_IDS_IN_ORDER, CASH_FLOW_GROUPED_OPERATING_IDS_IN_ORDER, } from '../cashFlow/cashFlowGroupedSectionOrder';
|
|
6
|
+
export const getCashFlowProjectView = (filter, accountState, projectState, sectionsState, cashFlowProjectViewState) => {
|
|
7
|
+
const fetchState = reduceFetchStateParallelTimeframes([
|
|
8
|
+
cashFlowProjectViewState.fetchState.month,
|
|
9
|
+
cashFlowProjectViewState.fetchState.quarter,
|
|
10
|
+
cashFlowProjectViewState.fetchState.year,
|
|
11
|
+
]);
|
|
12
|
+
const reportId = 'cash_flow_by_projects';
|
|
13
|
+
const sections = {};
|
|
14
|
+
const calculatedSections = {};
|
|
15
|
+
if (fetchState.fetchState === 'Completed') {
|
|
16
|
+
CASH_FLOW_GROUPED_BREAKDOWN_IDS.forEach((sectionId) => {
|
|
17
|
+
sections[sectionId] = getSectionProjectViewReport(accountState, projectState, sectionsState, cashFlowProjectViewState.projectIds, { reportId, sectionId }, filter);
|
|
18
|
+
});
|
|
19
|
+
// These come back grouped, so each figure is read through the section layer
|
|
20
|
+
// and arrives already pruned by the class/project picker — the same source
|
|
21
|
+
// the breakdown rows above render from, so the two can never disagree.
|
|
22
|
+
CASH_FLOW_GROUPED_CALCULATED_IDS.forEach((calculatedSectionId) => {
|
|
23
|
+
calculatedSections[calculatedSectionId] = getCOABalances(
|
|
24
|
+
// Already built by the breakdown loop above; rebuilding it would repeat
|
|
25
|
+
// the whole section walk on every recompute.
|
|
26
|
+
sections[calculatedSectionId].sectionBalancesTotalByPeriod, filter);
|
|
27
|
+
});
|
|
28
|
+
calculatedSections['investingActivitiesTotal'] = getCOABalances(sections['investingActivities'].sectionBalancesTotalByPeriod, filter);
|
|
29
|
+
calculatedSections['financingActivitiesTotal'] = getCOABalances(sections['financingActivities'].sectionBalancesTotalByPeriod, filter);
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
sections,
|
|
33
|
+
calculatedSections,
|
|
34
|
+
fetchState: fetchState.fetchState,
|
|
35
|
+
error: fetchState.error,
|
|
36
|
+
filter,
|
|
37
|
+
uiState: cashFlowProjectViewState.uiState,
|
|
38
|
+
projects: getProjectsByIds(projectState, cashFlowProjectViewState.projectIds),
|
|
39
|
+
projectsToFilterOut: cashFlowProjectViewState.uiState.projectsToFilterOut,
|
|
40
|
+
reportId: cashFlowProjectViewState.reportId,
|
|
41
|
+
reportTitle: cashFlowProjectViewState.reportTitle,
|
|
42
|
+
firstMonthOfFY: cashFlowProjectViewState.firstMonthOfFY,
|
|
43
|
+
dataAvailable: cashFlowProjectViewState.dataAvailable,
|
|
44
|
+
bookCloseDate: cashFlowProjectViewState.bookCloseDate,
|
|
45
|
+
version: cashFlowProjectViewState.version,
|
|
46
|
+
status: cashFlowProjectViewState.status,
|
|
47
|
+
idsInOrder: CASH_FLOW_GROUPED_IDS_IN_ORDER,
|
|
48
|
+
rootSectionsWithSubSectionIds: {
|
|
49
|
+
operatingActivities: CASH_FLOW_GROUPED_OPERATING_IDS_IN_ORDER,
|
|
50
|
+
investingActivities: CASH_FLOW_GROUPED_INVESTING_IDS_IN_ORDER,
|
|
51
|
+
financingActivities: CASH_FLOW_GROUPED_FINANCING_IDS_IN_ORDER,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -11,6 +11,8 @@ import { getBalanceSheet } from '../balanceSheet/balanceSheetSelector';
|
|
|
11
11
|
import { getBalanceSheetClassesView } from '../balanceSheetClassesView/balanceSheetClassesViewSelector';
|
|
12
12
|
import { getBalanceSheetProjectView } from '../balanceSheetProjectView/balanceSheetProjectViewSelector';
|
|
13
13
|
import { getCashFlow } from '../cashFlow/cashFlowSelector';
|
|
14
|
+
import { getCashFlowClassesView } from '../cashFlowClassesView/cashFlowClassesViewSelector';
|
|
15
|
+
import { getCashFlowProjectView } from '../cashFlowProjectView/cashFlowProjectViewSelector';
|
|
14
16
|
import { getProfitAndLossReport, } from '../profitAndLoss/profitAndLossSelector';
|
|
15
17
|
import { getProfitAndLossClassesHorizontalView } from '../profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelector';
|
|
16
18
|
import { getProfitAndLossClassesView } from '../profitAndLossClassesView/profitAndLossClassesViewSelector';
|
|
@@ -39,7 +41,7 @@ function getFirstMonthOfFY(profitAndLossState, balanceSheetState, cashFlowState)
|
|
|
39
41
|
cashFlowState.firstMonthOfFY ??
|
|
40
42
|
1);
|
|
41
43
|
}
|
|
42
|
-
export const getFinanceStatement = createSelector((state) => state.accountState, (state) => state.accountGroupState, (state) => state.classState, (state) => state.sectionClassesViewStateV2, (state) => state.profitAndLossState, (state) => state.profitAndLossClassesViewState, (state) => state.projectState, (state) => state.sectionProjectViewState, (state) => state.profitAndLossProjectViewState, (state) => state.balanceSheetState, (state) => state.balanceSheetClassesViewState, (state) => state.balanceSheetProjectViewState, (state) => state.cashFlowState, (state) => state.financeStatementState, (state) => state.sectionAccountsViewState, (state) => state.forecastState, (accountState, accountGroupState, classState, sectionsState, profitAndLossState, profitAndLossClassesViewState, projectState, sectionProjectViewState, profitAndLossProjectViewState, balanceSheetState, balanceSheetClassesViewState, balanceSheetProjectViewState, cashFlowState, financeStatementState, sectionAccountsViewState, forecastState) => {
|
|
44
|
+
export const getFinanceStatement = createSelector((state) => state.accountState, (state) => state.accountGroupState, (state) => state.classState, (state) => state.sectionClassesViewStateV2, (state) => state.profitAndLossState, (state) => state.profitAndLossClassesViewState, (state) => state.projectState, (state) => state.sectionProjectViewState, (state) => state.profitAndLossProjectViewState, (state) => state.balanceSheetState, (state) => state.balanceSheetClassesViewState, (state) => state.balanceSheetProjectViewState, (state) => state.cashFlowState, (state) => state.cashFlowClassesViewState, (state) => state.cashFlowProjectViewState, (state) => state.financeStatementState, (state) => state.sectionAccountsViewState, (state) => state.forecastState, (accountState, accountGroupState, classState, sectionsState, profitAndLossState, profitAndLossClassesViewState, projectState, sectionProjectViewState, profitAndLossProjectViewState, balanceSheetState, balanceSheetClassesViewState, balanceSheetProjectViewState, cashFlowState, cashFlowClassesViewState, cashFlowProjectViewState, financeStatementState, sectionAccountsViewState, forecastState) => {
|
|
43
45
|
// to get min and max dates across three reports
|
|
44
46
|
let allTimeframeTicks = [];
|
|
45
47
|
let balancesInTimeframe = [];
|
|
@@ -81,6 +83,10 @@ export const getFinanceStatement = createSelector((state) => state.accountState,
|
|
|
81
83
|
const balanceSheetReport = getBalanceSheet(filter, accountState, accountGroupState, sectionAccountsViewState, balanceSheetState);
|
|
82
84
|
const balanceSheetClassFilter = newBalancesFilterClassesView(filter.firstMonthOfFY, filter.timeframe, filter.balancesRange.numberOfPeriods, filter.balancesRange.thisPeriod, filter.balancesRange.orderBy, filter.additionalBalances, balanceSheetClassesViewState.uiState.classesToFilterOut);
|
|
83
85
|
const balanceSheetByClassReport = getBalanceSheetClassesView(balanceSheetClassFilter, accountState, classState, sectionsState, balanceSheetClassesViewState);
|
|
86
|
+
const cashFlowClassFilter = newBalancesFilterClassesView(filter.firstMonthOfFY, filter.timeframe, filter.balancesRange.numberOfPeriods, filter.balancesRange.thisPeriod, filter.balancesRange.orderBy, filter.additionalBalances, cashFlowClassesViewState.uiState.classesToFilterOut);
|
|
87
|
+
const cashFlowByClassReport = getCashFlowClassesView(cashFlowClassFilter, accountState, classState, sectionsState, cashFlowClassesViewState);
|
|
88
|
+
const cashFlowProjectFilter = newBalancesFilterProjectView(filter.firstMonthOfFY, filter.timeframe, filter.balancesRange.numberOfPeriods, filter.balancesRange.thisPeriod, filter.balancesRange.orderBy, filter.additionalBalances, cashFlowProjectViewState.uiState.projectsToFilterOut);
|
|
89
|
+
const cashFlowByProjectReport = getCashFlowProjectView(cashFlowProjectFilter, accountState, projectState, sectionProjectViewState, cashFlowProjectViewState);
|
|
84
90
|
const balanceSheetProjectFilter = newBalancesFilterProjectView(filter.firstMonthOfFY, filter.timeframe, filter.balancesRange.numberOfPeriods, filter.balancesRange.thisPeriod, filter.balancesRange.orderBy, filter.additionalBalances, balanceSheetProjectViewState.uiState.projectsToFilterOut);
|
|
85
91
|
const balanceSheetByProjectReport = getBalanceSheetProjectView(balanceSheetProjectFilter, accountState, projectState, sectionProjectViewState, balanceSheetProjectViewState);
|
|
86
92
|
const cashFlowReport = getCashFlow(filter, accountState, accountGroupState, sectionAccountsViewState, cashFlowState);
|
|
@@ -129,6 +135,18 @@ export const getFinanceStatement = createSelector((state) => state.accountState,
|
|
|
129
135
|
error: cashFlowReport.error,
|
|
130
136
|
};
|
|
131
137
|
break;
|
|
138
|
+
case 'cash_flow_by_classes':
|
|
139
|
+
selectedReportAndTimeframeFetchState = {
|
|
140
|
+
fetchState: cashFlowByClassReport.fetchState,
|
|
141
|
+
error: cashFlowByClassReport.error,
|
|
142
|
+
};
|
|
143
|
+
break;
|
|
144
|
+
case 'cash_flow_by_projects':
|
|
145
|
+
selectedReportAndTimeframeFetchState = {
|
|
146
|
+
fetchState: cashFlowByProjectReport.fetchState,
|
|
147
|
+
error: cashFlowByProjectReport.error,
|
|
148
|
+
};
|
|
149
|
+
break;
|
|
132
150
|
default:
|
|
133
151
|
break;
|
|
134
152
|
}
|
|
@@ -151,6 +169,8 @@ export const getFinanceStatement = createSelector((state) => state.accountState,
|
|
|
151
169
|
profitAndLossByClassHorizontalReport,
|
|
152
170
|
balanceSheetReport,
|
|
153
171
|
balanceSheetByClassReport,
|
|
172
|
+
cashFlowByClassReport,
|
|
173
|
+
cashFlowByProjectReport,
|
|
154
174
|
balanceSheetByProjectReport,
|
|
155
175
|
cashFlowReport,
|
|
156
176
|
filter,
|
package/lib/index.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ import { stringToUnion, stringToUnionStrict } from './commonStateTypes/stringToU
|
|
|
42
42
|
import { AbsoluteDay, Day, Month, MonthYearPeriod, Quarter, SCHEDULE_DAYS_OF_MONTH, ScheduleDaysOfMonth, TimePeriod, convertToPeriod, toAbsoluteDay, toMonth, toMonthStrict, toMonthYearPeriodId, toQuarter, toQuarterStrict, toScheduleDaysOfMonth } from './commonStateTypes/timePeriod';
|
|
43
43
|
import { TimeframeTick, TimeframeTickWithMetaData, mapTimePeriodtoTimeframeTick, toTimePeriod, toTimeframeTick } from './commonStateTypes/timeframeTick';
|
|
44
44
|
import { AgingDateSelectionType, AgingDetailReportInvoice, AgingDetailReportUIState, AgingReportId, AgingReportInvoice, AgingReportSortKey, AgingReportUIState } from './commonStateTypes/viewAndReport/agingReportStateTypes';
|
|
45
|
-
import { isAgingReport, isBalanceSheetClassesViewReport, isBalanceSheetProjectViewReport, isBalanceSheetReport, isCashFlowOrBalanceSheetReport, isDashboardClassesViewReport, isDashboardProjectViewReport, isDashboardReport, isFluxAnalysisOpExReport, isGroupedBalanceSheetReport, isOpExByVendorReport, isPAndLClassesViewReport, isPAndLProjectViewReport, isPAndLReport } from './commonStateTypes/viewAndReport/reportIDHelper';
|
|
45
|
+
import { isAgingReport, isBalanceSheetClassesViewReport, isBalanceSheetProjectViewReport, isBalanceSheetReport, isCashFlowClassesViewReport, isCashFlowOrBalanceSheetReport, isCashFlowProjectViewReport, isCashFlowReport, isDashboardClassesViewReport, isDashboardProjectViewReport, isDashboardReport, isFluxAnalysisOpExReport, isGroupedBalanceSheetReport, isGroupedCashFlowReport, isOpExByVendorReport, isPAndLClassesViewReport, isPAndLProjectViewReport, isPAndLReport } from './commonStateTypes/viewAndReport/reportIDHelper';
|
|
46
46
|
import { PageToken, Report, ReportFormat, ReportID, ReportIDPlusForecastID, SelectorReport, SelectorView, View, toReportFormatStrict, toReportID } from './commonStateTypes/viewAndReport/viewAndReport';
|
|
47
47
|
import { PAYMENT_BUSINESS_DAYS, filterDays, getNextNthWorkingDay, getNextTransferDate, getPreviousNthWorkingDay, getYearsList, holidaysFormatted, isHoliday, isHolidayToday } from './commonStateTypes/workingDayHelper';
|
|
48
48
|
import { AccountFilterOption, AccountReport, AccountWithBalanceReport, getAllAccounts, getTransactionFilterAccountOptions } from './entity/account/accountSelector';
|
|
@@ -239,6 +239,14 @@ import { CashFlowReportViewCalculatedSectionID, CashFlowReportViewID, CashFlowRe
|
|
|
239
239
|
import { fetchCashFlow, fetchCashFlowForTimeframe, resetCashFlowNodeCollapseState, updateCashFlowUIState } from './view/cashFlow/cashFlowReducer';
|
|
240
240
|
import { getCashFlow, getCashFlowReportFetchState } from './view/cashFlow/cashFlowSelector';
|
|
241
241
|
import { CashFlowReport, CashFlowReportViewRootSectionID, SectionIdsWithSubSectionIds as CashFlowSectionIdsWithSubSectionIds, typeOfCashFlowRootSection } from './view/cashFlow/cashFlowSelectorTypes';
|
|
242
|
+
import { fetchCashFlowClassesView, fetchCashFlowForTimeframeClassesView, resetCashFlowClassesNodeCollapseState, updateCashFlowClassesToFilterOut, updateCashFlowClassesViewAccountViewMode, updateCashFlowClassesViewUIState } from './view/cashFlowClassesView/cashFlowClassesViewReducer';
|
|
243
|
+
import { getCashFlowClassesView } from './view/cashFlowClassesView/cashFlowClassesViewSelector';
|
|
244
|
+
import { CashFlowClassesViewReport } from './view/cashFlowClassesView/cashFlowClassesViewSelectorTypes';
|
|
245
|
+
import { CashFlowClassesViewUIState } from './view/cashFlowClassesView/cashFlowClassesViewState';
|
|
246
|
+
import { fetchCashFlowForTimeframeProjectView, fetchCashFlowProjectView, resetCashFlowProjectNodeCollapseState, updateCashFlowProjectViewAccountViewMode, updateCashFlowProjectViewUIState, updateCashFlowProjectsToFilterOut } from './view/cashFlowProjectView/cashFlowProjectViewReducer';
|
|
247
|
+
import { getCashFlowProjectView } from './view/cashFlowProjectView/cashFlowProjectViewSelector';
|
|
248
|
+
import { CashFlowProjectViewReport } from './view/cashFlowProjectView/cashFlowProjectViewSelectorTypes';
|
|
249
|
+
import { CashFlowProjectViewUIState } from './view/cashFlowProjectView/cashFlowProjectViewState';
|
|
242
250
|
import { fetchCashInCashOut, updateCashInCashOutCOABalancesRange, updateCashInCashOutDownloadState, updateCashInCashOutUIState } from './view/cashInCashOut/cashInCashOutReducer';
|
|
243
251
|
import { getCashInCashOut, getCashInCashOutForHighlightedRange, getCashInCashOutForSelectedRange, getCashInCashOutUIState } from './view/cashInCashOut/cashInCashOutSelector';
|
|
244
252
|
import { CashInCashOutCalculatedSectionID, CashInCashOutReport, CashInCashOutSectionID, CashInCashOutUIStateSelectorView } from './view/cashInCashOut/cashInCashOutSelectorTypes';
|
|
@@ -706,7 +714,7 @@ export default initialize;
|
|
|
706
714
|
export { initializePusher, disconnectPusher, Dayjs, ZeniDate, dateInLocal as zeniDateInLocal, date as zeniDate, dateLocal, dateNow, getBusinessDayOfDate, formatZeniDateFY as formatZeniDate, getFYMonths, getFYQuarterAndYear, getStartOfAndEndOfTimeframeForFY, getActualPeriodOfFYQtr, getActualPeriodOfFY, getLocalTimezone, addPeriod, subtractPeriod, setLocalTimezone, updateZeniDateLocaleID, ZeniUrl, toZeniUrl, toZeniUrlWithoutBaseURL, RESTAPIEndpoints, RootState, updateZeniAPIClientConfig, zeniAPIClientConfig, injectFeatureEpics, injectFeatureModules, initializeWithNewStore, ZeniStore, ZeniAPIStatus, getTimeframeTickTag, TimeFrameTickTag, isIncompleteMonthPresentInTimeframeTick, getLastMonthOfFYQuarter, getLastMonthOfFYYear, getMonthIndex, dateFromYearMonthDate, getMinDate, ExternalAPIEndpoints, };
|
|
707
715
|
export { ID, FetchState, FetchStateAndError, FetchedState, UpdateType, Mode, AccountViewMode, CompletionStatusType, };
|
|
708
716
|
export { Amount, toAmount, Currency };
|
|
709
|
-
export { View, SelectorView, Report, ReportID, toReportID, ReportIDPlusForecastID, SelectorReport, ReportFormat, toReportFormatStrict, isCashFlowOrBalanceSheetReport, isBalanceSheetReport, isBalanceSheetClassesViewReport, isBalanceSheetProjectViewReport, isGroupedBalanceSheetReport, isDashboardReport, isDashboardClassesViewReport, isDashboardProjectViewReport, isPAndLReport, isPAndLClassesViewReport, isPAndLProjectViewReport, isAgingReport, isOpExByVendorReport, isFluxAnalysisOpExReport, PageToken, };
|
|
717
|
+
export { View, SelectorView, Report, ReportID, toReportID, ReportIDPlusForecastID, SelectorReport, ReportFormat, toReportFormatStrict, isCashFlowOrBalanceSheetReport, isBalanceSheetReport, isBalanceSheetClassesViewReport, isBalanceSheetProjectViewReport, isCashFlowClassesViewReport, isCashFlowProjectViewReport, isCashFlowReport, isGroupedCashFlowReport, isGroupedBalanceSheetReport, isDashboardReport, isDashboardClassesViewReport, isDashboardProjectViewReport, isPAndLReport, isPAndLClassesViewReport, isPAndLProjectViewReport, isAgingReport, isOpExByVendorReport, isFluxAnalysisOpExReport, PageToken, };
|
|
710
718
|
export { NestedClassIDHierarchy, NestedClassID, NestedClassHierarchyForReport };
|
|
711
719
|
export { NestedAccountHierarchyForReport, NestedAccountID, NestedAccountIDHierarchy, };
|
|
712
720
|
export { NestedCustomerID, NestedCustomerHierarchy };
|
|
@@ -777,7 +785,7 @@ export { fetchAllPeopleRequiredViews, fetchPeoplePage, fetchPeople, deletePerson
|
|
|
777
785
|
export { REMINDER_NOTIFICATION_TYPES, NOTIFICATION_MODES, clearSettingsView, fetchMyProfileView, fetchMyProfile, fetchBankConnectionsView, fetchBillingAccountsView, fetchCompanyBillingAddress, saveCompanyBillingAddress, fetchNotificationSettings, saveNotificationSettings, updateNotificationSettingsLocalData, fetchNotificationSettingsView, resetNotificationSettingsLocalData, resetNotificationSettingsUpdateStatus, refreshQBOData, updateSettingsViewUIState, isMonthEndNotificationsSectionVisibleOnSettingsPage, getNotificationSettingsView, getNotificationSettings, getBillingAccountsViewDetails, getMyProfileView, getMyBankConnectionsDetails, isAccountingTabVisible, isApprovalRulesTabVisible, isBankConnectionsTabVisible, isBillingTabVisible, isBusinessVerificationTabVisible, isCompanyDetailsTabVisible, isIntegrationsTabVisible, isSettingsVisible, isMyBankConnectionsTabVisible, isNotificationsTabVisible, isPerformanceTabVisible, isRemindersSectionVisibleOnSettingsPage, MyProfileSelectorView, MyBankConnectionsView, BillingView, MyProfile, SettingsViewState, SettingsViewUIState, NotificationSettings, NotificationSettingsLocalData, ReminderNotificationSettingsLocalData, NotificationSettingsSelectorView, ReminderNotificationSettingsData, MonthEndInsightsNotificationSettingsData, MonthEndInsightsNotificationSettingsLocalData, ReminderTypeKey, NotificationModeKey, FrequencyTypeKey, RemindersLocalData, IntegrationsSettings, ProductWisePrimaryAccount, OtherPaymentAccountWithSetup, updateMyProfile, updateMyProfileLocalData, MyProfileSettingsLocalData, initializeMyProfileLocalData, };
|
|
778
786
|
export { PeopleViewSortKey };
|
|
779
787
|
export { fetchBalanceSheet, BalanceSheetReport, getBalanceSheet, getBalanceSheetFetchState, getBalanceSheetForFullDataAvailableRange, BalanceSheetState, BalanceSheetUIState, resetBalanceSheetNodeCollapseState, updateBalanceSheetUIState, BalanceSheetReportViewID, BalanceSheetSectionIdsWithSubSectionIds, BalanceSheetReportViewCalculatedSectionID, BalanceSheetReportViewSectionID, BalanceSheetReportViewRootSectionID, typeOfBalanceSheetRootSection, isBalanceSheetReportViewSectionID, isBalanceSheetReportViewCalculatedSectionID, fetchBalanceSheetForTimeframe, };
|
|
780
|
-
export { fetchBalanceSheetClassesView, fetchBalanceSheetForTimeframeClassesView, resetBalanceSheetClassesNodeCollapseState, updateBalanceSheetClassesToFilterOut, updateBalanceSheetClassesViewAccountViewMode, updateBalanceSheetClassesViewUIState, getBalanceSheetClassesView, BalanceSheetClassesViewReport, BalanceSheetClassesViewUIState, };
|
|
788
|
+
export { CashFlowClassesViewReport, CashFlowClassesViewUIState, CashFlowProjectViewReport, CashFlowProjectViewUIState, fetchCashFlowClassesView, fetchCashFlowForTimeframeClassesView, fetchCashFlowForTimeframeProjectView, fetchCashFlowProjectView, getCashFlowClassesView, getCashFlowProjectView, resetCashFlowClassesNodeCollapseState, resetCashFlowProjectNodeCollapseState, updateCashFlowClassesToFilterOut, updateCashFlowClassesViewAccountViewMode, updateCashFlowClassesViewUIState, updateCashFlowProjectViewAccountViewMode, updateCashFlowProjectViewUIState, updateCashFlowProjectsToFilterOut, fetchBalanceSheetClassesView, fetchBalanceSheetForTimeframeClassesView, resetBalanceSheetClassesNodeCollapseState, updateBalanceSheetClassesToFilterOut, updateBalanceSheetClassesViewAccountViewMode, updateBalanceSheetClassesViewUIState, getBalanceSheetClassesView, BalanceSheetClassesViewReport, BalanceSheetClassesViewUIState, };
|
|
781
789
|
export { fetchBalanceSheetForTimeframeProjectView, fetchBalanceSheetProjectView, resetBalanceSheetProjectNodeCollapseState, updateBalanceSheetProjectViewAccountViewMode, updateBalanceSheetProjectViewUIState, updateBalanceSheetProjectsToFilterOut, getBalanceSheetProjectView, BalanceSheetProjectViewReport, BalanceSheetProjectViewUIState, };
|
|
782
790
|
export { fetchCashFlow, CashFlowReport, getCashFlow, getCashFlowReportFetchState, CashFlowReportViewCalculatedSectionID, resetCashFlowNodeCollapseState, updateCashFlowUIState, CashFlowReportViewRootSectionID, CashFlowSectionIdsWithSubSectionIds, typeOfCashFlowRootSection, CashFlowReportViewID, isCashFlowReportViewCalculatedSectionID, isCashFlowReportViewSectionID, isCashFlowReportViewCalculatedSectionType1ID, CashFlowReportViewSectionID, fetchCashFlowForTimeframe, };
|
|
783
791
|
export { FinanceStatementReport, getFinanceStatement, getReportsResyncView, fetchFinanceStatement, updateCOABalancesRange, updateSelectedReportId, updateDownloadState, updateFinanceStatementAdditionalBalancesSelection, updateFinanceStatementDisplayOrder, updateFinanceStatementFormat, };
|