@zeniai/client-epic-state 5.1.79 → 5.1.81-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.
- package/lib/commonStateTypes/viewAndReport/reportIDHelper.d.ts +1 -0
- package/lib/commonStateTypes/viewAndReport/reportIDHelper.js +13 -1
- package/lib/commonStateTypes/viewAndReport/viewAndReport.d.ts +2 -2
- package/lib/commonStateTypes/viewAndReport/viewAndReport.js +3 -0
- package/lib/entity/account/accountState.d.ts +1 -1
- 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/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/entity/tenant/clearAllEpic.d.ts +4 -1
- package/lib/entity/tenant/clearAllEpic.js +6 -0
- package/lib/epic.d.ts +8 -1
- package/lib/epic.js +8 -1
- package/lib/esm/commonStateTypes/viewAndReport/reportIDHelper.js +11 -0
- package/lib/esm/commonStateTypes/viewAndReport/viewAndReport.js +3 -0
- package/lib/esm/entity/tenant/clearAllEpic.js +6 -0
- package/lib/esm/epic.js +8 -1
- package/lib/esm/index.js +14 -3
- package/lib/esm/reducer.js +9 -0
- package/lib/esm/view/invoicing/issueCreditNote/issueCreditNoteSelector.js +9 -12
- package/lib/esm/view/netBurnOrIncomeProjectView/netBurnOrIncomeForTimeframeProjectViewEpic.js +45 -0
- package/lib/esm/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewEpic.js +30 -0
- package/lib/esm/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewPayload.js +1 -0
- package/lib/esm/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewReducer.js +111 -0
- package/lib/esm/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewSelector.js +65 -0
- package/lib/esm/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewSelectorTypes.js +1 -0
- package/lib/esm/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewState.js +1 -0
- package/lib/esm/view/opExProjectView/opExForTimeframeProjectViewEpic.js +43 -0
- package/lib/esm/view/opExProjectView/opExProjectViewEpic.js +30 -0
- package/lib/esm/view/opExProjectView/opExProjectViewPayload.js +1 -0
- package/lib/esm/view/opExProjectView/opExProjectViewReducer.js +111 -0
- package/lib/esm/view/opExProjectView/opExProjectViewSelector.js +52 -0
- package/lib/esm/view/opExProjectView/opExProjectViewSelectorTypes.js +1 -0
- package/lib/esm/view/opExProjectView/opExProjectViewState.js +1 -0
- package/lib/esm/view/reportsResync/reportsClassViewRefetchingEpic.js +0 -4
- package/lib/esm/view/reportsResync/reportsProjectViewRefetchingEpic.js +30 -0
- package/lib/esm/view/reportsResync/reportsResyncEpic.js +11 -3
- package/lib/esm/view/reportsResync/reportsResyncReducer.js +9 -1
- package/lib/esm/view/revenueProjectView/revenueForTimeframeProjectViewEpic.js +35 -0
- package/lib/esm/view/revenueProjectView/revenueProjectViewEpic.js +30 -0
- package/lib/esm/view/revenueProjectView/revenueProjectViewPayload.js +1 -0
- package/lib/esm/view/revenueProjectView/revenueProjectViewReducer.js +111 -0
- package/lib/esm/view/revenueProjectView/revenueProjectViewSelector.js +58 -0
- package/lib/esm/view/revenueProjectView/revenueProjectViewSelectorTypes.js +1 -0
- package/lib/esm/view/revenueProjectView/revenueProjectViewState.js +1 -0
- package/lib/index.d.ts +21 -4
- package/lib/index.js +87 -48
- package/lib/reducer.d.ts +9 -0
- package/lib/reducer.js +9 -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/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/globalMerchantView/globalMerchantViewReducer.d.ts +2 -2
- package/lib/view/invoicing/issueCreditNote/issueCreditNoteSelector.d.ts +15 -7
- package/lib/view/invoicing/issueCreditNote/issueCreditNoteSelector.js +11 -15
- package/lib/view/netBurnOrIncomeProjectView/netBurnOrIncomeForTimeframeProjectViewEpic.d.ts +9 -0
- package/lib/view/netBurnOrIncomeProjectView/netBurnOrIncomeForTimeframeProjectViewEpic.js +49 -0
- package/lib/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewEpic.d.ts +6 -0
- package/lib/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewEpic.js +34 -0
- package/lib/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewPayload.d.ts +11 -0
- package/lib/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewPayload.js +2 -0
- package/lib/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewReducer.d.ts +33 -0
- package/lib/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewReducer.js +115 -0
- package/lib/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewSelector.d.ts +13 -0
- package/lib/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewSelector.js +69 -0
- package/lib/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewSelectorTypes.d.ts +21 -0
- package/lib/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewSelectorTypes.js +2 -0
- package/lib/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewState.d.ts +20 -0
- package/lib/view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewState.js +2 -0
- package/lib/view/opExProjectView/opExForTimeframeProjectViewEpic.d.ts +9 -0
- package/lib/view/opExProjectView/opExForTimeframeProjectViewEpic.js +47 -0
- package/lib/view/opExProjectView/opExProjectViewEpic.d.ts +6 -0
- package/lib/view/opExProjectView/opExProjectViewEpic.js +34 -0
- package/lib/view/opExProjectView/opExProjectViewPayload.d.ts +6 -0
- package/lib/view/opExProjectView/opExProjectViewPayload.js +2 -0
- package/lib/view/opExProjectView/opExProjectViewReducer.d.ts +33 -0
- package/lib/view/opExProjectView/opExProjectViewReducer.js +115 -0
- package/lib/view/opExProjectView/opExProjectViewSelector.d.ts +12 -0
- package/lib/view/opExProjectView/opExProjectViewSelector.js +56 -0
- package/lib/view/opExProjectView/opExProjectViewSelectorTypes.d.ts +19 -0
- package/lib/view/opExProjectView/opExProjectViewSelectorTypes.js +2 -0
- package/lib/view/opExProjectView/opExProjectViewState.d.ts +20 -0
- package/lib/view/opExProjectView/opExProjectViewState.js +2 -0
- package/lib/view/reimbursementCard/reimbursementCardSelector.d.ts +1 -1
- package/lib/view/reportsResync/reportsClassViewRefetchingEpic.d.ts +1 -2
- package/lib/view/reportsResync/reportsClassViewRefetchingEpic.js +0 -4
- package/lib/view/reportsResync/reportsProjectViewRefetchingEpic.d.ts +10 -0
- package/lib/view/reportsResync/reportsProjectViewRefetchingEpic.js +34 -0
- package/lib/view/reportsResync/reportsResyncEpic.d.ts +2 -2
- package/lib/view/reportsResync/reportsResyncEpic.js +10 -2
- package/lib/view/reportsResync/reportsResyncReducer.d.ts +5 -3
- package/lib/view/reportsResync/reportsResyncReducer.js +10 -2
- package/lib/view/revenueProjectView/revenueForTimeframeProjectViewEpic.d.ts +9 -0
- package/lib/view/revenueProjectView/revenueForTimeframeProjectViewEpic.js +39 -0
- package/lib/view/revenueProjectView/revenueProjectViewEpic.d.ts +6 -0
- package/lib/view/revenueProjectView/revenueProjectViewEpic.js +34 -0
- package/lib/view/revenueProjectView/revenueProjectViewPayload.d.ts +9 -0
- package/lib/view/revenueProjectView/revenueProjectViewPayload.js +2 -0
- package/lib/view/revenueProjectView/revenueProjectViewReducer.d.ts +33 -0
- package/lib/view/revenueProjectView/revenueProjectViewReducer.js +115 -0
- package/lib/view/revenueProjectView/revenueProjectViewSelector.d.ts +12 -0
- package/lib/view/revenueProjectView/revenueProjectViewSelector.js +62 -0
- package/lib/view/revenueProjectView/revenueProjectViewSelectorTypes.d.ts +19 -0
- package/lib/view/revenueProjectView/revenueProjectViewSelectorTypes.js +2 -0
- package/lib/view/revenueProjectView/revenueProjectViewState.d.ts +20 -0
- package/lib/view/revenueProjectView/revenueProjectViewState.js +2 -0
- package/lib/view/tasksCard/tasksCardSelector.d.ts +1 -1
- package/lib/view/topEx/topExSelector.d.ts +1 -1
- package/package.json +1 -1
package/lib/esm/reducer.js
CHANGED
|
@@ -169,6 +169,7 @@ import invoicingSubscriptionAction, { initialState as initialInvoicingSubscripti
|
|
|
169
169
|
import monthEndCloseChecksView, { initialState as initialMonthEndCloseChecksViewState, } from './view/monthEndCloseChecksView/monthEndCloseChecksViewReducer';
|
|
170
170
|
import netBurnOrIncome, { initialState as initialNetBurnOrIncomeWithForecastState, } from './view/netBurnOrIncome/netBurnOrIncomeReducer';
|
|
171
171
|
import netBurnOrIncomeClassesView, { initialState as initialNetBurnOrIncomeClassesViewState, } from './view/netBurnOrIncomeClassesView/netBurnOrIncomeClassesViewReducer';
|
|
172
|
+
import netBurnOrIncomeProjectView, { initialState as initialNetBurnOrIncomeProjectViewState, } from './view/netBurnOrIncomeProjectView/netBurnOrIncomeProjectViewReducer';
|
|
172
173
|
import netBurnOrIncomeStoryCard, { initialState as initialNetBurnOrIncomeStoryCardState, } from './view/netBurnOrIncomeStoryCard/netBurnOrIncomeStoryCardReducer';
|
|
173
174
|
import notificationPreferencesView, { initialState as initialNotificationPreferencesViewState, } from './view/notificationPreferencesView/notificationPreferencesViewReducer';
|
|
174
175
|
import notificationView, { initialState as initialNotificationViewState, } from './view/notificationView/notificationViewReducer';
|
|
@@ -177,6 +178,7 @@ import onboardingCustomerView, { initialState as initialOnboardingCustomerViewSt
|
|
|
177
178
|
import opEx, { initialState as initialOpExState } from './view/opEx/opExReducer';
|
|
178
179
|
import opExByVendor, { initialState as initialOpExByVendorState, } from './view/opExByVendor/opExByVendorReducer';
|
|
179
180
|
import opExClassesView, { initialState as initialOpExClassesViewState, } from './view/opExClassesView/opExClassesViewReducer';
|
|
181
|
+
import opExProjectView, { initialState as initialOpExProjectViewState, } from './view/opExProjectView/opExProjectViewReducer';
|
|
180
182
|
import ownerList, { initialState as initialOwnerListState, } from './view/ownerList/ownerListReducer';
|
|
181
183
|
import people, { initialState as initialPeopleState, } from './view/people/peopleReducer';
|
|
182
184
|
import profitAndLoss, { initialState as initialProfitAndLossState, } from './view/profitAndLoss/profitAndLossReducer';
|
|
@@ -190,6 +192,7 @@ import reportUIOptionsReducer, { initialState as initialReportUIOptionsState, }
|
|
|
190
192
|
import reportsResync, { initialReportsResyncState, } from './view/reportsResync/reportsResyncReducer';
|
|
191
193
|
import revenue, { initialState as initialRevenueWithForecastState, } from './view/revenue/revenueReducer';
|
|
192
194
|
import revenueClassesView, { initialState as initialRevenueClassesViewState, } from './view/revenueClassesView/revenueClassesViewReducer';
|
|
195
|
+
import revenueProjectView, { initialState as initialRevenueProjectViewState, } from './view/revenueProjectView/revenueProjectViewReducer';
|
|
193
196
|
import reviewCompanyView, { initialState as initialReviewCompanyViewState, } from './view/reviewCompanyView/reviewCompanyViewReducer';
|
|
194
197
|
import scheduleAccruedDetailView, { initialState as initialScheduleAccruedDetailViewState, } from './view/scheduleView/scheduleAccruedDetailView/scheduleAccruedDetailReducer';
|
|
195
198
|
import scheduleDetailView, { initialState as initialScheduleDetailViewState, } from './view/scheduleView/scheduleDetailView/scheduleDetailReducer';
|
|
@@ -483,6 +486,7 @@ const initialViewsState = {
|
|
|
483
486
|
merchantListState: initialMerchantListState,
|
|
484
487
|
monthEndCloseChecksViewState: initialMonthEndCloseChecksViewState,
|
|
485
488
|
netBurnOrIncomeClassesViewState: initialNetBurnOrIncomeClassesViewState,
|
|
489
|
+
netBurnOrIncomeProjectViewState: initialNetBurnOrIncomeProjectViewState,
|
|
486
490
|
netBurnOrIncomeState: initialNetBurnOrIncomeWithForecastState,
|
|
487
491
|
netBurnOrIncomeStoryCardState: initialNetBurnOrIncomeStoryCardState,
|
|
488
492
|
notificationPreferencesViewState: initialNotificationPreferencesViewState,
|
|
@@ -492,6 +496,7 @@ const initialViewsState = {
|
|
|
492
496
|
onboardingCustomerViewState: initialOnboardingCustomerViewState,
|
|
493
497
|
opExByVendorState: initialOpExByVendorState,
|
|
494
498
|
opExClassesViewState: initialOpExClassesViewState,
|
|
499
|
+
opExProjectViewState: initialOpExProjectViewState,
|
|
495
500
|
opExState: initialOpExState,
|
|
496
501
|
ownerListState: initialOwnerListState,
|
|
497
502
|
paymentAccountListState: initialPaymentAccountListState,
|
|
@@ -514,6 +519,7 @@ const initialViewsState = {
|
|
|
514
519
|
reportsResyncState: initialReportsResyncState,
|
|
515
520
|
reportUIOptionsState: initialReportUIOptionsState,
|
|
516
521
|
revenueClassesViewState: initialRevenueClassesViewState,
|
|
522
|
+
revenueProjectViewState: initialRevenueProjectViewState,
|
|
517
523
|
revenueState: initialRevenueWithForecastState,
|
|
518
524
|
reviewCompanyViewState: initialReviewCompanyViewState,
|
|
519
525
|
scheduleAccruedDetailState: initialScheduleAccruedDetailViewState,
|
|
@@ -773,6 +779,7 @@ const viewReducers = {
|
|
|
773
779
|
merchantListState: merchantList,
|
|
774
780
|
monthEndCloseChecksViewState: monthEndCloseChecksView,
|
|
775
781
|
netBurnOrIncomeClassesViewState: netBurnOrIncomeClassesView,
|
|
782
|
+
netBurnOrIncomeProjectViewState: netBurnOrIncomeProjectView,
|
|
776
783
|
netBurnOrIncomeState: netBurnOrIncome,
|
|
777
784
|
netBurnOrIncomeStoryCardState: netBurnOrIncomeStoryCard,
|
|
778
785
|
notificationPreferencesViewState: notificationPreferencesView,
|
|
@@ -782,6 +789,7 @@ const viewReducers = {
|
|
|
782
789
|
onboardingCustomerViewState: onboardingCustomerView,
|
|
783
790
|
opExByVendorState: opExByVendor,
|
|
784
791
|
opExClassesViewState: opExClassesView,
|
|
792
|
+
opExProjectViewState: opExProjectView,
|
|
785
793
|
opExState: opEx,
|
|
786
794
|
ownerListState: ownerList,
|
|
787
795
|
paymentAccountListState: paymentAccountList,
|
|
@@ -805,6 +813,7 @@ const viewReducers = {
|
|
|
805
813
|
reportsResyncState: reportsResync,
|
|
806
814
|
reportUIOptionsState: reportUIOptionsReducer,
|
|
807
815
|
revenueClassesViewState: revenueClassesView,
|
|
816
|
+
revenueProjectViewState: revenueProjectView,
|
|
808
817
|
revenueState: revenue,
|
|
809
818
|
reviewCompanyViewState: reviewCompanyView,
|
|
810
819
|
scheduleAccruedDetailState: scheduleAccruedDetailView,
|
|
@@ -1,20 +1,17 @@
|
|
|
1
|
+
import { getInvoiceDetail } from '../invoiceDetail/invoiceDetailSelector';
|
|
1
2
|
import { INVOICING_CREDIT_NOTE_REASON_CODES } from './issueCreditNoteFormConfig';
|
|
2
|
-
export const getIssueCreditNoteView = (state) => {
|
|
3
|
-
const
|
|
3
|
+
export const getIssueCreditNoteView = (state, invoiceId) => {
|
|
4
|
+
const invoiceView = getInvoiceDetail(state, invoiceId);
|
|
5
|
+
const { draft, error, fetchState, issuedCreditNoteId } = state.invoicingIssueCreditNoteState;
|
|
4
6
|
return {
|
|
5
|
-
|
|
6
|
-
fetchState,
|
|
7
|
+
invoice: invoiceView.invoice,
|
|
8
|
+
isPageReady: invoiceView.fetchState === 'Completed' && draft.lineItems.length > 0,
|
|
7
9
|
issuedCreditNoteId,
|
|
8
|
-
version: 1.0,
|
|
9
|
-
};
|
|
10
|
-
};
|
|
11
|
-
export const getIssueCreditNoteFormView = (state) => {
|
|
12
|
-
const { draft, error, fetchState } = state.invoicingIssueCreditNoteState;
|
|
13
|
-
return {
|
|
14
10
|
localData: draft,
|
|
15
11
|
reasonCodeValues: [...INVOICING_CREDIT_NOTE_REASON_CODES],
|
|
16
|
-
error,
|
|
17
|
-
|
|
12
|
+
submitState: { error, fetchState },
|
|
13
|
+
error: invoiceView.error,
|
|
14
|
+
fetchState: invoiceView.fetchState,
|
|
18
15
|
version: 1.0,
|
|
19
16
|
};
|
|
20
17
|
};
|
|
@@ -0,0 +1,45 @@
|
|
|
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 { fetchNetBurnOrIncomeForTimeframeProjectView, updateNetBurnOrIncomeForTimeframeProjectView, updateNetBurnOrIncomeForTimeframeProjectViewFailure, } from './netBurnOrIncomeProjectViewReducer';
|
|
7
|
+
export const fetchNetBurnOrIncomeForTimeframeProjectViewEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchNetBurnOrIncomeForTimeframeProjectView.match), mergeMap((action) => {
|
|
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
|
+
const queryValue = {
|
|
19
|
+
is_full_response: action.payload.fetchFullReport,
|
|
20
|
+
time_series_groups: [getTimeSeriesGroup(action.payload.timeframe)],
|
|
21
|
+
is_group_by_project: true,
|
|
22
|
+
};
|
|
23
|
+
return zeniAPI
|
|
24
|
+
.getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/2.0/reports/net_burn_or_income?query=${encodeURIComponent(JSON.stringify(queryValue))}`)
|
|
25
|
+
.pipe(mergeMap((response) => {
|
|
26
|
+
if (response.data != null && isSuccessResponse(response)) {
|
|
27
|
+
const actions = [];
|
|
28
|
+
const report = response.data.report;
|
|
29
|
+
const currency = report.currency;
|
|
30
|
+
actions.push(updateProjects(report.projects));
|
|
31
|
+
actions.push(updateSectionProjectView(action.payload.timeframe, 'cogs', 'net_burn_or_income_by_projects', report.cogs, report.accounts, currency));
|
|
32
|
+
actions.push(updateSectionProjectView(action.payload.timeframe, 'expenses', 'net_burn_or_income_by_projects', report.expenses, report.accounts, currency));
|
|
33
|
+
actions.push(updateSectionProjectView(action.payload.timeframe, 'income', 'net_burn_or_income_by_projects', report.income, report.accounts, currency));
|
|
34
|
+
actions.push(updateNetBurnOrIncomeForTimeframeProjectView({
|
|
35
|
+
timeframe: action.payload.timeframe,
|
|
36
|
+
report: response.data,
|
|
37
|
+
}));
|
|
38
|
+
return from(actions);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
return of(updateNetBurnOrIncomeForTimeframeProjectViewFailure(response.status, action.payload.timeframe));
|
|
42
|
+
}
|
|
43
|
+
}), catchError((error) => of(updateNetBurnOrIncomeForTimeframeProjectViewFailure(createZeniAPIStatus('Unexpected Error', 'Net Burn by Projects REST API call errored out' +
|
|
44
|
+
(error instanceof Error ? error.message : String(error))), action.payload.timeframe))));
|
|
45
|
+
}));
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { from } from 'rxjs';
|
|
2
|
+
import { filter, switchMap } from 'rxjs/operators';
|
|
3
|
+
import { fetchNetBurnOrIncomeForTimeframeProjectView, fetchNetBurnOrIncomeProjectView, } from './netBurnOrIncomeProjectViewReducer';
|
|
4
|
+
export const fetchNetBurnOrIncomeProjectViewEpic = (actions$, state) => actions$.pipe(filter(fetchNetBurnOrIncomeProjectView.match), switchMap((action) => {
|
|
5
|
+
const { cacheOverride } = action.payload;
|
|
6
|
+
if (cacheOverride === true) {
|
|
7
|
+
return from([
|
|
8
|
+
fetchNetBurnOrIncomeForTimeframeProjectView('month'),
|
|
9
|
+
fetchNetBurnOrIncomeForTimeframeProjectView('quarter'),
|
|
10
|
+
fetchNetBurnOrIncomeForTimeframeProjectView('year'),
|
|
11
|
+
]);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
const fetchActions = [];
|
|
15
|
+
const projectFetchState = state.value.netBurnOrIncomeProjectViewState.fetchState;
|
|
16
|
+
if (projectFetchState['month'].fetchState !== 'In-Progress' &&
|
|
17
|
+
projectFetchState['month'].fetchState !== 'Completed') {
|
|
18
|
+
fetchActions.push(fetchNetBurnOrIncomeForTimeframeProjectView('month'));
|
|
19
|
+
}
|
|
20
|
+
if (projectFetchState['quarter'].fetchState !== 'In-Progress' &&
|
|
21
|
+
projectFetchState['quarter'].fetchState !== 'Completed') {
|
|
22
|
+
fetchActions.push(fetchNetBurnOrIncomeForTimeframeProjectView('quarter'));
|
|
23
|
+
}
|
|
24
|
+
if (projectFetchState['year'].fetchState !== 'In-Progress' &&
|
|
25
|
+
projectFetchState['year'].fetchState !== 'Completed') {
|
|
26
|
+
fetchActions.push(fetchNetBurnOrIncomeForTimeframeProjectView('year'));
|
|
27
|
+
}
|
|
28
|
+
return from(fetchActions);
|
|
29
|
+
}
|
|
30
|
+
}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { createSlice } from '@reduxjs/toolkit';
|
|
2
|
+
import { mapReportPayloadV2ToReportV2 } from '../../commonPayloadTypes/v2/viewAndReportPayloadv2';
|
|
3
|
+
export const initialState = {
|
|
4
|
+
fetchState: {
|
|
5
|
+
month: {
|
|
6
|
+
fetchState: 'Not-Started',
|
|
7
|
+
error: undefined,
|
|
8
|
+
},
|
|
9
|
+
quarter: {
|
|
10
|
+
fetchState: 'Not-Started',
|
|
11
|
+
error: undefined,
|
|
12
|
+
},
|
|
13
|
+
year: {
|
|
14
|
+
fetchState: 'Not-Started',
|
|
15
|
+
error: undefined,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
firstMonthOfFY: 1,
|
|
19
|
+
projectIds: [],
|
|
20
|
+
reportId: 'net_burn_or_income_by_projects',
|
|
21
|
+
reportTitle: 'Net Income',
|
|
22
|
+
uiState: {
|
|
23
|
+
accountViewMode: 'account_group',
|
|
24
|
+
nodeCollapseState: {},
|
|
25
|
+
projectsToFilterOut: [],
|
|
26
|
+
scrollPosition: undefined,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
const netBurnOrIncomeProjectView = createSlice({
|
|
30
|
+
name: 'netBurnOrIncomeProjectView',
|
|
31
|
+
initialState,
|
|
32
|
+
reducers: {
|
|
33
|
+
fetchNetBurnOrIncomeProjectView: {
|
|
34
|
+
prepare(cacheOverride = false) {
|
|
35
|
+
return { payload: { cacheOverride } };
|
|
36
|
+
},
|
|
37
|
+
reducer(
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
39
|
+
_draft,
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
41
|
+
_action) {
|
|
42
|
+
// nothing to do here
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
fetchNetBurnOrIncomeForTimeframeProjectView: {
|
|
46
|
+
prepare(timeframe, fetchFullReport = true, cacheOverride = false) {
|
|
47
|
+
return { payload: { timeframe, fetchFullReport, cacheOverride } };
|
|
48
|
+
},
|
|
49
|
+
reducer(draft, action) {
|
|
50
|
+
const timeframe = action.payload.timeframe;
|
|
51
|
+
draft.fetchState[timeframe].fetchState = 'In-Progress';
|
|
52
|
+
draft.fetchState[timeframe].error = undefined;
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
updateNetBurnOrIncomeForTimeframeProjectView(draft, action) {
|
|
56
|
+
doUpdateNetBurnOrIncomeProjectView(draft, action.payload.timeframe, action.payload.report);
|
|
57
|
+
},
|
|
58
|
+
updateNetBurnOrIncomeForTimeframeProjectViewFailure: {
|
|
59
|
+
prepare(error, timeframe) {
|
|
60
|
+
return {
|
|
61
|
+
payload: {
|
|
62
|
+
error,
|
|
63
|
+
timeframe,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
reducer(draft, action) {
|
|
68
|
+
draft.fetchState[action.payload.timeframe] = {
|
|
69
|
+
fetchState: 'Error',
|
|
70
|
+
error: action.payload.error,
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
updateProjectsToFilterOut(draft, action) {
|
|
75
|
+
draft.uiState.projectsToFilterOut = action.payload.projectsToFilterOut;
|
|
76
|
+
},
|
|
77
|
+
updateNetBurnOrIncomeProjectViewUIState(draft, action) {
|
|
78
|
+
const { nodeCollapseState, scrollPosition } = action.payload;
|
|
79
|
+
if (nodeCollapseState != null) {
|
|
80
|
+
draft.uiState.nodeCollapseState = Object.assign({}, draft.uiState.nodeCollapseState, {
|
|
81
|
+
[nodeCollapseState.nodeId]: nodeCollapseState.isCollapsed,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
if (scrollPosition != null) {
|
|
85
|
+
draft.uiState.scrollPosition = scrollPosition;
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
updateProjectViewAccountViewMode(draft, action) {
|
|
89
|
+
draft.uiState.accountViewMode = action.payload.viewMode;
|
|
90
|
+
},
|
|
91
|
+
resetProjectNodeCollapseState(draft) {
|
|
92
|
+
draft.uiState.nodeCollapseState = {};
|
|
93
|
+
},
|
|
94
|
+
clearNetBurnOrIncomeProjectView(draft) {
|
|
95
|
+
Object.assign(draft, initialState);
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
export const { fetchNetBurnOrIncomeProjectView, fetchNetBurnOrIncomeForTimeframeProjectView, updateNetBurnOrIncomeForTimeframeProjectView, updateNetBurnOrIncomeForTimeframeProjectViewFailure, updateProjectsToFilterOut, updateNetBurnOrIncomeProjectViewUIState, updateProjectViewAccountViewMode, resetProjectNodeCollapseState, clearNetBurnOrIncomeProjectView, } = netBurnOrIncomeProjectView.actions;
|
|
100
|
+
export default netBurnOrIncomeProjectView.reducer;
|
|
101
|
+
const doUpdateNetBurnOrIncomeProjectView = (draft, timeframe, netBurnReport) => {
|
|
102
|
+
const report = mapReportPayloadV2ToReportV2(netBurnReport.report);
|
|
103
|
+
draft.dataAvailable = report.dataAvailable;
|
|
104
|
+
draft.firstMonthOfFY = report.firstMonthOfFY;
|
|
105
|
+
draft.bookCloseDate = report.bookCloseDate;
|
|
106
|
+
draft.status = report.status;
|
|
107
|
+
draft.fetchState[timeframe].fetchState = 'Completed';
|
|
108
|
+
if (draft.projectIds.length <= 0) {
|
|
109
|
+
draft.projectIds = netBurnReport.report.projects.map((project) => project.accounting_project_id);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createSelector } from '@reduxjs/toolkit';
|
|
2
|
+
import { getDifferenceOfBalancesGroupedByPeriod } from '../../commonStateTypes/coaBalance/classBalances/getDifferenceOfBalancesGroupedByPeriod';
|
|
3
|
+
import { getSumOfBalancesByGroupedByPeriod } from '../../commonStateTypes/coaBalance/classBalances/getSumOfBalancesGroupedByPeriod';
|
|
4
|
+
import { getCOABalances } from '../../commonStateTypes/coaBalance/coaBalance';
|
|
5
|
+
import { newBalancesFilterProjectView, } from '../../commonStateTypes/coaBalance/coaBalancesFilterProjectView';
|
|
6
|
+
import { reduceFetchStateParallelTimeframes } from '../../commonStateTypes/reduceFetchState';
|
|
7
|
+
import { getProjectsByIds } from '../../entity/project/projectSelector';
|
|
8
|
+
import { getSectionProjectViewReport } from '../../entity/sectionProjectView/sectionProjectViewSelector';
|
|
9
|
+
import { ALL_NETBURN_OR_INCOME_CLASSES_VIEW_SECTION_IDS, } from '../netBurnOrIncomeClassesView/netBurnOrIncomeClassesViewSelectorTypes';
|
|
10
|
+
export const netBurnOrIncomeProjectIdsInOrder = ['income', 'cogs', 'expenses', 'grossBurn', 'netBurnOrIncome'];
|
|
11
|
+
export const getNetBurnOrIncomeProjectView = (filter, accountState, projectState, sectionsState, netBurnOrIncomeWithForecastState, netBurnOrIncomeProjectViewState) => {
|
|
12
|
+
const fetchState = reduceFetchStateParallelTimeframes([
|
|
13
|
+
netBurnOrIncomeProjectViewState.fetchState.month,
|
|
14
|
+
netBurnOrIncomeProjectViewState.fetchState.quarter,
|
|
15
|
+
netBurnOrIncomeProjectViewState.fetchState.year,
|
|
16
|
+
]);
|
|
17
|
+
const reportId = 'net_burn_or_income_by_projects';
|
|
18
|
+
const sections = {};
|
|
19
|
+
const calculatedSections = {};
|
|
20
|
+
if (fetchState.fetchState === 'Completed') {
|
|
21
|
+
ALL_NETBURN_OR_INCOME_CLASSES_VIEW_SECTION_IDS.forEach((sectionId) => {
|
|
22
|
+
sections[`${sectionId}`] = getSectionProjectViewReport(accountState, projectState, sectionsState, netBurnOrIncomeProjectViewState.projectIds, {
|
|
23
|
+
reportId,
|
|
24
|
+
sectionId,
|
|
25
|
+
}, filter);
|
|
26
|
+
});
|
|
27
|
+
const grossBurnBalancesByPeriod = getSumOfBalancesByGroupedByPeriod([
|
|
28
|
+
sections['expenses'].sectionBalancesTotalByPeriod,
|
|
29
|
+
sections['cogs'].sectionBalancesTotalByPeriod,
|
|
30
|
+
]);
|
|
31
|
+
calculatedSections['grossBurn'] = getCOABalances(grossBurnBalancesByPeriod, filter);
|
|
32
|
+
const netBurnOrIncomeBalances = getDifferenceOfBalancesGroupedByPeriod(sections['income'].sectionBalancesTotalByPeriod, grossBurnBalancesByPeriod);
|
|
33
|
+
calculatedSections['netBurnOrIncome'] = getCOABalances(netBurnOrIncomeBalances, filter);
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
sections,
|
|
37
|
+
calculatedSections,
|
|
38
|
+
reportId: netBurnOrIncomeProjectViewState.reportId,
|
|
39
|
+
reportTitle: netBurnOrIncomeProjectViewState.reportTitle,
|
|
40
|
+
firstMonthOfFY: netBurnOrIncomeProjectViewState.firstMonthOfFY,
|
|
41
|
+
dataAvailable: netBurnOrIncomeProjectViewState.dataAvailable,
|
|
42
|
+
bookCloseDate: netBurnOrIncomeProjectViewState.bookCloseDate,
|
|
43
|
+
version: netBurnOrIncomeProjectViewState.version,
|
|
44
|
+
status: netBurnOrIncomeProjectViewState.status,
|
|
45
|
+
fetchState: fetchState.fetchState,
|
|
46
|
+
error: fetchState.error,
|
|
47
|
+
filter,
|
|
48
|
+
uiState: netBurnOrIncomeProjectViewState.uiState,
|
|
49
|
+
projects: getProjectsByIds(projectState, netBurnOrIncomeProjectViewState.projectIds),
|
|
50
|
+
projectsToFilterOut: netBurnOrIncomeProjectViewState.uiState.projectsToFilterOut,
|
|
51
|
+
idsInOrder: netBurnOrIncomeProjectIdsInOrder,
|
|
52
|
+
runwayAndAverages: netBurnOrIncomeWithForecastState.netBurnOrIncome.runwayAndAverages,
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
export const getNetBurnOrIncomeProjectViewForSelectedRange = createSelector((state) => state.accountState, (state) => state.projectState, (state) => state.sectionProjectViewState, (state) => state.netBurnOrIncomeState, (state) => state.netBurnOrIncomeProjectViewState, (accountState, projectState, sectionsState, netBurnOrIncomeState, netBurnOrIncomeProjectViewState) => {
|
|
56
|
+
const { timeframe, selectedCOABalancesRange, selectedAdditionalBalances } = netBurnOrIncomeState.uiState;
|
|
57
|
+
const noFilter = newBalancesFilterProjectView(netBurnOrIncomeState.netBurnOrIncome.firstMonthOfFY, timeframe, selectedCOABalancesRange.numberOfPeriods, selectedCOABalancesRange.thisPeriod, 'ascending_date', selectedAdditionalBalances, netBurnOrIncomeProjectViewState.uiState.projectsToFilterOut);
|
|
58
|
+
return getNetBurnOrIncomeProjectView(noFilter, accountState, projectState, sectionsState, netBurnOrIncomeState, netBurnOrIncomeProjectViewState);
|
|
59
|
+
});
|
|
60
|
+
export const getNetBurnOrIncomeProjectViewForHighlightedRange = createSelector((state) => state.accountState, (state) => state.projectState, (state) => state.sectionProjectViewState, (state) => state.netBurnOrIncomeState, (state) => state.netBurnOrIncomeProjectViewState, (accountState, projectState, sectionsState, netBurnOrIncomeState, netBurnOrIncomeProjectViewState) => {
|
|
61
|
+
const { timeframe, highlightedCOABalancesRange, selectedAdditionalBalances, maxNumOfPeriodsToHighlight, } = netBurnOrIncomeState.uiState;
|
|
62
|
+
const filter = newBalancesFilterProjectView(netBurnOrIncomeState.netBurnOrIncome.firstMonthOfFY, timeframe, highlightedCOABalancesRange?.numberOfPeriods ??
|
|
63
|
+
maxNumOfPeriodsToHighlight, highlightedCOABalancesRange?.thisPeriod, 'ascending_date', selectedAdditionalBalances, netBurnOrIncomeProjectViewState.uiState.projectsToFilterOut);
|
|
64
|
+
return getNetBurnOrIncomeProjectView(filter, accountState, projectState, sectionsState, netBurnOrIncomeState, netBurnOrIncomeProjectViewState);
|
|
65
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
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 { fetchOpExForTimeframeProjectView, updateOpExForTimeframeProjectView, updateOpExForTimeframeProjectViewFailure, } from './opExProjectViewReducer';
|
|
7
|
+
export const fetchOpExForTimeframeProjectViewEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchOpExForTimeframeProjectView.match), mergeMap((action) => {
|
|
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
|
+
const queryValue = {
|
|
19
|
+
is_full_response: action.payload.fetchFullReport,
|
|
20
|
+
time_series_groups: [getTimeSeriesGroup(action.payload.timeframe)],
|
|
21
|
+
is_group_by_project: true,
|
|
22
|
+
};
|
|
23
|
+
return zeniAPI
|
|
24
|
+
.getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/2.0/reports/operating_expenses?query=${encodeURIComponent(JSON.stringify(queryValue))}`)
|
|
25
|
+
.pipe(mergeMap((response) => {
|
|
26
|
+
if (response.data != null && isSuccessResponse(response)) {
|
|
27
|
+
const actions = [];
|
|
28
|
+
const report = response.data.report;
|
|
29
|
+
const currency = report.currency;
|
|
30
|
+
actions.push(updateProjects(report.projects));
|
|
31
|
+
actions.push(updateSectionProjectView(action.payload.timeframe, 'expenses', 'operating_expenses_by_projects', report.expenses, report.accounts, currency));
|
|
32
|
+
actions.push(updateOpExForTimeframeProjectView({
|
|
33
|
+
timeframe: action.payload.timeframe,
|
|
34
|
+
report: response.data,
|
|
35
|
+
}));
|
|
36
|
+
return from(actions);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
return of(updateOpExForTimeframeProjectViewFailure(response.status, action.payload.timeframe));
|
|
40
|
+
}
|
|
41
|
+
}), catchError((error) => of(updateOpExForTimeframeProjectViewFailure(createZeniAPIStatus('Unexpected Error', 'OpEx by Projects REST API call errored out' +
|
|
42
|
+
(error instanceof Error ? error.message : String(error))), action.payload.timeframe))));
|
|
43
|
+
}));
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { from } from 'rxjs';
|
|
2
|
+
import { filter, switchMap } from 'rxjs/operators';
|
|
3
|
+
import { fetchOpExForTimeframeProjectView, fetchOpExProjectView, } from './opExProjectViewReducer';
|
|
4
|
+
export const fetchOpExProjectViewEpic = (actions$, state) => actions$.pipe(filter(fetchOpExProjectView.match), switchMap((action) => {
|
|
5
|
+
const { cacheOverride } = action.payload;
|
|
6
|
+
if (cacheOverride === true) {
|
|
7
|
+
return from([
|
|
8
|
+
fetchOpExForTimeframeProjectView('month'),
|
|
9
|
+
fetchOpExForTimeframeProjectView('quarter'),
|
|
10
|
+
fetchOpExForTimeframeProjectView('year'),
|
|
11
|
+
]);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
const fetchActions = [];
|
|
15
|
+
const projectFetchState = state.value.opExProjectViewState.fetchState;
|
|
16
|
+
if (projectFetchState['month'].fetchState !== 'In-Progress' &&
|
|
17
|
+
projectFetchState['month'].fetchState !== 'Completed') {
|
|
18
|
+
fetchActions.push(fetchOpExForTimeframeProjectView('month'));
|
|
19
|
+
}
|
|
20
|
+
if (projectFetchState['quarter'].fetchState !== 'In-Progress' &&
|
|
21
|
+
projectFetchState['quarter'].fetchState !== 'Completed') {
|
|
22
|
+
fetchActions.push(fetchOpExForTimeframeProjectView('quarter'));
|
|
23
|
+
}
|
|
24
|
+
if (projectFetchState['year'].fetchState !== 'In-Progress' &&
|
|
25
|
+
projectFetchState['year'].fetchState !== 'Completed') {
|
|
26
|
+
fetchActions.push(fetchOpExForTimeframeProjectView('year'));
|
|
27
|
+
}
|
|
28
|
+
return from(fetchActions);
|
|
29
|
+
}
|
|
30
|
+
}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { createSlice } from '@reduxjs/toolkit';
|
|
2
|
+
import { mapReportPayloadV2ToReportV2 } from '../../commonPayloadTypes/v2/viewAndReportPayloadv2';
|
|
3
|
+
export const initialState = {
|
|
4
|
+
fetchState: {
|
|
5
|
+
month: {
|
|
6
|
+
fetchState: 'Not-Started',
|
|
7
|
+
error: undefined,
|
|
8
|
+
},
|
|
9
|
+
quarter: {
|
|
10
|
+
fetchState: 'Not-Started',
|
|
11
|
+
error: undefined,
|
|
12
|
+
},
|
|
13
|
+
year: {
|
|
14
|
+
fetchState: 'Not-Started',
|
|
15
|
+
error: undefined,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
firstMonthOfFY: 1,
|
|
19
|
+
projectIds: [],
|
|
20
|
+
reportId: 'operating_expenses_by_projects',
|
|
21
|
+
reportTitle: 'operating_expenses_by_projects',
|
|
22
|
+
uiState: {
|
|
23
|
+
accountViewMode: 'account_group',
|
|
24
|
+
nodeCollapseState: {},
|
|
25
|
+
projectsToFilterOut: [],
|
|
26
|
+
scrollPosition: undefined,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
const opExProjectView = createSlice({
|
|
30
|
+
name: 'opExProjectView',
|
|
31
|
+
initialState,
|
|
32
|
+
reducers: {
|
|
33
|
+
fetchOpExProjectView: {
|
|
34
|
+
prepare(cacheOverride = false) {
|
|
35
|
+
return { payload: { cacheOverride } };
|
|
36
|
+
},
|
|
37
|
+
reducer(
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
39
|
+
_draft,
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
41
|
+
_action) {
|
|
42
|
+
// nothing to do here
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
fetchOpExForTimeframeProjectView: {
|
|
46
|
+
prepare(timeframe, fetchFullReport = true, cacheOverride = false) {
|
|
47
|
+
return { payload: { timeframe, fetchFullReport, cacheOverride } };
|
|
48
|
+
},
|
|
49
|
+
reducer(draft, action) {
|
|
50
|
+
const timeframe = action.payload.timeframe;
|
|
51
|
+
draft.fetchState[timeframe].fetchState = 'In-Progress';
|
|
52
|
+
draft.fetchState[timeframe].error = undefined;
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
updateOpExForTimeframeProjectView(draft, action) {
|
|
56
|
+
doUpdateOpExProjectView(draft, action.payload.timeframe, action.payload.report);
|
|
57
|
+
},
|
|
58
|
+
updateOpExForTimeframeProjectViewFailure: {
|
|
59
|
+
prepare(error, timeframe) {
|
|
60
|
+
return {
|
|
61
|
+
payload: {
|
|
62
|
+
error,
|
|
63
|
+
timeframe,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
reducer(draft, action) {
|
|
68
|
+
draft.fetchState[action.payload.timeframe] = {
|
|
69
|
+
fetchState: 'Error',
|
|
70
|
+
error: action.payload.error,
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
updateProjectsToFilterOut(draft, action) {
|
|
75
|
+
draft.uiState.projectsToFilterOut = action.payload.projectsToFilterOut;
|
|
76
|
+
},
|
|
77
|
+
updateOpExProjectViewUIState(draft, action) {
|
|
78
|
+
const { nodeCollapseState, scrollPosition } = action.payload;
|
|
79
|
+
if (nodeCollapseState != null) {
|
|
80
|
+
draft.uiState.nodeCollapseState = Object.assign({}, draft.uiState.nodeCollapseState, {
|
|
81
|
+
[nodeCollapseState.nodeId]: nodeCollapseState.isCollapsed,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
if (scrollPosition != null) {
|
|
85
|
+
draft.uiState.scrollPosition = scrollPosition;
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
updateProjectViewAccountViewMode(draft, action) {
|
|
89
|
+
draft.uiState.accountViewMode = action.payload.viewMode;
|
|
90
|
+
},
|
|
91
|
+
resetProjectNodeCollapseState(draft) {
|
|
92
|
+
draft.uiState.nodeCollapseState = {};
|
|
93
|
+
},
|
|
94
|
+
clearOpExProjectView(draft) {
|
|
95
|
+
Object.assign(draft, initialState);
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
export const { fetchOpExProjectView, fetchOpExForTimeframeProjectView, updateOpExForTimeframeProjectView, updateOpExForTimeframeProjectViewFailure, updateProjectsToFilterOut, updateOpExProjectViewUIState, updateProjectViewAccountViewMode, resetProjectNodeCollapseState, clearOpExProjectView, } = opExProjectView.actions;
|
|
100
|
+
export default opExProjectView.reducer;
|
|
101
|
+
const doUpdateOpExProjectView = (draft, timeframe, opExReport) => {
|
|
102
|
+
const report = mapReportPayloadV2ToReportV2(opExReport.report);
|
|
103
|
+
draft.dataAvailable = report.dataAvailable;
|
|
104
|
+
draft.firstMonthOfFY = report.firstMonthOfFY;
|
|
105
|
+
draft.bookCloseDate = report.bookCloseDate;
|
|
106
|
+
draft.status = report.status;
|
|
107
|
+
draft.fetchState[timeframe].fetchState = 'Completed';
|
|
108
|
+
if (draft.projectIds.length <= 0) {
|
|
109
|
+
draft.projectIds = opExReport.report.projects.map((project) => project.accounting_project_id);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { createSelector } from '@reduxjs/toolkit';
|
|
2
|
+
import { newBalancesFilterProjectView, } from '../../commonStateTypes/coaBalance/coaBalancesFilterProjectView';
|
|
3
|
+
import { reduceFetchStateParallelTimeframes } from '../../commonStateTypes/reduceFetchState';
|
|
4
|
+
import { getProjectsByIds } from '../../entity/project/projectSelector';
|
|
5
|
+
import { getSectionProjectViewReport } from '../../entity/sectionProjectView/sectionProjectViewSelector';
|
|
6
|
+
export const opExProjectIdsInOrder = ['expenses'];
|
|
7
|
+
export const getOpExProjectView = (filter, accountState, projectState, sectionsState, opExProjectViewState) => {
|
|
8
|
+
const fetchState = reduceFetchStateParallelTimeframes([
|
|
9
|
+
opExProjectViewState.fetchState.month,
|
|
10
|
+
opExProjectViewState.fetchState.quarter,
|
|
11
|
+
opExProjectViewState.fetchState.year,
|
|
12
|
+
]);
|
|
13
|
+
const reportId = 'operating_expenses_by_projects';
|
|
14
|
+
const sectionId = 'expenses';
|
|
15
|
+
const sections = {};
|
|
16
|
+
const calculatedSections = {};
|
|
17
|
+
if (fetchState.fetchState === 'Completed') {
|
|
18
|
+
sections.expenses = getSectionProjectViewReport(accountState, projectState, sectionsState, opExProjectViewState.projectIds, {
|
|
19
|
+
reportId,
|
|
20
|
+
sectionId,
|
|
21
|
+
}, filter);
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
sections,
|
|
25
|
+
calculatedSections,
|
|
26
|
+
reportId: opExProjectViewState.reportId,
|
|
27
|
+
reportTitle: opExProjectViewState.reportTitle,
|
|
28
|
+
firstMonthOfFY: opExProjectViewState.firstMonthOfFY,
|
|
29
|
+
dataAvailable: opExProjectViewState.dataAvailable,
|
|
30
|
+
bookCloseDate: opExProjectViewState.bookCloseDate,
|
|
31
|
+
version: opExProjectViewState.version,
|
|
32
|
+
status: opExProjectViewState.status,
|
|
33
|
+
fetchState: fetchState.fetchState,
|
|
34
|
+
error: fetchState.error,
|
|
35
|
+
filter,
|
|
36
|
+
uiState: opExProjectViewState.uiState,
|
|
37
|
+
projects: getProjectsByIds(projectState, opExProjectViewState.projectIds),
|
|
38
|
+
projectsToFilterOut: opExProjectViewState.uiState.projectsToFilterOut,
|
|
39
|
+
idsInOrder: opExProjectIdsInOrder,
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
export const getOpExProjectViewForSelectedRange = createSelector((state) => state.accountState, (state) => state.projectState, (state) => state.sectionProjectViewState, (state) => state.opExState, (state) => state.opExProjectViewState, (accountState, projectState, sectionsState, opExState, opExProjectViewState) => {
|
|
43
|
+
const { timeframe, selectedCOABalancesRange, selectedAdditionalBalances } = opExState.uiState;
|
|
44
|
+
const noFilter = newBalancesFilterProjectView(opExState.opEx.firstMonthOfFY, timeframe, selectedCOABalancesRange.numberOfPeriods, selectedCOABalancesRange.thisPeriod, 'ascending_date', selectedAdditionalBalances, opExProjectViewState.uiState.projectsToFilterOut);
|
|
45
|
+
return getOpExProjectView(noFilter, accountState, projectState, sectionsState, opExProjectViewState);
|
|
46
|
+
});
|
|
47
|
+
export const getOpExProjectViewForHighlightedRange = createSelector((state) => state.accountState, (state) => state.projectState, (state) => state.sectionProjectViewState, (state) => state.opExState, (state) => state.opExProjectViewState, (accountState, projectState, sectionsState, opExState, opExProjectViewState) => {
|
|
48
|
+
const { timeframe, highlightedCOABalancesRange, selectedAdditionalBalances, maxNumOfPeriodsToHighlight, } = opExState.uiState;
|
|
49
|
+
const filter = newBalancesFilterProjectView(opExState.opEx.firstMonthOfFY, timeframe, highlightedCOABalancesRange?.numberOfPeriods ??
|
|
50
|
+
maxNumOfPeriodsToHighlight, highlightedCOABalancesRange?.thisPeriod, 'ascending_date', selectedAdditionalBalances, opExProjectViewState.uiState.projectsToFilterOut);
|
|
51
|
+
return getOpExProjectView(filter, accountState, projectState, sectionsState, opExProjectViewState);
|
|
52
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -3,7 +3,6 @@ import { filter, switchMap } from 'rxjs/operators';
|
|
|
3
3
|
import { fetchNetBurnOrIncomeClassesView } from '../netBurnOrIncomeClassesView/netBurnOrIncomeClassesViewReducer';
|
|
4
4
|
import { fetchOpExClassesView } from '../opExClassesView/opExClassesViewReducer';
|
|
5
5
|
import { fetchProfitAndLossClassesView } from '../profitAndLossClassesView/profitAndLossClassesViewReducer';
|
|
6
|
-
import { fetchProfitAndLossProjectView } from '../profitAndLossProjectView/profitAndLossProjectViewReducer';
|
|
7
6
|
import { fetchRevenueClassesView } from '../revenueClassesView/revenueClassesViewReducer';
|
|
8
7
|
import { initiateReportsClassViewRefetching } from './reportsResyncReducer';
|
|
9
8
|
export const initiateReportsClassViewRefetchingEpic = (actions$,
|
|
@@ -24,9 +23,6 @@ _) => actions$.pipe(filter(initiateReportsClassViewRefetching.match), switchMap(
|
|
|
24
23
|
case 'net_burn_or_income_by_classes':
|
|
25
24
|
actions.push(fetchNetBurnOrIncomeClassesView(true));
|
|
26
25
|
break;
|
|
27
|
-
case 'profit_and_loss_by_projects':
|
|
28
|
-
actions.push(fetchProfitAndLossProjectView(true));
|
|
29
|
-
break;
|
|
30
26
|
default:
|
|
31
27
|
break;
|
|
32
28
|
}
|