@zeniai/client-epic-state 5.3.19 → 5.3.20
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/coaBalance.d.ts +9 -0
- package/lib/commonStateTypes/coaBalance/coaBalance.js +11 -0
- package/lib/epic.js +1 -0
- package/lib/esm/commonStateTypes/coaBalance/coaBalance.js +10 -0
- package/lib/esm/epic.js +2 -1
- package/lib/esm/view/balanceSheet/balanceSheetForTimeframeEpic.js +9 -4
- package/lib/esm/view/balanceSheet/balanceSheetReducer.js +2 -0
- package/lib/esm/view/cashFlow/cashFlowForTimeframeEpic.js +11 -5
- package/lib/esm/view/cashFlow/cashFlowReducer.js +2 -0
- package/lib/esm/view/financeStatement/financeStatementSelector.js +18 -0
- package/lib/esm/view/profitAndLoss/profitAndLossForTimeframeEpic.js +9 -4
- package/lib/esm/view/profitAndLoss/profitAndLossReducer.js +5 -1
- package/lib/esm/view/spendManagement/reimbursement/editRemiView/editRemiViewReducer.js +23 -3
- package/lib/esm/view/spendManagement/reimbursement/editRemiView/epics/fetchRemiAndInitializeLocalStoreEpic.js +17 -4
- package/lib/esm/view/spendManagement/reimbursement/remiDetailView/epics/fetchRemiDetailEpic.js +1 -1
- package/lib/esm/view/transactionList/filterTransactionsByTimePeriod.js +18 -0
- package/lib/esm/view/transactionList/transactionListByAccountSelector.js +2 -1
- package/lib/esm/view/transactionList/transactionListByCategoryTypeSelector.js +2 -1
- package/lib/esm/view/transactionList/transactionListByClassSelector.js +2 -1
- package/lib/esm/view/transactionList/transactionListByProjectSelector.js +2 -1
- package/lib/view/balanceSheet/balanceSheetForTimeframeEpic.js +8 -3
- package/lib/view/balanceSheet/balanceSheetReducer.js +2 -0
- package/lib/view/balanceSheet/balanceSheetState.d.ts +2 -0
- package/lib/view/cashFlow/cashFlowForTimeframeEpic.js +10 -4
- package/lib/view/cashFlow/cashFlowReducer.js +2 -0
- package/lib/view/cashFlow/cashFlowState.d.ts +2 -0
- package/lib/view/financeStatement/financeStatementSelector.d.ts +8 -0
- package/lib/view/financeStatement/financeStatementSelector.js +18 -0
- package/lib/view/profitAndLoss/profitAndLossForTimeframeEpic.js +8 -3
- package/lib/view/profitAndLoss/profitAndLossReducer.js +5 -1
- package/lib/view/profitAndLoss/profitAndLossState.d.ts +2 -1
- package/lib/view/spendManagement/reimbursement/editRemiView/editRemiViewReducer.d.ts +7 -2
- package/lib/view/spendManagement/reimbursement/editRemiView/editRemiViewReducer.js +24 -4
- package/lib/view/spendManagement/reimbursement/editRemiView/epics/fetchRemiAndInitializeLocalStoreEpic.d.ts +7 -4
- package/lib/view/spendManagement/reimbursement/editRemiView/epics/fetchRemiAndInitializeLocalStoreEpic.js +15 -1
- package/lib/view/spendManagement/reimbursement/remiDetailView/epics/fetchRemiDetailEpic.js +1 -1
- package/lib/view/transactionList/filterTransactionsByTimePeriod.d.ts +15 -0
- package/lib/view/transactionList/filterTransactionsByTimePeriod.js +22 -0
- package/lib/view/transactionList/transactionListByAccountSelector.js +2 -1
- package/lib/view/transactionList/transactionListByCategoryTypeSelector.js +2 -1
- package/lib/view/transactionList/transactionListByClassSelector.js +2 -1
- package/lib/view/transactionList/transactionListByProjectSelector.js +2 -1
- package/package.json +1 -1
|
@@ -29,6 +29,15 @@ export type COABalanceTimeFrame = NonNullable<ReturnType<typeof toCOABalanceTime
|
|
|
29
29
|
export type COABalanceMonthQuarterTimeframe = Extract<COABalanceTimeFrame, 'month' | 'quarter'>;
|
|
30
30
|
export type COABalanceMonthQuarterYearTimeframe = Exclude<COABalanceTimeFrame, 'free_range' | 'week'>;
|
|
31
31
|
export type FetchStateByTimeframe = Record<COABalanceMonthQuarterYearTimeframe, FetchStateAndError>;
|
|
32
|
+
/**
|
|
33
|
+
* Custom start/end (YYYY-MM-DD) sent with the last fetch of each timeframe. A timeframe is missing
|
|
34
|
+
* when its last fetch used the default periods, so the stored balances cover full periods.
|
|
35
|
+
*/
|
|
36
|
+
export type CustomDateRangeByTimeframe = Partial<Record<COABalanceMonthQuarterYearTimeframe, {
|
|
37
|
+
endDate: string;
|
|
38
|
+
startDate: string;
|
|
39
|
+
}>>;
|
|
40
|
+
export declare function withFetchedCustomDateRange(current: CustomDateRangeByTimeframe | undefined, timeframe: COABalanceMonthQuarterYearTimeframe, startDate: string | undefined, endDate: string | undefined): CustomDateRangeByTimeframe | undefined;
|
|
32
41
|
export interface COABalanceGroupedByPeriod {
|
|
33
42
|
months?: COABalance[];
|
|
34
43
|
quarters?: COABalance[];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.toCOABalanceTimeframe = void 0;
|
|
4
|
+
exports.withFetchedCustomDateRange = withFetchedCustomDateRange;
|
|
4
5
|
const stringToUnion_1 = require("../stringToUnion");
|
|
5
6
|
/**
|
|
6
7
|
* COA balance time frame
|
|
@@ -19,3 +20,13 @@ const ALL_COA_BALANCE_TIMEFRAME = [
|
|
|
19
20
|
];
|
|
20
21
|
const toCOABalanceTimeframe = (v) => (0, stringToUnion_1.stringToUnionStrict)(v?.toLocaleLowerCase() ?? '', ALL_COA_BALANCE_TIMEFRAME);
|
|
21
22
|
exports.toCOABalanceTimeframe = toCOABalanceTimeframe;
|
|
23
|
+
function withFetchedCustomDateRange(current, timeframe, startDate, endDate) {
|
|
24
|
+
const next = { ...current };
|
|
25
|
+
if (startDate != null && endDate != null) {
|
|
26
|
+
next[timeframe] = { startDate, endDate };
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
delete next[timeframe];
|
|
30
|
+
}
|
|
31
|
+
return Object.keys(next).length > 0 ? next : undefined;
|
|
32
|
+
}
|
package/lib/epic.js
CHANGED
|
@@ -1579,6 +1579,7 @@ const ALL_EPICS = [
|
|
|
1579
1579
|
fetchOpExWithForecastEpic_1.waitForForecastListThenFetchOpExWithForecastEpic,
|
|
1580
1580
|
fetchRevenueWithForecastEpic_1.waitForForecastListThenFetchRevenueWithForecastEpic,
|
|
1581
1581
|
fetchRecommendationsAndUpdateMerchantRecommendationsEpic_1.waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchantEpic,
|
|
1582
|
+
fetchRemiAndInitializeLocalStoreEpic_1.waitForRemiDetailThenInitializeLocalStoreEpic,
|
|
1582
1583
|
fetchVendorAndUpdateBillLocalDataEpic_1.waitForVendorByIdThenSaveBillUpdatetoLocalStoreEpic,
|
|
1583
1584
|
fetchVendorByNameAndParseInvoice_1.waitForVendorByNameThenParsetoLocalStoreEpic,
|
|
1584
1585
|
fetchBillDetailEpic_1.waitForVendorByNameThenUpdateBillDetailEpic,
|
|
@@ -15,3 +15,13 @@ const ALL_COA_BALANCE_TIMEFRAME = [
|
|
|
15
15
|
'free_range',
|
|
16
16
|
];
|
|
17
17
|
export const toCOABalanceTimeframe = (v) => stringToUnionStrict(v?.toLocaleLowerCase() ?? '', ALL_COA_BALANCE_TIMEFRAME);
|
|
18
|
+
export function withFetchedCustomDateRange(current, timeframe, startDate, endDate) {
|
|
19
|
+
const next = { ...current };
|
|
20
|
+
if (startDate != null && endDate != null) {
|
|
21
|
+
next[timeframe] = { startDate, endDate };
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
delete next[timeframe];
|
|
25
|
+
}
|
|
26
|
+
return Object.keys(next).length > 0 ? next : undefined;
|
|
27
|
+
}
|
package/lib/esm/epic.js
CHANGED
|
@@ -636,7 +636,7 @@ import { saveRealTimeApprovalEpic, } from './view/spendManagement/realTimeApprov
|
|
|
636
636
|
import { fetchCurrencyConversionValueEpic, } from './view/spendManagement/reimbursement/editRemiView/epics/fetchCurrencyConversionValueEpic';
|
|
637
637
|
import { fetchEditRemiDetailPageEpic, } from './view/spendManagement/reimbursement/editRemiView/epics/fetchEditRemiDetailPageEpic';
|
|
638
638
|
import { fetchRecommendationsAndUpdateMerchantRecommendationsEpic, waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchantEpic, } from './view/spendManagement/reimbursement/editRemiView/epics/fetchRecommendationsAndUpdateMerchantRecommendationsEpic';
|
|
639
|
-
import { fetchRemiAndInitializeLocalStoreEpic, } from './view/spendManagement/reimbursement/editRemiView/epics/fetchRemiAndInitializeLocalStoreEpic';
|
|
639
|
+
import { fetchRemiAndInitializeLocalStoreEpic, waitForRemiDetailThenInitializeLocalStoreEpic, } from './view/spendManagement/reimbursement/editRemiView/epics/fetchRemiAndInitializeLocalStoreEpic';
|
|
640
640
|
import { initializeRemiToLocalStoreEpic, } from './view/spendManagement/reimbursement/editRemiView/epics/initializeRemiToLocalStoreEpic';
|
|
641
641
|
import { parseReceiptsToRemiEpic, } from './view/spendManagement/reimbursement/editRemiView/epics/parseReceiptsToRemiEpic';
|
|
642
642
|
import { saveRemiDetailEpic, } from './view/spendManagement/reimbursement/editRemiView/epics/saveRemiDetailEpic';
|
|
@@ -1576,6 +1576,7 @@ const ALL_EPICS = [
|
|
|
1576
1576
|
waitForForecastListThenFetchOpExWithForecastEpic,
|
|
1577
1577
|
waitForForecastListThenFetchRevenueWithForecastEpic,
|
|
1578
1578
|
waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchantEpic,
|
|
1579
|
+
waitForRemiDetailThenInitializeLocalStoreEpic,
|
|
1579
1580
|
waitForVendorByIdThenSaveBillUpdatetoLocalStoreEpic,
|
|
1580
1581
|
waitForVendorByNameThenParsetoLocalStoreEpic,
|
|
1581
1582
|
waitForVendorByNameThenUpdateBillDetailEpic,
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { from, of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
2
|
+
import { catchError, filter, groupBy, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
3
|
import { updateCalculatedSectionAccountsView, updateSectionAccountsView, } from '../../entity/sectionAccountsView/sectionAccountsViewReducer';
|
|
4
4
|
import { createZeniAPIStatus, isSuccessResponse } from '../../responsePayload';
|
|
5
5
|
import { ALL_ASSETS_SECTIONS, ALL_CURRENT_ASSETS_SECTIONS, ALL_CURRENT_LIABILITIES_SECTIONS, ALL_LIABILITIES_SECTIONS, toSectionId, } from './balanceSheetPayload';
|
|
6
6
|
import { fetchBalanceSheetForTimeframe, updateBalanceSheetForTimeframe, updateBalanceSheetForTimeframeFailure, } from './balanceSheetReducer';
|
|
7
7
|
export const reportIdUniqueKey = () => 'balance_sheet';
|
|
8
|
-
export const fetchBalanceSheetForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchBalanceSheetForTimeframe.match),
|
|
8
|
+
export const fetchBalanceSheetForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchBalanceSheetForTimeframe.match),
|
|
9
|
+
// One stream per timeframe: a newer request for the same timeframe (e.g. a
|
|
10
|
+
// custom-date-range change, or a dated fetch right after a default one)
|
|
11
|
+
// cancels the older in-flight request so a stale response can't land last.
|
|
12
|
+
groupBy((action) => action.payload.timeframe), mergeMap((group$) => group$.pipe(switchMap((action) => {
|
|
9
13
|
const getTimeSeriesGroup = (timeframe) => {
|
|
10
14
|
switch (timeframe) {
|
|
11
15
|
case 'month':
|
|
@@ -20,7 +24,8 @@ export const fetchBalanceSheetForTimeframeEpic = (actions$, _, zeniAPI) => actio
|
|
|
20
24
|
is_full_response: action.payload.fetchFullReport,
|
|
21
25
|
time_series_groups: [getTimeSeriesGroup(action.payload.timeframe)],
|
|
22
26
|
};
|
|
23
|
-
if (action.payload.startDate != null &&
|
|
27
|
+
if (action.payload.startDate != null &&
|
|
28
|
+
action.payload.endDate != null) {
|
|
24
29
|
queryValue.custom_start_date = action.payload.startDate;
|
|
25
30
|
queryValue.custom_end_date = action.payload.endDate;
|
|
26
31
|
}
|
|
@@ -73,4 +78,4 @@ export const fetchBalanceSheetForTimeframeEpic = (actions$, _, zeniAPI) => actio
|
|
|
73
78
|
}
|
|
74
79
|
}), catchError((error) => of(updateBalanceSheetForTimeframeFailure(createZeniAPIStatus('Unexpected Error', 'Balance Sheet REST API call errored out' +
|
|
75
80
|
JSON.stringify(error)), action.payload.timeframe))));
|
|
76
|
-
}));
|
|
81
|
+
}))));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
2
|
import { mapReportPayloadV2ToReportV2 } from '../../commonPayloadTypes/v2/viewAndReportPayloadv2';
|
|
3
|
+
import { withFetchedCustomDateRange } from '../../commonStateTypes/coaBalance/coaBalance';
|
|
3
4
|
import { clearAll } from '../../rootActions';
|
|
4
5
|
export const initialState = {
|
|
5
6
|
bookCloseDate: undefined,
|
|
@@ -62,6 +63,7 @@ const balanceSheet = createSlice({
|
|
|
62
63
|
fetchState: 'In-Progress',
|
|
63
64
|
error: undefined,
|
|
64
65
|
};
|
|
66
|
+
draft.customDateRangeByTimeframe = withFetchedCustomDateRange(draft.customDateRangeByTimeframe, timeframe, action.payload.startDate, action.payload.endDate);
|
|
65
67
|
},
|
|
66
68
|
},
|
|
67
69
|
updateBalanceSheetForTimeframe(draft, action) {
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { from, of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
2
|
+
import { catchError, filter, groupBy, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
3
|
import { updateCalculatedSectionAccountsView, updateSectionAccountsView, } from '../../entity/sectionAccountsView/sectionAccountsViewReducer';
|
|
4
4
|
import { createZeniAPIStatus, isSuccessResponse } from '../../responsePayload';
|
|
5
5
|
import { toCashFlowReportViewID, } from './cashFlowPayload';
|
|
6
6
|
import { fetchCashFlowForTimeframe, updateCashFlowForTimeframe, updateCashFlowForTimeframeFailure, } from './cashFlowReducer';
|
|
7
7
|
export const reportIdUniqueKey = () => 'cash_flow';
|
|
8
|
-
export const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchCashFlowForTimeframe.match),
|
|
8
|
+
export const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchCashFlowForTimeframe.match),
|
|
9
|
+
// One stream per timeframe: a newer request for the same timeframe (e.g. a
|
|
10
|
+
// custom-date-range change, or a dated fetch right after a default one)
|
|
11
|
+
// cancels the older in-flight request so a stale response can't land last.
|
|
12
|
+
groupBy((action) => action.payload.timeframe), mergeMap((group$) => group$.pipe(switchMap((action) => {
|
|
9
13
|
const getTimeSeriesGroup = (timeframe) => {
|
|
10
14
|
switch (timeframe) {
|
|
11
15
|
case 'month':
|
|
@@ -20,7 +24,8 @@ export const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.
|
|
|
20
24
|
is_full_response: action.payload.fetchFullReport,
|
|
21
25
|
time_series_groups: [getTimeSeriesGroup(action.payload.timeframe)],
|
|
22
26
|
};
|
|
23
|
-
if (action.payload.startDate != null &&
|
|
27
|
+
if (action.payload.startDate != null &&
|
|
28
|
+
action.payload.endDate != null) {
|
|
24
29
|
queryValue.custom_start_date = action.payload.startDate;
|
|
25
30
|
queryValue.custom_end_date = action.payload.endDate;
|
|
26
31
|
}
|
|
@@ -48,5 +53,6 @@ export const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.
|
|
|
48
53
|
else {
|
|
49
54
|
return of(updateCashFlowForTimeframeFailure(response.status, action.payload.timeframe));
|
|
50
55
|
}
|
|
51
|
-
}), catchError((error) => of(updateCashFlowForTimeframeFailure(createZeniAPIStatus('Unexpected Error', 'Cash Flow REST API call errored out' +
|
|
52
|
-
|
|
56
|
+
}), catchError((error) => of(updateCashFlowForTimeframeFailure(createZeniAPIStatus('Unexpected Error', 'Cash Flow REST API call errored out' +
|
|
57
|
+
JSON.stringify(error)), action.payload.timeframe))));
|
|
58
|
+
}))));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
2
|
import { mapReportPayloadV2ToReportV2 } from '../../commonPayloadTypes/v2/viewAndReportPayloadv2';
|
|
3
|
+
import { withFetchedCustomDateRange } from '../../commonStateTypes/coaBalance/coaBalance';
|
|
3
4
|
import { clearAll } from '../../rootActions';
|
|
4
5
|
export const initialState = {
|
|
5
6
|
fetchState: {
|
|
@@ -54,6 +55,7 @@ const cashFlow = createSlice({
|
|
|
54
55
|
fetchState: 'In-Progress',
|
|
55
56
|
error: undefined,
|
|
56
57
|
};
|
|
58
|
+
draft.customDateRangeByTimeframe = withFetchedCustomDateRange(draft.customDateRangeByTimeframe, timeframe, action.payload.startDate, action.payload.endDate);
|
|
57
59
|
},
|
|
58
60
|
},
|
|
59
61
|
updateCashFlowForTimeframe(draft, action) {
|
|
@@ -161,6 +161,23 @@ export const getFinanceStatement = createSelector((state) => state.accountState,
|
|
|
161
161
|
default:
|
|
162
162
|
break;
|
|
163
163
|
}
|
|
164
|
+
let customDateRangeByTimeframe;
|
|
165
|
+
switch (financeStatementState.selectedReportId) {
|
|
166
|
+
case 'profit_and_loss':
|
|
167
|
+
customDateRangeByTimeframe =
|
|
168
|
+
profitAndLossState.pandL.customDateRangeByTimeframe;
|
|
169
|
+
break;
|
|
170
|
+
case 'balance_sheet':
|
|
171
|
+
customDateRangeByTimeframe =
|
|
172
|
+
balanceSheetState.customDateRangeByTimeframe;
|
|
173
|
+
break;
|
|
174
|
+
case 'cash_flow':
|
|
175
|
+
customDateRangeByTimeframe = cashFlowState.customDateRangeByTimeframe;
|
|
176
|
+
break;
|
|
177
|
+
default:
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
const selectedReportCustomDateRange = customDateRangeByTimeframe?.[financeStatementState.timeframe];
|
|
164
181
|
return {
|
|
165
182
|
reportId: 'finance_statement',
|
|
166
183
|
reportTitle: '',
|
|
@@ -170,6 +187,7 @@ export const getFinanceStatement = createSelector((state) => state.accountState,
|
|
|
170
187
|
allTimeframeTicks,
|
|
171
188
|
balancesInTimeframe,
|
|
172
189
|
selectedReportAndTimeframeFetchState,
|
|
190
|
+
selectedReportCustomDateRange,
|
|
173
191
|
displayOrder: financeStatementState.displayOrder,
|
|
174
192
|
reportFormat: financeStatementState.reportFormat,
|
|
175
193
|
firstMonthOfFY,
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { from, of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
2
|
+
import { catchError, filter, groupBy, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
3
|
import { updateCalculatedSectionAccountsView, updateSectionAccountsView, } from '../../entity/sectionAccountsView/sectionAccountsViewReducer';
|
|
4
4
|
import { createZeniAPIStatus, isSuccessResponse } from '../../responsePayload';
|
|
5
5
|
import { fetchProfitAndLossForTimeframe, updateProfitAndLossForTimeframe, updateProfitAndLossForTimeframeFailure, } from './profitAndLossReducer';
|
|
6
6
|
export const reportIdUniqueKey = (forecastId) => forecastId != null
|
|
7
7
|
? `profit_and_loss+${forecastId}`
|
|
8
8
|
: 'profit_and_loss';
|
|
9
|
-
export const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchProfitAndLossForTimeframe.match),
|
|
9
|
+
export const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe(filter(fetchProfitAndLossForTimeframe.match),
|
|
10
|
+
// One stream per timeframe: a newer request for the same timeframe (e.g. a
|
|
11
|
+
// custom-date-range change, or a dated fetch right after a default one)
|
|
12
|
+
// cancels the older in-flight request so a stale response can't land last.
|
|
13
|
+
groupBy((action) => `${action.payload.forecastId ?? ''}_${action.payload.timeframe}`), mergeMap((group$) => group$.pipe(switchMap((action) => {
|
|
10
14
|
const getTimeSeriesGroup = (timeframe) => {
|
|
11
15
|
switch (timeframe) {
|
|
12
16
|
case 'month':
|
|
@@ -25,7 +29,8 @@ export const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => acti
|
|
|
25
29
|
queryValue.forecast_id = action.payload.forecastId;
|
|
26
30
|
queryValue.is_forecast_vs_actual = true;
|
|
27
31
|
}
|
|
28
|
-
if (action.payload.startDate != null &&
|
|
32
|
+
if (action.payload.startDate != null &&
|
|
33
|
+
action.payload.endDate != null) {
|
|
29
34
|
queryValue.custom_start_date = action.payload.startDate;
|
|
30
35
|
queryValue.custom_end_date = action.payload.endDate;
|
|
31
36
|
}
|
|
@@ -55,4 +60,4 @@ export const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => acti
|
|
|
55
60
|
return of(updateProfitAndLossForTimeframeFailure(response.status, action.payload.forecastId, action.payload.timeframe));
|
|
56
61
|
}
|
|
57
62
|
}), catchError((error) => of(updateProfitAndLossForTimeframeFailure(createZeniAPIStatus('Unexpected Error', 'P&L REST API call errored out' + JSON.stringify(error)), action.payload.forecastId, action.payload.timeframe))));
|
|
58
|
-
}));
|
|
63
|
+
}))));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
2
|
import { mapReportPayloadV2ToReportV2 } from '../../commonPayloadTypes/v2/viewAndReportPayloadv2';
|
|
3
|
+
import { withFetchedCustomDateRange } from '../../commonStateTypes/coaBalance/coaBalance';
|
|
3
4
|
import { clearAll } from '../../rootActions';
|
|
4
5
|
export const initialPandLState = {
|
|
5
6
|
bookCloseDate: undefined,
|
|
@@ -71,7 +72,10 @@ const profitAndLoss = createSlice({
|
|
|
71
72
|
fetchState: 'In-Progress',
|
|
72
73
|
error: undefined,
|
|
73
74
|
};
|
|
74
|
-
updateState(draft, action.payload.forecastId, {
|
|
75
|
+
updateState(draft, action.payload.forecastId, {
|
|
76
|
+
fetchState,
|
|
77
|
+
customDateRangeByTimeframe: withFetchedCustomDateRange(pAndLState.customDateRangeByTimeframe, timeframe, action.payload.startDate, action.payload.endDate),
|
|
78
|
+
});
|
|
75
79
|
},
|
|
76
80
|
},
|
|
77
81
|
updateProfitAndLossForTimeframe(draft, action) {
|
|
@@ -30,8 +30,13 @@ const editRemiView = createSlice({
|
|
|
30
30
|
};
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
|
-
indicateReadyToInitializeRemiLocalStore
|
|
34
|
-
|
|
33
|
+
indicateReadyToInitializeRemiLocalStore: {
|
|
34
|
+
reducer() {
|
|
35
|
+
// do nothing
|
|
36
|
+
},
|
|
37
|
+
prepare(reimbursementId) {
|
|
38
|
+
return { payload: { reimbursementId } };
|
|
39
|
+
},
|
|
35
40
|
},
|
|
36
41
|
fetchRecommendationsAndUpdateMerchantRecommendations: {
|
|
37
42
|
reducer() {
|
|
@@ -137,6 +142,21 @@ const editRemiView = createSlice({
|
|
|
137
142
|
return { payload: { reimbursementId } };
|
|
138
143
|
},
|
|
139
144
|
},
|
|
145
|
+
initializeRemiToLocalStoreFailure: {
|
|
146
|
+
reducer(draft, action) {
|
|
147
|
+
const { reimbursementId, error } = action.payload;
|
|
148
|
+
draft.editRemiStateById[reimbursementId] = {
|
|
149
|
+
...draft.editRemiStateById[reimbursementId],
|
|
150
|
+
fetchStatus: {
|
|
151
|
+
fetchState: 'Error',
|
|
152
|
+
error,
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
},
|
|
156
|
+
prepare(reimbursementId, error) {
|
|
157
|
+
return { payload: { reimbursementId, error } };
|
|
158
|
+
},
|
|
159
|
+
},
|
|
140
160
|
saveRemiUpdatesToLocalStore(draft, action) {
|
|
141
161
|
if (action.payload.reimbursementId != null) {
|
|
142
162
|
const reimbursementId = action.payload.reimbursementId;
|
|
@@ -387,7 +407,7 @@ const editRemiView = createSlice({
|
|
|
387
407
|
});
|
|
388
408
|
},
|
|
389
409
|
});
|
|
390
|
-
export const { fetchEditRemiDetailPage, fetchRemiAndInitializeLocalStore, initializeRemiToLocalStore, fetchRecommendationsAndUpdateMerchantRecommendations, saveRemiUpdatesToLocalStore, updatesPaymentToInLocalStore, discardRemiUpdatesInLocalStore, removeFileFromRemiUpdatesInLocalStore, saveRemiDetail, saveRemiSuccessOrFailure, parseReceiptsToRemi, fetchCurrencyConversionValue, updateReimbursementType, updateHomeCurrencyConversion, currencyConversionValueSuccessOrFailure, waitForRemiDetailThenInitializeLocalStore, waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant, updateAddRemiAutoFields, indicateReadyToInitializeRemiLocalStore, updateUploadFetchState, updateRecommendationInMerchant, updateTentativeMerchantNames, clearTentativeMerchantName, clearAddRemiAutoFields, } = editRemiView.actions;
|
|
410
|
+
export const { fetchEditRemiDetailPage, fetchRemiAndInitializeLocalStore, initializeRemiToLocalStore, fetchRecommendationsAndUpdateMerchantRecommendations, saveRemiUpdatesToLocalStore, updatesPaymentToInLocalStore, discardRemiUpdatesInLocalStore, removeFileFromRemiUpdatesInLocalStore, saveRemiDetail, saveRemiSuccessOrFailure, parseReceiptsToRemi, fetchCurrencyConversionValue, updateReimbursementType, updateHomeCurrencyConversion, currencyConversionValueSuccessOrFailure, waitForRemiDetailThenInitializeLocalStore, initializeRemiToLocalStoreFailure, waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant, updateAddRemiAutoFields, indicateReadyToInitializeRemiLocalStore, updateUploadFetchState, updateRecommendationInMerchant, updateTentativeMerchantNames, clearTentativeMerchantName, clearAddRemiAutoFields, } = editRemiView.actions;
|
|
391
411
|
export default editRemiView.reducer;
|
|
392
412
|
const doUpdateRecommendationForEntity = (draft, lineId, recommendations, shouldAutofill, reimbursementId, reimbursementStageCode) => {
|
|
393
413
|
if (reimbursementId != null) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import recordGet from 'lodash/get';
|
|
2
|
-
import { from } from 'rxjs';
|
|
3
|
-
import { filter, mergeMap } from 'rxjs/operators';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { from, merge } from 'rxjs';
|
|
3
|
+
import { filter, map, mergeMap, take, takeUntil, takeWhile, } from 'rxjs/operators';
|
|
4
|
+
import { clearAll } from '../../../../../rootActions';
|
|
5
|
+
import { fetchRemiDetail, updateRemiDetailFetchState, } from '../../remiDetailView/remiDetailViewReducer';
|
|
6
|
+
import { fetchRemiAndInitializeLocalStore, indicateReadyToInitializeRemiLocalStore, initializeRemiToLocalStore, initializeRemiToLocalStoreFailure, waitForRemiDetailThenInitializeLocalStore, } from '../editRemiViewReducer';
|
|
6
7
|
export const fetchRemiAndInitializeLocalStoreEpic = (actions$, state$) => actions$.pipe(filter(fetchRemiAndInitializeLocalStore.match), mergeMap((action) => {
|
|
7
8
|
const { reimbursementId, cacheOverride, isShowDeletedReimbursementEnabled, } = action.payload;
|
|
8
9
|
const state = state$.value;
|
|
@@ -35,3 +36,15 @@ export const fetchRemiAndInitializeLocalStoreEpic = (actions$, state$) => action
|
|
|
35
36
|
}
|
|
36
37
|
return from(remiDetailActions);
|
|
37
38
|
}));
|
|
39
|
+
export const waitForRemiDetailThenInitializeLocalStoreEpic = (actions$) => actions$.pipe(filter(waitForRemiDetailThenInitializeLocalStore.match), mergeMap((action) => {
|
|
40
|
+
const { reimbursementId } = action.payload;
|
|
41
|
+
const ready$ = actions$.pipe(filter(indicateReadyToInitializeRemiLocalStore.match), filter((readyAction) => readyAction.payload.reimbursementId === reimbursementId), take(1), map(() => initializeRemiToLocalStore(reimbursementId)));
|
|
42
|
+
const failed$ = actions$.pipe(filter(updateRemiDetailFetchState.match), filter((fetchStateAction) => fetchStateAction.payload.reimbursementId === reimbursementId &&
|
|
43
|
+
fetchStateAction.payload.fetchState === 'Error'), map((fetchStateAction) => initializeRemiToLocalStoreFailure(reimbursementId, fetchStateAction.payload.error)));
|
|
44
|
+
const supersededOrCleared$ = actions$.pipe(filter((nextAction) => clearAll.match(nextAction) ||
|
|
45
|
+
(waitForRemiDetailThenInitializeLocalStore.match(nextAction) &&
|
|
46
|
+
nextAction.payload.reimbursementId === reimbursementId)));
|
|
47
|
+
// An Error does not end the wait: a newer request for the same id may still succeed.
|
|
48
|
+
// After an Error, supersededOrCleared$ is what ends it.
|
|
49
|
+
return merge(ready$, failed$).pipe(takeWhile((resultAction) => !initializeRemiToLocalStore.match(resultAction), true), takeUntil(supersededOrCleared$));
|
|
50
|
+
}));
|
package/lib/esm/view/spendManagement/reimbursement/remiDetailView/epics/fetchRemiDetailEpic.js
CHANGED
|
@@ -75,7 +75,7 @@ export const fetchRemiDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe(
|
|
|
75
75
|
}));
|
|
76
76
|
}
|
|
77
77
|
});
|
|
78
|
-
actions.push(indicateReadyToInitializeRemiLocalStore());
|
|
78
|
+
actions.push(indicateReadyToInitializeRemiLocalStore(reimbursementId));
|
|
79
79
|
if (response.data.transaction?.lines != null &&
|
|
80
80
|
response.data.transaction.lines.length > 0) {
|
|
81
81
|
actions.push(fetchDuplicateReimbursement(response.data.transaction.created_by_user_id, false, response.data.transaction.transaction_id));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DEFAULT_DATE_FORMAT, toString, } from '../../commonStateTypes/timePeriod';
|
|
2
|
+
/**
|
|
3
|
+
* Transaction lists are fetched and cached in month buckets: `splitPeriod`
|
|
4
|
+
* snaps the first bucket back to the 1st of the month, while the last bucket
|
|
5
|
+
* is fetched with the real end date. So a period that starts mid-month (e.g. a
|
|
6
|
+
* drill-down from the custom-date-range column "Jun 17-30 2026") pulls in the
|
|
7
|
+
* days before its start. Drop those so the list reconciles to the clicked
|
|
8
|
+
* figure. Periods starting on the 1st (every pre-existing caller) are returned
|
|
9
|
+
* untouched. Compares calendar days as `YYYY-MM-DD` strings so the viewer's
|
|
10
|
+
* timezone can't shift the boundary.
|
|
11
|
+
*/
|
|
12
|
+
export const filterTransactionsByTimePeriod = (transactions, period) => {
|
|
13
|
+
if (period.start.day === 1) {
|
|
14
|
+
return transactions;
|
|
15
|
+
}
|
|
16
|
+
const start = toString(period.start);
|
|
17
|
+
return transactions.filter((transaction) => transaction.date.format(DEFAULT_DATE_FORMAT) >= start);
|
|
18
|
+
};
|
|
@@ -2,6 +2,7 @@ import flatMap from 'lodash/flatMap';
|
|
|
2
2
|
import recordGet from 'lodash/get';
|
|
3
3
|
import orderBy from 'lodash/orderBy';
|
|
4
4
|
import { getSupportedTransactionById } from '../../entity/transaction/transactionSelector';
|
|
5
|
+
import { filterTransactionsByTimePeriod } from './filterTransactionsByTimePeriod';
|
|
5
6
|
import { splitPeriod } from './parallelFetchAccountTransactionListEpic';
|
|
6
7
|
import { isAnyFetchCompleted, reduceFetchState, } from './reduceTransactionListFetchState';
|
|
7
8
|
import { getAcKey, getAcTranKey, } from './transactionListState';
|
|
@@ -29,7 +30,7 @@ export const getTransactionListByAccount = (transactionState, transactionListSta
|
|
|
29
30
|
}
|
|
30
31
|
return value != null;
|
|
31
32
|
});
|
|
32
|
-
transactions = orderBy(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
|
|
33
|
+
transactions = orderBy(filterTransactionsByTimePeriod(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
|
|
33
34
|
}
|
|
34
35
|
const key = getAcKey(accountId, accountType);
|
|
35
36
|
const uiState = recordGet(transactionListState.byAccount.transactionListUIStateByAccountKey, key, {});
|
|
@@ -2,6 +2,7 @@ import flatMap from 'lodash/flatMap';
|
|
|
2
2
|
import recordGet from 'lodash/get';
|
|
3
3
|
import orderBy from 'lodash/orderBy';
|
|
4
4
|
import { getSupportedTransactionById } from '../../entity/transaction/transactionSelector';
|
|
5
|
+
import { filterTransactionsByTimePeriod } from './filterTransactionsByTimePeriod';
|
|
5
6
|
import { splitPeriod } from './parallelFetchAccountTransactionListEpic';
|
|
6
7
|
import { isAnyFetchCompleted, reduceFetchState, } from './reduceTransactionListFetchState';
|
|
7
8
|
import { getCategoryTypeTranKey, } from './transactionListState';
|
|
@@ -26,7 +27,7 @@ export const getTransactionsListByCategoryType = (transactionState, transactionL
|
|
|
26
27
|
}
|
|
27
28
|
return value != null;
|
|
28
29
|
});
|
|
29
|
-
transactions = orderBy(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
|
|
30
|
+
transactions = orderBy(filterTransactionsByTimePeriod(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
|
|
30
31
|
}
|
|
31
32
|
const uiState = transactionListState.byType[transactionCategoryType].transactionListUIState;
|
|
32
33
|
return {
|
|
@@ -2,6 +2,7 @@ import flatMap from 'lodash/flatMap';
|
|
|
2
2
|
import recordGet from 'lodash/get';
|
|
3
3
|
import orderBy from 'lodash/orderBy';
|
|
4
4
|
import { getSupportedTransactionById } from '../../entity/transaction/transactionSelector';
|
|
5
|
+
import { filterTransactionsByTimePeriod } from './filterTransactionsByTimePeriod';
|
|
5
6
|
import { splitPeriod } from './parallelFetchAccountTransactionListEpic';
|
|
6
7
|
import { isAnyFetchCompleted, reduceFetchState, } from './reduceTransactionListFetchState';
|
|
7
8
|
import { getClassAcKey, getClassAcTranKey, } from './transactionListState';
|
|
@@ -29,7 +30,7 @@ export const getTransactionListByClass = (transactionState, transactionListState
|
|
|
29
30
|
}
|
|
30
31
|
return value != null;
|
|
31
32
|
});
|
|
32
|
-
transactions = orderBy(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
|
|
33
|
+
transactions = orderBy(filterTransactionsByTimePeriod(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
|
|
33
34
|
}
|
|
34
35
|
const key = getClassAcKey(accountId, accountType, classId);
|
|
35
36
|
const uiState = recordGet(transactionListState.byClass.transactionListUIStateByClassKey, key, {});
|
|
@@ -2,6 +2,7 @@ import flatMap from 'lodash/flatMap';
|
|
|
2
2
|
import recordGet from 'lodash/get';
|
|
3
3
|
import orderBy from 'lodash/orderBy';
|
|
4
4
|
import { getSupportedTransactionById } from '../../entity/transaction/transactionSelector';
|
|
5
|
+
import { filterTransactionsByTimePeriod } from './filterTransactionsByTimePeriod';
|
|
5
6
|
import { splitPeriod } from './parallelFetchAccountTransactionListEpic';
|
|
6
7
|
import { isAnyFetchCompleted, reduceFetchState, } from './reduceTransactionListFetchState';
|
|
7
8
|
import { getProjectAcKey, getProjectAcTranKey, } from './transactionListState';
|
|
@@ -29,7 +30,7 @@ export const getTransactionListByProject = (transactionState, transactionListSta
|
|
|
29
30
|
}
|
|
30
31
|
return value != null;
|
|
31
32
|
});
|
|
32
|
-
transactions = orderBy(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
|
|
33
|
+
transactions = orderBy(filterTransactionsByTimePeriod(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
|
|
33
34
|
}
|
|
34
35
|
const key = getProjectAcKey(accountId, accountType, projectId);
|
|
35
36
|
const uiState = recordGet(transactionListState.byProject.transactionListUIStateByProjectKey, key, {});
|
|
@@ -9,7 +9,11 @@ const balanceSheetPayload_1 = require("./balanceSheetPayload");
|
|
|
9
9
|
const balanceSheetReducer_1 = require("./balanceSheetReducer");
|
|
10
10
|
const reportIdUniqueKey = () => 'balance_sheet';
|
|
11
11
|
exports.reportIdUniqueKey = reportIdUniqueKey;
|
|
12
|
-
const fetchBalanceSheetForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(balanceSheetReducer_1.fetchBalanceSheetForTimeframe.match),
|
|
12
|
+
const fetchBalanceSheetForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(balanceSheetReducer_1.fetchBalanceSheetForTimeframe.match),
|
|
13
|
+
// One stream per timeframe: a newer request for the same timeframe (e.g. a
|
|
14
|
+
// custom-date-range change, or a dated fetch right after a default one)
|
|
15
|
+
// cancels the older in-flight request so a stale response can't land last.
|
|
16
|
+
(0, operators_1.groupBy)((action) => action.payload.timeframe), (0, operators_1.mergeMap)((group$) => group$.pipe((0, operators_1.switchMap)((action) => {
|
|
13
17
|
const getTimeSeriesGroup = (timeframe) => {
|
|
14
18
|
switch (timeframe) {
|
|
15
19
|
case 'month':
|
|
@@ -24,7 +28,8 @@ const fetchBalanceSheetForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pip
|
|
|
24
28
|
is_full_response: action.payload.fetchFullReport,
|
|
25
29
|
time_series_groups: [getTimeSeriesGroup(action.payload.timeframe)],
|
|
26
30
|
};
|
|
27
|
-
if (action.payload.startDate != null &&
|
|
31
|
+
if (action.payload.startDate != null &&
|
|
32
|
+
action.payload.endDate != null) {
|
|
28
33
|
queryValue.custom_start_date = action.payload.startDate;
|
|
29
34
|
queryValue.custom_end_date = action.payload.endDate;
|
|
30
35
|
}
|
|
@@ -77,5 +82,5 @@ const fetchBalanceSheetForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pip
|
|
|
77
82
|
}
|
|
78
83
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, balanceSheetReducer_1.updateBalanceSheetForTimeframeFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Balance Sheet REST API call errored out' +
|
|
79
84
|
JSON.stringify(error)), action.payload.timeframe))));
|
|
80
|
-
}));
|
|
85
|
+
}))));
|
|
81
86
|
exports.fetchBalanceSheetForTimeframeEpic = fetchBalanceSheetForTimeframeEpic;
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.resetBalanceSheetNodeCollapseState = exports.updateBalanceSheetUIState = exports.updateBalanceSheetForTimeframeFailure = exports.updateBalanceSheetForTimeframe = exports.fetchBalanceSheetForTimeframe = exports.fetchBalanceSheet = exports.initialState = void 0;
|
|
5
5
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
6
6
|
const viewAndReportPayloadv2_1 = require("../../commonPayloadTypes/v2/viewAndReportPayloadv2");
|
|
7
|
+
const coaBalance_1 = require("../../commonStateTypes/coaBalance/coaBalance");
|
|
7
8
|
const rootActions_1 = require("../../rootActions");
|
|
8
9
|
exports.initialState = {
|
|
9
10
|
bookCloseDate: undefined,
|
|
@@ -66,6 +67,7 @@ const balanceSheet = (0, toolkit_1.createSlice)({
|
|
|
66
67
|
fetchState: 'In-Progress',
|
|
67
68
|
error: undefined,
|
|
68
69
|
};
|
|
70
|
+
draft.customDateRangeByTimeframe = (0, coaBalance_1.withFetchedCustomDateRange)(draft.customDateRangeByTimeframe, timeframe, action.payload.startDate, action.payload.endDate);
|
|
69
71
|
},
|
|
70
72
|
},
|
|
71
73
|
updateBalanceSheetForTimeframe(draft, action) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CustomDateRangeByTimeframe } from '../../commonStateTypes/coaBalance/coaBalance';
|
|
1
2
|
import { FetchStateAndError, ID } from '../../commonStateTypes/common';
|
|
2
3
|
import { Report } from '../../commonStateTypes/viewAndReport/viewAndReport';
|
|
3
4
|
export interface BalanceSheetUIState {
|
|
@@ -14,4 +15,5 @@ export interface BalanceSheetState extends Report {
|
|
|
14
15
|
year: FetchStateAndError;
|
|
15
16
|
};
|
|
16
17
|
uiState: BalanceSheetUIState;
|
|
18
|
+
customDateRangeByTimeframe?: CustomDateRangeByTimeframe;
|
|
17
19
|
}
|
|
@@ -9,7 +9,11 @@ const cashFlowPayload_1 = require("./cashFlowPayload");
|
|
|
9
9
|
const cashFlowReducer_1 = require("./cashFlowReducer");
|
|
10
10
|
const reportIdUniqueKey = () => 'cash_flow';
|
|
11
11
|
exports.reportIdUniqueKey = reportIdUniqueKey;
|
|
12
|
-
const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(cashFlowReducer_1.fetchCashFlowForTimeframe.match),
|
|
12
|
+
const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(cashFlowReducer_1.fetchCashFlowForTimeframe.match),
|
|
13
|
+
// One stream per timeframe: a newer request for the same timeframe (e.g. a
|
|
14
|
+
// custom-date-range change, or a dated fetch right after a default one)
|
|
15
|
+
// cancels the older in-flight request so a stale response can't land last.
|
|
16
|
+
(0, operators_1.groupBy)((action) => action.payload.timeframe), (0, operators_1.mergeMap)((group$) => group$.pipe((0, operators_1.switchMap)((action) => {
|
|
13
17
|
const getTimeSeriesGroup = (timeframe) => {
|
|
14
18
|
switch (timeframe) {
|
|
15
19
|
case 'month':
|
|
@@ -24,7 +28,8 @@ const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe((0
|
|
|
24
28
|
is_full_response: action.payload.fetchFullReport,
|
|
25
29
|
time_series_groups: [getTimeSeriesGroup(action.payload.timeframe)],
|
|
26
30
|
};
|
|
27
|
-
if (action.payload.startDate != null &&
|
|
31
|
+
if (action.payload.startDate != null &&
|
|
32
|
+
action.payload.endDate != null) {
|
|
28
33
|
queryValue.custom_start_date = action.payload.startDate;
|
|
29
34
|
queryValue.custom_end_date = action.payload.endDate;
|
|
30
35
|
}
|
|
@@ -52,6 +57,7 @@ const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe((0
|
|
|
52
57
|
else {
|
|
53
58
|
return (0, rxjs_1.of)((0, cashFlowReducer_1.updateCashFlowForTimeframeFailure)(response.status, action.payload.timeframe));
|
|
54
59
|
}
|
|
55
|
-
}), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, cashFlowReducer_1.updateCashFlowForTimeframeFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Cash Flow REST API call errored out' +
|
|
56
|
-
|
|
60
|
+
}), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, cashFlowReducer_1.updateCashFlowForTimeframeFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Cash Flow REST API call errored out' +
|
|
61
|
+
JSON.stringify(error)), action.payload.timeframe))));
|
|
62
|
+
}))));
|
|
57
63
|
exports.fetchCashFlowForTimeframeEpic = fetchCashFlowForTimeframeEpic;
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.resetCashFlowNodeCollapseState = exports.updateCashFlowUIState = exports.updateCashFlowForTimeframeFailure = exports.updateCashFlowForTimeframe = exports.fetchCashFlowForTimeframe = exports.fetchCashFlow = exports.initialState = void 0;
|
|
5
5
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
6
6
|
const viewAndReportPayloadv2_1 = require("../../commonPayloadTypes/v2/viewAndReportPayloadv2");
|
|
7
|
+
const coaBalance_1 = require("../../commonStateTypes/coaBalance/coaBalance");
|
|
7
8
|
const rootActions_1 = require("../../rootActions");
|
|
8
9
|
exports.initialState = {
|
|
9
10
|
fetchState: {
|
|
@@ -58,6 +59,7 @@ const cashFlow = (0, toolkit_1.createSlice)({
|
|
|
58
59
|
fetchState: 'In-Progress',
|
|
59
60
|
error: undefined,
|
|
60
61
|
};
|
|
62
|
+
draft.customDateRangeByTimeframe = (0, coaBalance_1.withFetchedCustomDateRange)(draft.customDateRangeByTimeframe, timeframe, action.payload.startDate, action.payload.endDate);
|
|
61
63
|
},
|
|
62
64
|
},
|
|
63
65
|
updateCashFlowForTimeframe(draft, action) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CustomDateRangeByTimeframe } from '../../commonStateTypes/coaBalance/coaBalance';
|
|
1
2
|
import { ID } from '../../commonStateTypes/common';
|
|
2
3
|
import { FetchStateAndError } from '../../commonStateTypes/common';
|
|
3
4
|
import { Report } from '../../commonStateTypes/viewAndReport/viewAndReport';
|
|
@@ -8,6 +9,7 @@ export interface CashFlowState extends Report {
|
|
|
8
9
|
year: FetchStateAndError;
|
|
9
10
|
};
|
|
10
11
|
uiState: CashFlowUIState;
|
|
12
|
+
customDateRangeByTimeframe?: CustomDateRangeByTimeframe;
|
|
11
13
|
}
|
|
12
14
|
export interface CashFlowUIState {
|
|
13
15
|
nodeCollapseState: Record<ID, boolean>;
|
|
@@ -36,5 +36,13 @@ export interface FinanceStatementReport extends SelectorReport {
|
|
|
36
36
|
selectedReportAndTimeframeFetchState: FetchStateAndError;
|
|
37
37
|
selectedReportId: ReportID;
|
|
38
38
|
dataAvailable?: DataAvailable;
|
|
39
|
+
/**
|
|
40
|
+
* Custom start/end the selected report (Accounts view only) was last fetched with for the
|
|
41
|
+
* selected timeframe; undefined when that fetch used the default periods.
|
|
42
|
+
*/
|
|
43
|
+
selectedReportCustomDateRange?: {
|
|
44
|
+
endDate: string;
|
|
45
|
+
startDate: string;
|
|
46
|
+
};
|
|
39
47
|
}
|
|
40
48
|
export declare const getFinanceStatement: (state: RootState) => FinanceStatementReport;
|
|
@@ -164,6 +164,23 @@ exports.getFinanceStatement = (0, toolkit_1.createSelector)((state) => state.acc
|
|
|
164
164
|
default:
|
|
165
165
|
break;
|
|
166
166
|
}
|
|
167
|
+
let customDateRangeByTimeframe;
|
|
168
|
+
switch (financeStatementState.selectedReportId) {
|
|
169
|
+
case 'profit_and_loss':
|
|
170
|
+
customDateRangeByTimeframe =
|
|
171
|
+
profitAndLossState.pandL.customDateRangeByTimeframe;
|
|
172
|
+
break;
|
|
173
|
+
case 'balance_sheet':
|
|
174
|
+
customDateRangeByTimeframe =
|
|
175
|
+
balanceSheetState.customDateRangeByTimeframe;
|
|
176
|
+
break;
|
|
177
|
+
case 'cash_flow':
|
|
178
|
+
customDateRangeByTimeframe = cashFlowState.customDateRangeByTimeframe;
|
|
179
|
+
break;
|
|
180
|
+
default:
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
const selectedReportCustomDateRange = customDateRangeByTimeframe?.[financeStatementState.timeframe];
|
|
167
184
|
return {
|
|
168
185
|
reportId: 'finance_statement',
|
|
169
186
|
reportTitle: '',
|
|
@@ -173,6 +190,7 @@ exports.getFinanceStatement = (0, toolkit_1.createSelector)((state) => state.acc
|
|
|
173
190
|
allTimeframeTicks,
|
|
174
191
|
balancesInTimeframe,
|
|
175
192
|
selectedReportAndTimeframeFetchState,
|
|
193
|
+
selectedReportCustomDateRange,
|
|
176
194
|
displayOrder: financeStatementState.displayOrder,
|
|
177
195
|
reportFormat: financeStatementState.reportFormat,
|
|
178
196
|
firstMonthOfFY,
|
|
@@ -10,7 +10,11 @@ const reportIdUniqueKey = (forecastId) => forecastId != null
|
|
|
10
10
|
? `profit_and_loss+${forecastId}`
|
|
11
11
|
: 'profit_and_loss';
|
|
12
12
|
exports.reportIdUniqueKey = reportIdUniqueKey;
|
|
13
|
-
const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(profitAndLossReducer_1.fetchProfitAndLossForTimeframe.match),
|
|
13
|
+
const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(profitAndLossReducer_1.fetchProfitAndLossForTimeframe.match),
|
|
14
|
+
// One stream per timeframe: a newer request for the same timeframe (e.g. a
|
|
15
|
+
// custom-date-range change, or a dated fetch right after a default one)
|
|
16
|
+
// cancels the older in-flight request so a stale response can't land last.
|
|
17
|
+
(0, operators_1.groupBy)((action) => `${action.payload.forecastId ?? ''}_${action.payload.timeframe}`), (0, operators_1.mergeMap)((group$) => group$.pipe((0, operators_1.switchMap)((action) => {
|
|
14
18
|
const getTimeSeriesGroup = (timeframe) => {
|
|
15
19
|
switch (timeframe) {
|
|
16
20
|
case 'month':
|
|
@@ -29,7 +33,8 @@ const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pi
|
|
|
29
33
|
queryValue.forecast_id = action.payload.forecastId;
|
|
30
34
|
queryValue.is_forecast_vs_actual = true;
|
|
31
35
|
}
|
|
32
|
-
if (action.payload.startDate != null &&
|
|
36
|
+
if (action.payload.startDate != null &&
|
|
37
|
+
action.payload.endDate != null) {
|
|
33
38
|
queryValue.custom_start_date = action.payload.startDate;
|
|
34
39
|
queryValue.custom_end_date = action.payload.endDate;
|
|
35
40
|
}
|
|
@@ -59,5 +64,5 @@ const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pi
|
|
|
59
64
|
return (0, rxjs_1.of)((0, profitAndLossReducer_1.updateProfitAndLossForTimeframeFailure)(response.status, action.payload.forecastId, action.payload.timeframe));
|
|
60
65
|
}
|
|
61
66
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, profitAndLossReducer_1.updateProfitAndLossForTimeframeFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'P&L REST API call errored out' + JSON.stringify(error)), action.payload.forecastId, action.payload.timeframe))));
|
|
62
|
-
}));
|
|
67
|
+
}))));
|
|
63
68
|
exports.fetchProfitAndLossForTimeframeEpic = fetchProfitAndLossForTimeframeEpic;
|
|
@@ -5,6 +5,7 @@ exports.resetProfitAndLossNodeCollapseState = exports.updateProfitAndLossUIState
|
|
|
5
5
|
exports.getState = getState;
|
|
6
6
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
7
7
|
const viewAndReportPayloadv2_1 = require("../../commonPayloadTypes/v2/viewAndReportPayloadv2");
|
|
8
|
+
const coaBalance_1 = require("../../commonStateTypes/coaBalance/coaBalance");
|
|
8
9
|
const rootActions_1 = require("../../rootActions");
|
|
9
10
|
exports.initialPandLState = {
|
|
10
11
|
bookCloseDate: undefined,
|
|
@@ -76,7 +77,10 @@ const profitAndLoss = (0, toolkit_1.createSlice)({
|
|
|
76
77
|
fetchState: 'In-Progress',
|
|
77
78
|
error: undefined,
|
|
78
79
|
};
|
|
79
|
-
updateState(draft, action.payload.forecastId, {
|
|
80
|
+
updateState(draft, action.payload.forecastId, {
|
|
81
|
+
fetchState,
|
|
82
|
+
customDateRangeByTimeframe: (0, coaBalance_1.withFetchedCustomDateRange)(pAndLState.customDateRangeByTimeframe, timeframe, action.payload.startDate, action.payload.endDate),
|
|
83
|
+
});
|
|
80
84
|
},
|
|
81
85
|
},
|
|
82
86
|
updateProfitAndLossForTimeframe(draft, action) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FetchStateByTimeframe } from '../../commonStateTypes/coaBalance/coaBalance';
|
|
1
|
+
import { CustomDateRangeByTimeframe, FetchStateByTimeframe } from '../../commonStateTypes/coaBalance/coaBalance';
|
|
2
2
|
import { ID } from '../../commonStateTypes/common';
|
|
3
3
|
import { Report } from '../../commonStateTypes/viewAndReport/viewAndReport';
|
|
4
4
|
export interface ProfitAndLossUIState {
|
|
@@ -11,6 +11,7 @@ export interface ProfitAndLossUIState {
|
|
|
11
11
|
export interface ProfitAndLossState extends Report {
|
|
12
12
|
fetchState: FetchStateByTimeframe;
|
|
13
13
|
uiState: ProfitAndLossUIState;
|
|
14
|
+
customDateRangeByTimeframe?: CustomDateRangeByTimeframe;
|
|
14
15
|
forecastId?: ID;
|
|
15
16
|
}
|
|
16
17
|
export interface ProfitAndLossWithForecastState {
|
|
@@ -69,7 +69,10 @@ export declare const fetchEditRemiDetailPage: import("@reduxjs/toolkit").ActionC
|
|
|
69
69
|
reimbursementId?: ID;
|
|
70
70
|
}, "editRemiView/currencyConversionValueSuccessOrFailure">, waitForRemiDetailThenInitializeLocalStore: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[reimbursementId: string], {
|
|
71
71
|
reimbursementId: string;
|
|
72
|
-
}, "editRemiView/waitForRemiDetailThenInitializeLocalStore", never, never>,
|
|
72
|
+
}, "editRemiView/waitForRemiDetailThenInitializeLocalStore", never, never>, initializeRemiToLocalStoreFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[reimbursementId: string, error?: ZeniAPIStatus<Record<string, unknown>> | undefined], {
|
|
73
|
+
reimbursementId: string;
|
|
74
|
+
error: ZeniAPIStatus<Record<string, unknown>> | undefined;
|
|
75
|
+
}, "editRemiView/initializeRemiToLocalStoreFailure", never, never>, waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[lineId: string, reimbursementId?: string | undefined, merchantId?: string | undefined, merchantName?: string | undefined], {
|
|
73
76
|
lineId: string;
|
|
74
77
|
reimbursementId: string | undefined;
|
|
75
78
|
merchantId: string | undefined;
|
|
@@ -77,7 +80,9 @@ export declare const fetchEditRemiDetailPage: import("@reduxjs/toolkit").ActionC
|
|
|
77
80
|
}, "editRemiView/waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant", never, never>, updateAddRemiAutoFields: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
78
81
|
addRemiAutoFields: Record<ID, AutoFields>;
|
|
79
82
|
reimbursementId?: ID;
|
|
80
|
-
}, "editRemiView/updateAddRemiAutoFields">, indicateReadyToInitializeRemiLocalStore: import("@reduxjs/toolkit").
|
|
83
|
+
}, "editRemiView/updateAddRemiAutoFields">, indicateReadyToInitializeRemiLocalStore: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[reimbursementId: string], {
|
|
84
|
+
reimbursementId: string;
|
|
85
|
+
}, "editRemiView/indicateReadyToInitializeRemiLocalStore", never, never>, updateUploadFetchState: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
81
86
|
fetchState: FetchState;
|
|
82
87
|
reimbursementId?: ID;
|
|
83
88
|
}, "editRemiView/updateUploadFetchState">, updateRecommendationInMerchant: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.clearAddRemiAutoFields = exports.clearTentativeMerchantName = exports.updateTentativeMerchantNames = exports.updateRecommendationInMerchant = exports.updateUploadFetchState = exports.indicateReadyToInitializeRemiLocalStore = exports.updateAddRemiAutoFields = exports.waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant = exports.waitForRemiDetailThenInitializeLocalStore = exports.currencyConversionValueSuccessOrFailure = exports.updateHomeCurrencyConversion = exports.updateReimbursementType = exports.fetchCurrencyConversionValue = exports.parseReceiptsToRemi = exports.saveRemiSuccessOrFailure = exports.saveRemiDetail = exports.removeFileFromRemiUpdatesInLocalStore = exports.discardRemiUpdatesInLocalStore = exports.updatesPaymentToInLocalStore = exports.saveRemiUpdatesToLocalStore = exports.fetchRecommendationsAndUpdateMerchantRecommendations = exports.initializeRemiToLocalStore = exports.fetchRemiAndInitializeLocalStore = exports.fetchEditRemiDetailPage = exports.initialState = void 0;
|
|
4
|
+
exports.clearAddRemiAutoFields = exports.clearTentativeMerchantName = exports.updateTentativeMerchantNames = exports.updateRecommendationInMerchant = exports.updateUploadFetchState = exports.indicateReadyToInitializeRemiLocalStore = exports.updateAddRemiAutoFields = exports.waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant = exports.initializeRemiToLocalStoreFailure = exports.waitForRemiDetailThenInitializeLocalStore = exports.currencyConversionValueSuccessOrFailure = exports.updateHomeCurrencyConversion = exports.updateReimbursementType = exports.fetchCurrencyConversionValue = exports.parseReceiptsToRemi = exports.saveRemiSuccessOrFailure = exports.saveRemiDetail = exports.removeFileFromRemiUpdatesInLocalStore = exports.discardRemiUpdatesInLocalStore = exports.updatesPaymentToInLocalStore = exports.saveRemiUpdatesToLocalStore = exports.fetchRecommendationsAndUpdateMerchantRecommendations = exports.initializeRemiToLocalStore = exports.fetchRemiAndInitializeLocalStore = exports.fetchEditRemiDetailPage = exports.initialState = void 0;
|
|
5
5
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
6
6
|
const amount_1 = require("../../../../commonStateTypes/amount");
|
|
7
7
|
const rootActions_1 = require("../../../../rootActions");
|
|
@@ -34,8 +34,13 @@ const editRemiView = (0, toolkit_1.createSlice)({
|
|
|
34
34
|
};
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
|
-
indicateReadyToInitializeRemiLocalStore
|
|
38
|
-
|
|
37
|
+
indicateReadyToInitializeRemiLocalStore: {
|
|
38
|
+
reducer() {
|
|
39
|
+
// do nothing
|
|
40
|
+
},
|
|
41
|
+
prepare(reimbursementId) {
|
|
42
|
+
return { payload: { reimbursementId } };
|
|
43
|
+
},
|
|
39
44
|
},
|
|
40
45
|
fetchRecommendationsAndUpdateMerchantRecommendations: {
|
|
41
46
|
reducer() {
|
|
@@ -141,6 +146,21 @@ const editRemiView = (0, toolkit_1.createSlice)({
|
|
|
141
146
|
return { payload: { reimbursementId } };
|
|
142
147
|
},
|
|
143
148
|
},
|
|
149
|
+
initializeRemiToLocalStoreFailure: {
|
|
150
|
+
reducer(draft, action) {
|
|
151
|
+
const { reimbursementId, error } = action.payload;
|
|
152
|
+
draft.editRemiStateById[reimbursementId] = {
|
|
153
|
+
...draft.editRemiStateById[reimbursementId],
|
|
154
|
+
fetchStatus: {
|
|
155
|
+
fetchState: 'Error',
|
|
156
|
+
error,
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
},
|
|
160
|
+
prepare(reimbursementId, error) {
|
|
161
|
+
return { payload: { reimbursementId, error } };
|
|
162
|
+
},
|
|
163
|
+
},
|
|
144
164
|
saveRemiUpdatesToLocalStore(draft, action) {
|
|
145
165
|
if (action.payload.reimbursementId != null) {
|
|
146
166
|
const reimbursementId = action.payload.reimbursementId;
|
|
@@ -391,7 +411,7 @@ const editRemiView = (0, toolkit_1.createSlice)({
|
|
|
391
411
|
});
|
|
392
412
|
},
|
|
393
413
|
});
|
|
394
|
-
_a = editRemiView.actions, exports.fetchEditRemiDetailPage = _a.fetchEditRemiDetailPage, exports.fetchRemiAndInitializeLocalStore = _a.fetchRemiAndInitializeLocalStore, exports.initializeRemiToLocalStore = _a.initializeRemiToLocalStore, exports.fetchRecommendationsAndUpdateMerchantRecommendations = _a.fetchRecommendationsAndUpdateMerchantRecommendations, exports.saveRemiUpdatesToLocalStore = _a.saveRemiUpdatesToLocalStore, exports.updatesPaymentToInLocalStore = _a.updatesPaymentToInLocalStore, exports.discardRemiUpdatesInLocalStore = _a.discardRemiUpdatesInLocalStore, exports.removeFileFromRemiUpdatesInLocalStore = _a.removeFileFromRemiUpdatesInLocalStore, exports.saveRemiDetail = _a.saveRemiDetail, exports.saveRemiSuccessOrFailure = _a.saveRemiSuccessOrFailure, exports.parseReceiptsToRemi = _a.parseReceiptsToRemi, exports.fetchCurrencyConversionValue = _a.fetchCurrencyConversionValue, exports.updateReimbursementType = _a.updateReimbursementType, exports.updateHomeCurrencyConversion = _a.updateHomeCurrencyConversion, exports.currencyConversionValueSuccessOrFailure = _a.currencyConversionValueSuccessOrFailure, exports.waitForRemiDetailThenInitializeLocalStore = _a.waitForRemiDetailThenInitializeLocalStore, exports.waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant = _a.waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant, exports.updateAddRemiAutoFields = _a.updateAddRemiAutoFields, exports.indicateReadyToInitializeRemiLocalStore = _a.indicateReadyToInitializeRemiLocalStore, exports.updateUploadFetchState = _a.updateUploadFetchState, exports.updateRecommendationInMerchant = _a.updateRecommendationInMerchant, exports.updateTentativeMerchantNames = _a.updateTentativeMerchantNames, exports.clearTentativeMerchantName = _a.clearTentativeMerchantName, exports.clearAddRemiAutoFields = _a.clearAddRemiAutoFields;
|
|
414
|
+
_a = editRemiView.actions, exports.fetchEditRemiDetailPage = _a.fetchEditRemiDetailPage, exports.fetchRemiAndInitializeLocalStore = _a.fetchRemiAndInitializeLocalStore, exports.initializeRemiToLocalStore = _a.initializeRemiToLocalStore, exports.fetchRecommendationsAndUpdateMerchantRecommendations = _a.fetchRecommendationsAndUpdateMerchantRecommendations, exports.saveRemiUpdatesToLocalStore = _a.saveRemiUpdatesToLocalStore, exports.updatesPaymentToInLocalStore = _a.updatesPaymentToInLocalStore, exports.discardRemiUpdatesInLocalStore = _a.discardRemiUpdatesInLocalStore, exports.removeFileFromRemiUpdatesInLocalStore = _a.removeFileFromRemiUpdatesInLocalStore, exports.saveRemiDetail = _a.saveRemiDetail, exports.saveRemiSuccessOrFailure = _a.saveRemiSuccessOrFailure, exports.parseReceiptsToRemi = _a.parseReceiptsToRemi, exports.fetchCurrencyConversionValue = _a.fetchCurrencyConversionValue, exports.updateReimbursementType = _a.updateReimbursementType, exports.updateHomeCurrencyConversion = _a.updateHomeCurrencyConversion, exports.currencyConversionValueSuccessOrFailure = _a.currencyConversionValueSuccessOrFailure, exports.waitForRemiDetailThenInitializeLocalStore = _a.waitForRemiDetailThenInitializeLocalStore, exports.initializeRemiToLocalStoreFailure = _a.initializeRemiToLocalStoreFailure, exports.waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant = _a.waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant, exports.updateAddRemiAutoFields = _a.updateAddRemiAutoFields, exports.indicateReadyToInitializeRemiLocalStore = _a.indicateReadyToInitializeRemiLocalStore, exports.updateUploadFetchState = _a.updateUploadFetchState, exports.updateRecommendationInMerchant = _a.updateRecommendationInMerchant, exports.updateTentativeMerchantNames = _a.updateTentativeMerchantNames, exports.clearTentativeMerchantName = _a.clearTentativeMerchantName, exports.clearAddRemiAutoFields = _a.clearAddRemiAutoFields;
|
|
395
415
|
exports.default = editRemiView.reducer;
|
|
396
416
|
const doUpdateRecommendationForEntity = (draft, lineId, recommendations, shouldAutofill, reimbursementId, reimbursementStageCode) => {
|
|
397
417
|
if (reimbursementId != null) {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { clearAll } from '../../../../../rootActions';
|
|
2
4
|
import { RootState } from '../../../../../rootStateTypes';
|
|
3
|
-
import { fetchRemiDetail, updateRemiDetail } from '../../remiDetailView/remiDetailViewReducer';
|
|
4
|
-
import { fetchRemiAndInitializeLocalStore, initializeRemiToLocalStore, waitForRemiDetailThenInitializeLocalStore } from '../editRemiViewReducer';
|
|
5
|
-
export type ActionType = ReturnType<typeof waitForRemiDetailThenInitializeLocalStore> | ReturnType<typeof fetchRemiDetail> | ReturnType<typeof updateRemiDetail> | ReturnType<typeof initializeRemiToLocalStore> | ReturnType<typeof fetchRemiAndInitializeLocalStore>;
|
|
6
|
-
export declare const fetchRemiAndInitializeLocalStoreEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>) =>
|
|
5
|
+
import { fetchRemiDetail, updateRemiDetail, updateRemiDetailFetchState } from '../../remiDetailView/remiDetailViewReducer';
|
|
6
|
+
import { fetchRemiAndInitializeLocalStore, indicateReadyToInitializeRemiLocalStore, initializeRemiToLocalStore, initializeRemiToLocalStoreFailure, waitForRemiDetailThenInitializeLocalStore } from '../editRemiViewReducer';
|
|
7
|
+
export type ActionType = ReturnType<typeof waitForRemiDetailThenInitializeLocalStore> | ReturnType<typeof fetchRemiDetail> | ReturnType<typeof updateRemiDetail> | ReturnType<typeof updateRemiDetailFetchState> | ReturnType<typeof initializeRemiToLocalStore> | ReturnType<typeof fetchRemiAndInitializeLocalStore> | ReturnType<typeof indicateReadyToInitializeRemiLocalStore> | ReturnType<typeof initializeRemiToLocalStoreFailure> | ReturnType<typeof clearAll>;
|
|
8
|
+
export declare const fetchRemiAndInitializeLocalStoreEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>) => Observable<ActionType>;
|
|
9
|
+
export declare const waitForRemiDetailThenInitializeLocalStoreEpic: (actions$: ActionsObservable<ActionType>) => Observable<ActionType>;
|
|
@@ -3,10 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.fetchRemiAndInitializeLocalStoreEpic = void 0;
|
|
6
|
+
exports.waitForRemiDetailThenInitializeLocalStoreEpic = exports.fetchRemiAndInitializeLocalStoreEpic = void 0;
|
|
7
7
|
const get_1 = __importDefault(require("lodash/get"));
|
|
8
8
|
const rxjs_1 = require("rxjs");
|
|
9
9
|
const operators_1 = require("rxjs/operators");
|
|
10
|
+
const rootActions_1 = require("../../../../../rootActions");
|
|
10
11
|
const remiDetailViewReducer_1 = require("../../remiDetailView/remiDetailViewReducer");
|
|
11
12
|
const editRemiViewReducer_1 = require("../editRemiViewReducer");
|
|
12
13
|
const fetchRemiAndInitializeLocalStoreEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)(editRemiViewReducer_1.fetchRemiAndInitializeLocalStore.match), (0, operators_1.mergeMap)((action) => {
|
|
@@ -42,3 +43,16 @@ const fetchRemiAndInitializeLocalStoreEpic = (actions$, state$) => actions$.pipe
|
|
|
42
43
|
return (0, rxjs_1.from)(remiDetailActions);
|
|
43
44
|
}));
|
|
44
45
|
exports.fetchRemiAndInitializeLocalStoreEpic = fetchRemiAndInitializeLocalStoreEpic;
|
|
46
|
+
const waitForRemiDetailThenInitializeLocalStoreEpic = (actions$) => actions$.pipe((0, operators_1.filter)(editRemiViewReducer_1.waitForRemiDetailThenInitializeLocalStore.match), (0, operators_1.mergeMap)((action) => {
|
|
47
|
+
const { reimbursementId } = action.payload;
|
|
48
|
+
const ready$ = actions$.pipe((0, operators_1.filter)(editRemiViewReducer_1.indicateReadyToInitializeRemiLocalStore.match), (0, operators_1.filter)((readyAction) => readyAction.payload.reimbursementId === reimbursementId), (0, operators_1.take)(1), (0, operators_1.map)(() => (0, editRemiViewReducer_1.initializeRemiToLocalStore)(reimbursementId)));
|
|
49
|
+
const failed$ = actions$.pipe((0, operators_1.filter)(remiDetailViewReducer_1.updateRemiDetailFetchState.match), (0, operators_1.filter)((fetchStateAction) => fetchStateAction.payload.reimbursementId === reimbursementId &&
|
|
50
|
+
fetchStateAction.payload.fetchState === 'Error'), (0, operators_1.map)((fetchStateAction) => (0, editRemiViewReducer_1.initializeRemiToLocalStoreFailure)(reimbursementId, fetchStateAction.payload.error)));
|
|
51
|
+
const supersededOrCleared$ = actions$.pipe((0, operators_1.filter)((nextAction) => rootActions_1.clearAll.match(nextAction) ||
|
|
52
|
+
(editRemiViewReducer_1.waitForRemiDetailThenInitializeLocalStore.match(nextAction) &&
|
|
53
|
+
nextAction.payload.reimbursementId === reimbursementId)));
|
|
54
|
+
// An Error does not end the wait: a newer request for the same id may still succeed.
|
|
55
|
+
// After an Error, supersededOrCleared$ is what ends it.
|
|
56
|
+
return (0, rxjs_1.merge)(ready$, failed$).pipe((0, operators_1.takeWhile)((resultAction) => !editRemiViewReducer_1.initializeRemiToLocalStore.match(resultAction), true), (0, operators_1.takeUntil)(supersededOrCleared$));
|
|
57
|
+
}));
|
|
58
|
+
exports.waitForRemiDetailThenInitializeLocalStoreEpic = waitForRemiDetailThenInitializeLocalStoreEpic;
|
|
@@ -81,7 +81,7 @@ const fetchRemiDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, ope
|
|
|
81
81
|
}));
|
|
82
82
|
}
|
|
83
83
|
});
|
|
84
|
-
actions.push((0, editRemiViewReducer_1.indicateReadyToInitializeRemiLocalStore)());
|
|
84
|
+
actions.push((0, editRemiViewReducer_1.indicateReadyToInitializeRemiLocalStore)(reimbursementId));
|
|
85
85
|
if (response.data.transaction?.lines != null &&
|
|
86
86
|
response.data.transaction.lines.length > 0) {
|
|
87
87
|
actions.push((0, remiDetailViewReducer_1.fetchDuplicateReimbursement)(response.data.transaction.created_by_user_id, false, response.data.transaction.transaction_id));
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { TimePeriod } from '../../commonStateTypes/timePeriod';
|
|
2
|
+
import { ZeniDate } from '../../zeniDayJS';
|
|
3
|
+
/**
|
|
4
|
+
* Transaction lists are fetched and cached in month buckets: `splitPeriod`
|
|
5
|
+
* snaps the first bucket back to the 1st of the month, while the last bucket
|
|
6
|
+
* is fetched with the real end date. So a period that starts mid-month (e.g. a
|
|
7
|
+
* drill-down from the custom-date-range column "Jun 17-30 2026") pulls in the
|
|
8
|
+
* days before its start. Drop those so the list reconciles to the clicked
|
|
9
|
+
* figure. Periods starting on the 1st (every pre-existing caller) are returned
|
|
10
|
+
* untouched. Compares calendar days as `YYYY-MM-DD` strings so the viewer's
|
|
11
|
+
* timezone can't shift the boundary.
|
|
12
|
+
*/
|
|
13
|
+
export declare const filterTransactionsByTimePeriod: <T extends {
|
|
14
|
+
date: ZeniDate;
|
|
15
|
+
}>(transactions: T[], period: TimePeriod) => T[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.filterTransactionsByTimePeriod = void 0;
|
|
4
|
+
const timePeriod_1 = require("../../commonStateTypes/timePeriod");
|
|
5
|
+
/**
|
|
6
|
+
* Transaction lists are fetched and cached in month buckets: `splitPeriod`
|
|
7
|
+
* snaps the first bucket back to the 1st of the month, while the last bucket
|
|
8
|
+
* is fetched with the real end date. So a period that starts mid-month (e.g. a
|
|
9
|
+
* drill-down from the custom-date-range column "Jun 17-30 2026") pulls in the
|
|
10
|
+
* days before its start. Drop those so the list reconciles to the clicked
|
|
11
|
+
* figure. Periods starting on the 1st (every pre-existing caller) are returned
|
|
12
|
+
* untouched. Compares calendar days as `YYYY-MM-DD` strings so the viewer's
|
|
13
|
+
* timezone can't shift the boundary.
|
|
14
|
+
*/
|
|
15
|
+
const filterTransactionsByTimePeriod = (transactions, period) => {
|
|
16
|
+
if (period.start.day === 1) {
|
|
17
|
+
return transactions;
|
|
18
|
+
}
|
|
19
|
+
const start = (0, timePeriod_1.toString)(period.start);
|
|
20
|
+
return transactions.filter((transaction) => transaction.date.format(timePeriod_1.DEFAULT_DATE_FORMAT) >= start);
|
|
21
|
+
};
|
|
22
|
+
exports.filterTransactionsByTimePeriod = filterTransactionsByTimePeriod;
|
|
@@ -8,6 +8,7 @@ const flatMap_1 = __importDefault(require("lodash/flatMap"));
|
|
|
8
8
|
const get_1 = __importDefault(require("lodash/get"));
|
|
9
9
|
const orderBy_1 = __importDefault(require("lodash/orderBy"));
|
|
10
10
|
const transactionSelector_1 = require("../../entity/transaction/transactionSelector");
|
|
11
|
+
const filterTransactionsByTimePeriod_1 = require("./filterTransactionsByTimePeriod");
|
|
11
12
|
const parallelFetchAccountTransactionListEpic_1 = require("./parallelFetchAccountTransactionListEpic");
|
|
12
13
|
const reduceTransactionListFetchState_1 = require("./reduceTransactionListFetchState");
|
|
13
14
|
const transactionListState_1 = require("./transactionListState");
|
|
@@ -35,7 +36,7 @@ const getTransactionListByAccount = (transactionState, transactionListState, acc
|
|
|
35
36
|
}
|
|
36
37
|
return value != null;
|
|
37
38
|
});
|
|
38
|
-
transactions = (0, orderBy_1.default)(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
|
|
39
|
+
transactions = (0, orderBy_1.default)((0, filterTransactionsByTimePeriod_1.filterTransactionsByTimePeriod)(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
|
|
39
40
|
}
|
|
40
41
|
const key = (0, transactionListState_1.getAcKey)(accountId, accountType);
|
|
41
42
|
const uiState = (0, get_1.default)(transactionListState.byAccount.transactionListUIStateByAccountKey, key, {});
|
|
@@ -8,6 +8,7 @@ const flatMap_1 = __importDefault(require("lodash/flatMap"));
|
|
|
8
8
|
const get_1 = __importDefault(require("lodash/get"));
|
|
9
9
|
const orderBy_1 = __importDefault(require("lodash/orderBy"));
|
|
10
10
|
const transactionSelector_1 = require("../../entity/transaction/transactionSelector");
|
|
11
|
+
const filterTransactionsByTimePeriod_1 = require("./filterTransactionsByTimePeriod");
|
|
11
12
|
const parallelFetchAccountTransactionListEpic_1 = require("./parallelFetchAccountTransactionListEpic");
|
|
12
13
|
const reduceTransactionListFetchState_1 = require("./reduceTransactionListFetchState");
|
|
13
14
|
const transactionListState_1 = require("./transactionListState");
|
|
@@ -32,7 +33,7 @@ const getTransactionsListByCategoryType = (transactionState, transactionListStat
|
|
|
32
33
|
}
|
|
33
34
|
return value != null;
|
|
34
35
|
});
|
|
35
|
-
transactions = (0, orderBy_1.default)(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
|
|
36
|
+
transactions = (0, orderBy_1.default)((0, filterTransactionsByTimePeriod_1.filterTransactionsByTimePeriod)(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
|
|
36
37
|
}
|
|
37
38
|
const uiState = transactionListState.byType[transactionCategoryType].transactionListUIState;
|
|
38
39
|
return {
|
|
@@ -8,6 +8,7 @@ const flatMap_1 = __importDefault(require("lodash/flatMap"));
|
|
|
8
8
|
const get_1 = __importDefault(require("lodash/get"));
|
|
9
9
|
const orderBy_1 = __importDefault(require("lodash/orderBy"));
|
|
10
10
|
const transactionSelector_1 = require("../../entity/transaction/transactionSelector");
|
|
11
|
+
const filterTransactionsByTimePeriod_1 = require("./filterTransactionsByTimePeriod");
|
|
11
12
|
const parallelFetchAccountTransactionListEpic_1 = require("./parallelFetchAccountTransactionListEpic");
|
|
12
13
|
const reduceTransactionListFetchState_1 = require("./reduceTransactionListFetchState");
|
|
13
14
|
const transactionListState_1 = require("./transactionListState");
|
|
@@ -35,7 +36,7 @@ const getTransactionListByClass = (transactionState, transactionListState, accou
|
|
|
35
36
|
}
|
|
36
37
|
return value != null;
|
|
37
38
|
});
|
|
38
|
-
transactions = (0, orderBy_1.default)(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
|
|
39
|
+
transactions = (0, orderBy_1.default)((0, filterTransactionsByTimePeriod_1.filterTransactionsByTimePeriod)(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
|
|
39
40
|
}
|
|
40
41
|
const key = (0, transactionListState_1.getClassAcKey)(accountId, accountType, classId);
|
|
41
42
|
const uiState = (0, get_1.default)(transactionListState.byClass.transactionListUIStateByClassKey, key, {});
|
|
@@ -8,6 +8,7 @@ const flatMap_1 = __importDefault(require("lodash/flatMap"));
|
|
|
8
8
|
const get_1 = __importDefault(require("lodash/get"));
|
|
9
9
|
const orderBy_1 = __importDefault(require("lodash/orderBy"));
|
|
10
10
|
const transactionSelector_1 = require("../../entity/transaction/transactionSelector");
|
|
11
|
+
const filterTransactionsByTimePeriod_1 = require("./filterTransactionsByTimePeriod");
|
|
11
12
|
const parallelFetchAccountTransactionListEpic_1 = require("./parallelFetchAccountTransactionListEpic");
|
|
12
13
|
const reduceTransactionListFetchState_1 = require("./reduceTransactionListFetchState");
|
|
13
14
|
const transactionListState_1 = require("./transactionListState");
|
|
@@ -35,7 +36,7 @@ const getTransactionListByProject = (transactionState, transactionListState, acc
|
|
|
35
36
|
}
|
|
36
37
|
return value != null;
|
|
37
38
|
});
|
|
38
|
-
transactions = (0, orderBy_1.default)(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
|
|
39
|
+
transactions = (0, orderBy_1.default)((0, filterTransactionsByTimePeriod_1.filterTransactionsByTimePeriod)(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
|
|
39
40
|
}
|
|
40
41
|
const key = (0, transactionListState_1.getProjectAcKey)(accountId, accountType, projectId);
|
|
41
42
|
const uiState = (0, get_1.default)(transactionListState.byProject.transactionListUIStateByProjectKey, key, {});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeniai/client-epic-state",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.20",
|
|
4
4
|
"description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/esm/index.js",
|