@zeniai/client-epic-state 5.3.4 → 5.3.6
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/entity/customerIncome/customerIncomeTrend.d.ts +18 -2
- package/lib/entity/customerIncome/customerIncomeTrend.js +65 -5
- package/lib/entity/insights/insightSummary.d.ts +3 -0
- package/lib/entity/insights/insightSummaryPayload.js +2 -0
- package/lib/entity/invoicing/invoice/invoicePayload.d.ts +1 -0
- package/lib/entity/invoicing/invoice/invoicePayload.js +3 -0
- package/lib/entity/invoicing/invoice/invoiceState.d.ts +2 -0
- package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
- package/lib/entity/snackbar/snackbarTypes.js +1 -0
- package/lib/entity/vendorExpense/vendorSpendTrendFilterTabType.d.ts +2 -2
- package/lib/epic.d.ts +4 -1
- package/lib/epic.js +6 -0
- package/lib/esm/entity/customerIncome/customerIncomeTrend.js +63 -4
- package/lib/esm/entity/insights/insightSummaryPayload.js +2 -0
- package/lib/esm/entity/invoicing/invoice/invoicePayload.js +3 -0
- package/lib/esm/entity/snackbar/snackbarTypes.js +1 -0
- package/lib/esm/epic.js +6 -0
- package/lib/esm/index.js +3 -0
- package/lib/esm/reducer.js +3 -0
- package/lib/esm/view/customerSummaryView/customerSummaryViewPayload.js +1 -0
- package/lib/esm/view/customerSummaryView/customerSummaryViewReducer.js +197 -0
- package/lib/esm/view/customerSummaryView/customerSummaryViewSelector.js +35 -0
- package/lib/esm/view/customerSummaryView/customerSummaryViewState.js +10 -0
- package/lib/esm/view/customerSummaryView/epic/fetchCustomerSummaryDetailEpic.js +30 -0
- package/lib/esm/view/customerSummaryView/epic/fetchCustomerSummaryListEpic.js +27 -0
- package/lib/esm/view/customerSummaryView/epic/saveCustomerSummaryDetailEpic.js +44 -0
- package/lib/esm/view/expenseAutomationView/epics/accountRecon/fetchReconciliationViewEpic.js +2 -1
- package/lib/esm/view/transactionDetail/createTransaction/createTransactionPayload.js +0 -1
- package/lib/esm/view/trend/fetchIncomeTrendEpic.js +29 -6
- package/lib/esm/view/trend/trendReducer.js +4 -2
- package/lib/index.d.ts +6 -0
- package/lib/index.js +21 -1
- package/lib/reducer.d.ts +1 -0
- package/lib/reducer.js +3 -0
- package/lib/rootStateTypes.d.ts +2 -0
- package/lib/view/commonVendorView/vendorsTabVendorView/vendorsTabVendorViewReducer.d.ts +2 -2
- package/lib/view/customerSummaryView/customerSummaryViewPayload.d.ts +38 -0
- package/lib/view/customerSummaryView/customerSummaryViewPayload.js +2 -0
- package/lib/view/customerSummaryView/customerSummaryViewReducer.d.ts +32 -0
- package/lib/view/customerSummaryView/customerSummaryViewReducer.js +202 -0
- package/lib/view/customerSummaryView/customerSummaryViewSelector.d.ts +20 -0
- package/lib/view/customerSummaryView/customerSummaryViewSelector.js +43 -0
- package/lib/view/customerSummaryView/customerSummaryViewState.d.ts +63 -0
- package/lib/view/customerSummaryView/customerSummaryViewState.js +13 -0
- package/lib/view/customerSummaryView/epic/fetchCustomerSummaryDetailEpic.d.ts +9 -0
- package/lib/view/customerSummaryView/epic/fetchCustomerSummaryDetailEpic.js +34 -0
- package/lib/view/customerSummaryView/epic/fetchCustomerSummaryListEpic.d.ts +7 -0
- package/lib/view/customerSummaryView/epic/fetchCustomerSummaryListEpic.js +31 -0
- package/lib/view/customerSummaryView/epic/saveCustomerSummaryDetailEpic.d.ts +8 -0
- package/lib/view/customerSummaryView/epic/saveCustomerSummaryDetailEpic.js +48 -0
- package/lib/view/expenseAutomationView/epics/accountRecon/fetchReconciliationViewEpic.js +2 -1
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
- package/lib/view/transactionDetail/createTransaction/createTransactionPayload.d.ts +2 -4
- package/lib/view/transactionDetail/createTransaction/createTransactionPayload.js +0 -1
- package/lib/view/transactionDetail/createTransaction/createTransactionState.d.ts +0 -2
- package/lib/view/trend/fetchIncomeTrendEpic.d.ts +1 -1
- package/lib/view/trend/fetchIncomeTrendEpic.js +28 -5
- package/lib/view/trend/trendReducer.d.ts +8 -1
- package/lib/view/trend/trendReducer.js +4 -2
- package/package.json +1 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ZeniAPIResponse } from '../../responsePayload';
|
|
2
|
+
export interface CustomerSummaryRevenuePayload {
|
|
3
|
+
last_3_months_revenue?: number;
|
|
4
|
+
last_6_months_revenue?: number;
|
|
5
|
+
last_12_months_revenue?: number;
|
|
6
|
+
last_30_days_revenue?: number;
|
|
7
|
+
last_90_days_revenue?: number;
|
|
8
|
+
last_month_revenue?: number;
|
|
9
|
+
previous_year_revenue?: number;
|
|
10
|
+
year_to_date_revenue?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface CustomerSummaryPayload extends CustomerSummaryRevenuePayload {
|
|
13
|
+
customer_id: string;
|
|
14
|
+
account?: {
|
|
15
|
+
account_id: string;
|
|
16
|
+
account_name?: string;
|
|
17
|
+
} | null;
|
|
18
|
+
accounting_class?: {
|
|
19
|
+
accounting_class_id: string;
|
|
20
|
+
accounting_class_name?: string;
|
|
21
|
+
} | null;
|
|
22
|
+
balance?: number;
|
|
23
|
+
currency_code?: string | null;
|
|
24
|
+
currency_symbol?: string | null;
|
|
25
|
+
customer_name?: string;
|
|
26
|
+
qbo_id?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface CustomerSummaryListPayload {
|
|
29
|
+
customers: CustomerSummaryPayload[];
|
|
30
|
+
query?: {
|
|
31
|
+
page_token?: string | null;
|
|
32
|
+
};
|
|
33
|
+
total_count?: number;
|
|
34
|
+
}
|
|
35
|
+
export type CustomerSummaryListResponse = ZeniAPIResponse<CustomerSummaryListPayload>;
|
|
36
|
+
export type CustomerSummaryDetailResponse = ZeniAPIResponse<{
|
|
37
|
+
customers: CustomerSummaryPayload[];
|
|
38
|
+
}>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { FetchState } from '../../commonStateTypes/common';
|
|
2
|
+
import { PageToken } from '../../commonStateTypes/viewAndReport/viewAndReport';
|
|
3
|
+
import { ZeniAPIStatus } from '../../responsePayload';
|
|
4
|
+
import { CustomerSummaryListResponse, CustomerSummaryPayload } from './customerSummaryViewPayload';
|
|
5
|
+
import { CustomerAllTransactionsTabData, CustomerDetailTabType, CustomerSummary, CustomerSummaryDetailChanges, CustomerSummarySortKey, CustomerSummaryViewState } from './customerSummaryViewState';
|
|
6
|
+
export declare const initialState: CustomerSummaryViewState;
|
|
7
|
+
export declare const toCustomerSummary: (payload: CustomerSummaryPayload) => CustomerSummary;
|
|
8
|
+
export declare const fetchCustomerSummaryList: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[keepExistingListItems: boolean, searchString?: any, pageToken?: PageToken | undefined], {
|
|
9
|
+
keepExistingListItems: boolean;
|
|
10
|
+
pageToken: PageToken;
|
|
11
|
+
searchString: any;
|
|
12
|
+
}, "customerSummaryView/fetchCustomerSummaryList", never, never>, updateCustomerSummaryList: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[response: CustomerSummaryListResponse, keepExistingListItems: boolean], {
|
|
13
|
+
keepExistingListItems: boolean;
|
|
14
|
+
response: CustomerSummaryListResponse;
|
|
15
|
+
}, "customerSummaryView/updateCustomerSummaryList", never, never>, updateCustomerSummaryListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "customerSummaryView/updateCustomerSummaryListFailure">, updateCustomerSummarySortUiState: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[sortKey: CustomerSummarySortKey, sortOrder: "ascending" | "descending"], {
|
|
16
|
+
sortKey: CustomerSummarySortKey;
|
|
17
|
+
sortOrder: "ascending" | "descending";
|
|
18
|
+
}, "customerSummaryView/updateCustomerSummarySortUiState", never, never>, updateCustomerSummaryRevenueSelection: import("@reduxjs/toolkit").ActionCreatorWithPayload<"last_90_days_revenue" | "last_30_days_revenue" | "year_to_date_revenue" | "last_month_revenue" | "last_3_months_revenue" | "last_6_months_revenue" | "last_12_months_revenue" | "previous_year_revenue", "customerSummaryView/updateCustomerSummaryRevenueSelection">, updateCustomerSummaryScrollYOffset: import("@reduxjs/toolkit").ActionCreatorWithPayload<number, "customerSummaryView/updateCustomerSummaryScrollYOffset">, fetchCustomerSummaryDetail: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "customerSummaryView/fetchCustomerSummaryDetail">, updateCustomerSummaryDetail: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[customerId: string, customer: CustomerSummaryPayload], {
|
|
19
|
+
customer: CustomerSummaryPayload;
|
|
20
|
+
customerId: string;
|
|
21
|
+
}, "customerSummaryView/updateCustomerSummaryDetail", never, never>, updateCustomerSummaryDetailFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[customerId: string, status: ZeniAPIStatus<Record<string, unknown>>], {
|
|
22
|
+
customerId: string;
|
|
23
|
+
status: ZeniAPIStatus<Record<string, unknown>>;
|
|
24
|
+
}, "customerSummaryView/updateCustomerSummaryDetailFailure", never, never>, saveCustomerSummaryDetail: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[customerId: string, changes: CustomerSummaryDetailChanges], {
|
|
25
|
+
changes: CustomerSummaryDetailChanges;
|
|
26
|
+
customerId: string;
|
|
27
|
+
}, "customerSummaryView/saveCustomerSummaryDetail", never, never>, updateCustomerSummarySaveState: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[customerId: string, saveState: FetchState], {
|
|
28
|
+
customerId: string;
|
|
29
|
+
saveState: FetchState;
|
|
30
|
+
}, "customerSummaryView/updateCustomerSummarySaveState", never, never>, updateCustomerDetailSelectedTab: import("@reduxjs/toolkit").ActionCreatorWithPayload<CustomerDetailTabType, "customerSummaryView/updateCustomerDetailSelectedTab">, updateCustomerAllTransactionsTabData: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<CustomerAllTransactionsTabData | undefined, "customerSummaryView/updateCustomerAllTransactionsTabData">, updateCustomerTrendFilter: import("@reduxjs/toolkit").ActionCreatorWithPayload<"last_30_days" | "variance" | "last_90_days" | "YTD_spend" | "last_month" | "last_3_months" | "last_6_months" | "last_12_months" | "last_year", "customerSummaryView/updateCustomerTrendFilter">, resetCustomerSummaryDetailUiState: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "customerSummaryView/resetCustomerSummaryDetailUiState">;
|
|
31
|
+
declare const _default: import("redux").Reducer<CustomerSummaryViewState>;
|
|
32
|
+
export default _default;
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.resetCustomerSummaryDetailUiState = exports.updateCustomerTrendFilter = exports.updateCustomerAllTransactionsTabData = exports.updateCustomerDetailSelectedTab = exports.updateCustomerSummarySaveState = exports.saveCustomerSummaryDetail = exports.updateCustomerSummaryDetailFailure = exports.updateCustomerSummaryDetail = exports.fetchCustomerSummaryDetail = exports.updateCustomerSummaryScrollYOffset = exports.updateCustomerSummaryRevenueSelection = exports.updateCustomerSummarySortUiState = exports.updateCustomerSummaryListFailure = exports.updateCustomerSummaryList = exports.fetchCustomerSummaryList = exports.toCustomerSummary = exports.initialState = void 0;
|
|
5
|
+
const toolkit_1 = require("@reduxjs/toolkit");
|
|
6
|
+
const rootActions_1 = require("../../rootActions");
|
|
7
|
+
const customerSummaryViewState_1 = require("./customerSummaryViewState");
|
|
8
|
+
exports.initialState = {
|
|
9
|
+
customers: [],
|
|
10
|
+
detailById: {},
|
|
11
|
+
fetchState: 'Not-Started',
|
|
12
|
+
searchString: '',
|
|
13
|
+
selectedTabType: 'income_transactions',
|
|
14
|
+
totalCount: 0,
|
|
15
|
+
trendFilter: 'last_12_months',
|
|
16
|
+
uiState: {
|
|
17
|
+
pageToken: null,
|
|
18
|
+
revenueSelection: 'year_to_date_revenue',
|
|
19
|
+
scrollYOffset: 0,
|
|
20
|
+
sortKey: 'year_to_date_revenue',
|
|
21
|
+
sortOrder: 'descending',
|
|
22
|
+
},
|
|
23
|
+
allTransactionsTabData: undefined,
|
|
24
|
+
detailCustomerId: undefined,
|
|
25
|
+
error: undefined,
|
|
26
|
+
};
|
|
27
|
+
const toCustomerSummary = (payload) => ({
|
|
28
|
+
id: payload.customer_id,
|
|
29
|
+
qboId: payload.qbo_id ?? undefined,
|
|
30
|
+
name: payload.customer_name ?? '',
|
|
31
|
+
balance: payload.balance ?? 0,
|
|
32
|
+
currencyCode: payload.currency_code ?? undefined,
|
|
33
|
+
currencySymbol: payload.currency_symbol ?? undefined,
|
|
34
|
+
revenue: Object.fromEntries(customerSummaryViewState_1.CUSTOMER_REVENUE_KEYS.map((key) => [key, payload[key] ?? 0])),
|
|
35
|
+
account: payload.account?.account_id != null
|
|
36
|
+
? {
|
|
37
|
+
id: payload.account.account_id,
|
|
38
|
+
name: payload.account.account_name ?? '',
|
|
39
|
+
}
|
|
40
|
+
: undefined,
|
|
41
|
+
accountingClass: payload.accounting_class?.accounting_class_id != null
|
|
42
|
+
? {
|
|
43
|
+
id: payload.accounting_class.accounting_class_id,
|
|
44
|
+
name: payload.accounting_class.accounting_class_name ?? '',
|
|
45
|
+
}
|
|
46
|
+
: undefined,
|
|
47
|
+
});
|
|
48
|
+
exports.toCustomerSummary = toCustomerSummary;
|
|
49
|
+
const getDetail = (draft, customerId) => {
|
|
50
|
+
var _a;
|
|
51
|
+
return ((_a = draft.detailById)[customerId] ?? (_a[customerId] = {
|
|
52
|
+
fetchState: 'Not-Started',
|
|
53
|
+
saveState: 'Not-Started',
|
|
54
|
+
}));
|
|
55
|
+
};
|
|
56
|
+
const customerSummaryView = (0, toolkit_1.createSlice)({
|
|
57
|
+
name: 'customerSummaryView',
|
|
58
|
+
initialState: exports.initialState,
|
|
59
|
+
reducers: {
|
|
60
|
+
fetchCustomerSummaryList: {
|
|
61
|
+
prepare(keepExistingListItems, searchString = '', pageToken = null) {
|
|
62
|
+
return { payload: { keepExistingListItems, pageToken, searchString } };
|
|
63
|
+
},
|
|
64
|
+
reducer(draft, action) {
|
|
65
|
+
const { keepExistingListItems, pageToken, searchString } = action.payload;
|
|
66
|
+
// Load-more while a page is in flight: keep that page (the epic drops this fetch too).
|
|
67
|
+
if (keepExistingListItems && draft.fetchState === 'In-Progress') {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (!keepExistingListItems) {
|
|
71
|
+
draft.customers = [];
|
|
72
|
+
draft.uiState.scrollYOffset = 0;
|
|
73
|
+
}
|
|
74
|
+
draft.searchString = searchString;
|
|
75
|
+
draft.uiState.pageToken = pageToken;
|
|
76
|
+
draft.fetchState = 'In-Progress';
|
|
77
|
+
draft.error = undefined;
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
updateCustomerSummaryList: {
|
|
81
|
+
prepare(response, keepExistingListItems) {
|
|
82
|
+
return { payload: { keepExistingListItems, response } };
|
|
83
|
+
},
|
|
84
|
+
reducer(draft, action) {
|
|
85
|
+
const { response, keepExistingListItems } = action.payload;
|
|
86
|
+
const customers = (response.data?.customers ?? []).map(exports.toCustomerSummary);
|
|
87
|
+
const existingIds = new Set(draft.customers.map(({ id }) => id));
|
|
88
|
+
draft.customers = keepExistingListItems
|
|
89
|
+
? [
|
|
90
|
+
...draft.customers,
|
|
91
|
+
...customers.filter(({ id }) => !existingIds.has(id)),
|
|
92
|
+
]
|
|
93
|
+
: customers;
|
|
94
|
+
draft.totalCount = response.data?.total_count ?? 0;
|
|
95
|
+
draft.uiState.pageToken = response.data?.query?.page_token ?? null;
|
|
96
|
+
draft.fetchState = 'Completed';
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
updateCustomerSummaryListFailure(draft, action) {
|
|
100
|
+
draft.fetchState = 'Error';
|
|
101
|
+
draft.error = action.payload;
|
|
102
|
+
// No more pages after a failure, so load-more doesn't keep retrying.
|
|
103
|
+
draft.uiState.pageToken = null;
|
|
104
|
+
},
|
|
105
|
+
updateCustomerSummarySortUiState: {
|
|
106
|
+
prepare(sortKey, sortOrder) {
|
|
107
|
+
return { payload: { sortKey, sortOrder } };
|
|
108
|
+
},
|
|
109
|
+
reducer(draft, action) {
|
|
110
|
+
draft.uiState.sortKey = action.payload.sortKey;
|
|
111
|
+
draft.uiState.sortOrder = action.payload.sortOrder;
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
updateCustomerSummaryRevenueSelection(draft, action) {
|
|
115
|
+
draft.uiState.revenueSelection = action.payload;
|
|
116
|
+
},
|
|
117
|
+
updateCustomerSummaryScrollYOffset(draft, action) {
|
|
118
|
+
draft.uiState.scrollYOffset = action.payload;
|
|
119
|
+
},
|
|
120
|
+
fetchCustomerSummaryDetail(draft, action) {
|
|
121
|
+
const detail = getDetail(draft, action.payload);
|
|
122
|
+
detail.fetchState = 'In-Progress';
|
|
123
|
+
detail.error = undefined;
|
|
124
|
+
},
|
|
125
|
+
updateCustomerSummaryDetail: {
|
|
126
|
+
prepare(customerId, customer) {
|
|
127
|
+
return { payload: { customer, customerId } };
|
|
128
|
+
},
|
|
129
|
+
reducer(draft, action) {
|
|
130
|
+
const detail = getDetail(draft, action.payload.customerId);
|
|
131
|
+
detail.customer = (0, exports.toCustomerSummary)(action.payload.customer);
|
|
132
|
+
detail.fetchState = 'Completed';
|
|
133
|
+
// Keep the list row in sync after an edit.
|
|
134
|
+
const index = draft.customers.findIndex(({ id }) => id === action.payload.customerId);
|
|
135
|
+
if (index >= 0) {
|
|
136
|
+
draft.customers[index] = {
|
|
137
|
+
...draft.customers[index],
|
|
138
|
+
account: detail.customer.account,
|
|
139
|
+
accountingClass: detail.customer.accountingClass,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
updateCustomerSummaryDetailFailure: {
|
|
145
|
+
prepare(customerId, status) {
|
|
146
|
+
return { payload: { customerId, status } };
|
|
147
|
+
},
|
|
148
|
+
reducer(draft, action) {
|
|
149
|
+
const detail = getDetail(draft, action.payload.customerId);
|
|
150
|
+
detail.fetchState = 'Error';
|
|
151
|
+
detail.error = action.payload.status;
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
saveCustomerSummaryDetail: {
|
|
155
|
+
prepare(customerId, changes) {
|
|
156
|
+
return { payload: { changes, customerId } };
|
|
157
|
+
},
|
|
158
|
+
reducer(draft, action) {
|
|
159
|
+
getDetail(draft, action.payload.customerId).saveState = 'In-Progress';
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
updateCustomerSummarySaveState: {
|
|
163
|
+
prepare(customerId, saveState) {
|
|
164
|
+
return { payload: { customerId, saveState } };
|
|
165
|
+
},
|
|
166
|
+
reducer(draft, action) {
|
|
167
|
+
getDetail(draft, action.payload.customerId).saveState =
|
|
168
|
+
action.payload.saveState;
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
updateCustomerAllTransactionsTabData(draft, action) {
|
|
172
|
+
draft.allTransactionsTabData = action.payload;
|
|
173
|
+
},
|
|
174
|
+
updateCustomerDetailSelectedTab(draft, action) {
|
|
175
|
+
draft.selectedTabType = action.payload;
|
|
176
|
+
},
|
|
177
|
+
updateCustomerTrendFilter(draft, action) {
|
|
178
|
+
draft.trendFilter = action.payload;
|
|
179
|
+
},
|
|
180
|
+
// Detail page opened for `customerId`: a different customer starts from the default filter / tab /
|
|
181
|
+
// transactions window / save state; the same one (e.g. back from a transaction) keeps them.
|
|
182
|
+
resetCustomerSummaryDetailUiState(draft, action) {
|
|
183
|
+
if (draft.detailCustomerId === action.payload) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
draft.detailCustomerId = action.payload;
|
|
187
|
+
draft.trendFilter = exports.initialState.trendFilter;
|
|
188
|
+
draft.selectedTabType = exports.initialState.selectedTabType;
|
|
189
|
+
draft.allTransactionsTabData = undefined;
|
|
190
|
+
Object.values(draft.detailById).forEach((detail) => {
|
|
191
|
+
detail.saveState = 'Not-Started';
|
|
192
|
+
});
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
extraReducers: (builder) => {
|
|
196
|
+
builder.addCase(rootActions_1.clearAll, (draft) => {
|
|
197
|
+
Object.assign(draft, exports.initialState);
|
|
198
|
+
});
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
_a = customerSummaryView.actions, exports.fetchCustomerSummaryList = _a.fetchCustomerSummaryList, exports.updateCustomerSummaryList = _a.updateCustomerSummaryList, exports.updateCustomerSummaryListFailure = _a.updateCustomerSummaryListFailure, exports.updateCustomerSummarySortUiState = _a.updateCustomerSummarySortUiState, exports.updateCustomerSummaryRevenueSelection = _a.updateCustomerSummaryRevenueSelection, exports.updateCustomerSummaryScrollYOffset = _a.updateCustomerSummaryScrollYOffset, exports.fetchCustomerSummaryDetail = _a.fetchCustomerSummaryDetail, exports.updateCustomerSummaryDetail = _a.updateCustomerSummaryDetail, exports.updateCustomerSummaryDetailFailure = _a.updateCustomerSummaryDetailFailure, exports.saveCustomerSummaryDetail = _a.saveCustomerSummaryDetail, exports.updateCustomerSummarySaveState = _a.updateCustomerSummarySaveState, exports.updateCustomerDetailSelectedTab = _a.updateCustomerDetailSelectedTab, exports.updateCustomerAllTransactionsTabData = _a.updateCustomerAllTransactionsTabData, exports.updateCustomerTrendFilter = _a.updateCustomerTrendFilter, exports.resetCustomerSummaryDetailUiState = _a.resetCustomerSummaryDetailUiState;
|
|
202
|
+
exports.default = customerSummaryView.reducer;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { NestedAccountHierarchyForReport } from '../../commonStateTypes/accountView/nestedAccountID';
|
|
2
|
+
import { NestedClassHierarchyForReport } from '../../commonStateTypes/classesView/nestedClassID';
|
|
3
|
+
import { ID } from '../../commonStateTypes/common';
|
|
4
|
+
import { RoleMap } from '../../entity/userRole/userRoleType';
|
|
5
|
+
import { VendorSpendTrendFilterTabType } from '../../entity/vendorExpense/vendorSpendTrendFilterTabType';
|
|
6
|
+
import { RootState } from '../../rootStateTypes';
|
|
7
|
+
import { CustomerAllTransactionsTabData, CustomerDetailTabType, CustomerSummaryDetailState, CustomerSummaryViewState } from './customerSummaryViewState';
|
|
8
|
+
export interface CustomerSummaryDetailView extends CustomerSummaryDetailState {
|
|
9
|
+
accountsHierarchyList: NestedAccountHierarchyForReport[];
|
|
10
|
+
classHierarchyList: NestedClassHierarchyForReport[];
|
|
11
|
+
isAccountingClassesEnabled: boolean;
|
|
12
|
+
/** Account (and, with classes on, class) list still loading: the pickers would show raw ids. */
|
|
13
|
+
isReferenceDataLoading: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare const getCustomerSummaryList: (state: RootState) => CustomerSummaryViewState;
|
|
16
|
+
export declare const getCustomerSummaryDetail: (state: RootState, customerId: ID) => CustomerSummaryDetailView;
|
|
17
|
+
export declare const getCustomerSummarySelectedTabType: (state: RootState) => CustomerDetailTabType;
|
|
18
|
+
export declare const getCustomerSummaryAllTransactionsTabData: (state: RootState) => CustomerAllTransactionsTabData | undefined;
|
|
19
|
+
export declare const getCustomerSummaryTrendFilter: (state: RootState) => VendorSpendTrendFilterTabType;
|
|
20
|
+
export declare const isCustomersTabVisible: (roleMap: RoleMap | undefined) => boolean;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isCustomersTabVisible = exports.getCustomerSummaryTrendFilter = exports.getCustomerSummaryAllTransactionsTabData = exports.getCustomerSummarySelectedTabType = exports.getCustomerSummaryDetail = exports.getCustomerSummaryList = void 0;
|
|
4
|
+
const toolkit_1 = require("@reduxjs/toolkit");
|
|
5
|
+
const tenantSelector_1 = require("../../entity/tenant/tenantSelector");
|
|
6
|
+
const accountListSelector_1 = require("../accountList/accountListSelector");
|
|
7
|
+
const classListSelector_1 = require("../classList/classListSelector");
|
|
8
|
+
const isLoadingFetchState = (fetchState) => fetchState === 'Not-Started' || fetchState === 'In-Progress';
|
|
9
|
+
const NOT_STARTED_DETAIL = {
|
|
10
|
+
fetchState: 'Not-Started',
|
|
11
|
+
saveState: 'Not-Started',
|
|
12
|
+
};
|
|
13
|
+
const getCustomerSummaryList = (state) => state.customerSummaryViewState;
|
|
14
|
+
exports.getCustomerSummaryList = getCustomerSummaryList;
|
|
15
|
+
exports.getCustomerSummaryDetail = (0, toolkit_1.createSelector)((state, customerId) => state.customerSummaryViewState.detailById[customerId], (state) => state.accountListState, (state) => state.classListState, tenantSelector_1.getIsAccountingClassesEnabled, (detail, accountListState, classListState, isAccountingClassesEnabled) => ({
|
|
16
|
+
...(detail ?? NOT_STARTED_DETAIL),
|
|
17
|
+
accountsHierarchyList: (0, accountListSelector_1.getNestedAccountListHierarchy)(accountListState, 'accountList'),
|
|
18
|
+
classHierarchyList: (0, classListSelector_1.getNestedClassListHierarchy)(classListState),
|
|
19
|
+
isAccountingClassesEnabled,
|
|
20
|
+
isReferenceDataLoading: isLoadingFetchState(accountListState.byReportId.accountList.fetchState) ||
|
|
21
|
+
(isAccountingClassesEnabled &&
|
|
22
|
+
isLoadingFetchState(classListState.fetchState)),
|
|
23
|
+
}));
|
|
24
|
+
const getCustomerSummarySelectedTabType = (state) => state.customerSummaryViewState.selectedTabType;
|
|
25
|
+
exports.getCustomerSummarySelectedTabType = getCustomerSummarySelectedTabType;
|
|
26
|
+
const getCustomerSummaryAllTransactionsTabData = (state) => state.customerSummaryViewState.allTransactionsTabData;
|
|
27
|
+
exports.getCustomerSummaryAllTransactionsTabData = getCustomerSummaryAllTransactionsTabData;
|
|
28
|
+
const getCustomerSummaryTrendFilter = (state) => state.customerSummaryViewState.trendFilter;
|
|
29
|
+
exports.getCustomerSummaryTrendFilter = getCustomerSummaryTrendFilter;
|
|
30
|
+
// Roles holding the customers / customers.read_only scopes (tenant role_scopes_v32). Same roles as the
|
|
31
|
+
// Vendors tab today, kept separate so AR access can diverge; bookkeeping_user is read-only.
|
|
32
|
+
const isCustomersTabVisible = (roleMap) => [
|
|
33
|
+
'admin',
|
|
34
|
+
'bookkeeping_admin',
|
|
35
|
+
'bookkeeping_user',
|
|
36
|
+
'ap_analyst',
|
|
37
|
+
'controller',
|
|
38
|
+
'customer_success_manager',
|
|
39
|
+
'reviewer',
|
|
40
|
+
'tax_lead',
|
|
41
|
+
'preparer',
|
|
42
|
+
].some((role) => roleMap?.[role] === true);
|
|
43
|
+
exports.isCustomersTabVisible = isCustomersTabVisible;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { FetchState, ID } from '../../commonStateTypes/common';
|
|
2
|
+
import { SortOrder } from '../../commonStateTypes/selectorTypes/sortOrderTypes';
|
|
3
|
+
import { TimePeriod } from '../../commonStateTypes/timePeriod';
|
|
4
|
+
import { PageToken } from '../../commonStateTypes/viewAndReport/viewAndReport';
|
|
5
|
+
import { VendorSpendTrendFilterTabType } from '../../entity/vendorExpense/vendorSpendTrendFilterTabType';
|
|
6
|
+
import { ZeniAPIStatus } from '../../responsePayload';
|
|
7
|
+
export declare const CUSTOMER_REVENUE_KEYS: readonly ["last_90_days_revenue", "last_30_days_revenue", "year_to_date_revenue", "last_month_revenue", "last_3_months_revenue", "last_6_months_revenue", "last_12_months_revenue", "previous_year_revenue"];
|
|
8
|
+
export type CustomerRevenueKey = (typeof CUSTOMER_REVENUE_KEYS)[number];
|
|
9
|
+
export type CustomerSummarySortKey = 'customer_name' | 'account' | 'accounting_class' | 'balance' | CustomerRevenueKey;
|
|
10
|
+
export interface CustomerSummary {
|
|
11
|
+
balance: number;
|
|
12
|
+
id: ID;
|
|
13
|
+
name: string;
|
|
14
|
+
revenue: Record<CustomerRevenueKey, number>;
|
|
15
|
+
account?: {
|
|
16
|
+
id: ID;
|
|
17
|
+
name: string;
|
|
18
|
+
};
|
|
19
|
+
accountingClass?: {
|
|
20
|
+
id: ID;
|
|
21
|
+
name: string;
|
|
22
|
+
};
|
|
23
|
+
currencyCode?: string;
|
|
24
|
+
currencySymbol?: string;
|
|
25
|
+
qboId?: ID;
|
|
26
|
+
}
|
|
27
|
+
export interface CustomerSummaryListUIState {
|
|
28
|
+
pageToken: PageToken;
|
|
29
|
+
revenueSelection: CustomerRevenueKey;
|
|
30
|
+
scrollYOffset: number;
|
|
31
|
+
sortKey: CustomerSummarySortKey;
|
|
32
|
+
sortOrder: SortOrder;
|
|
33
|
+
}
|
|
34
|
+
export type CustomerDetailTabType = 'income_transactions' | 'all_transactions';
|
|
35
|
+
export interface CustomerAllTransactionsTabData {
|
|
36
|
+
numberOfQuartersFetched: number;
|
|
37
|
+
timePeriod: TimePeriod;
|
|
38
|
+
}
|
|
39
|
+
/** Default category / class edit: only the keys present are saved (null clears the default). */
|
|
40
|
+
export interface CustomerSummaryDetailChanges {
|
|
41
|
+
accountId?: ID | null;
|
|
42
|
+
accountingClassId?: ID | null;
|
|
43
|
+
}
|
|
44
|
+
export interface CustomerSummaryDetailState {
|
|
45
|
+
fetchState: FetchState;
|
|
46
|
+
saveState: FetchState;
|
|
47
|
+
customer?: CustomerSummary;
|
|
48
|
+
error?: ZeniAPIStatus;
|
|
49
|
+
}
|
|
50
|
+
export interface CustomerSummaryViewState {
|
|
51
|
+
customers: CustomerSummary[];
|
|
52
|
+
detailById: Record<ID, CustomerSummaryDetailState>;
|
|
53
|
+
fetchState: FetchState;
|
|
54
|
+
searchString: string;
|
|
55
|
+
selectedTabType: CustomerDetailTabType;
|
|
56
|
+
totalCount: number;
|
|
57
|
+
trendFilter: VendorSpendTrendFilterTabType;
|
|
58
|
+
uiState: CustomerSummaryListUIState;
|
|
59
|
+
allTransactionsTabData?: CustomerAllTransactionsTabData;
|
|
60
|
+
/** Customer the detail page UI state (filter, tab, transactions window) belongs to. */
|
|
61
|
+
detailCustomerId?: ID;
|
|
62
|
+
error?: ZeniAPIStatus;
|
|
63
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CUSTOMER_REVENUE_KEYS = void 0;
|
|
4
|
+
exports.CUSTOMER_REVENUE_KEYS = [
|
|
5
|
+
'last_90_days_revenue',
|
|
6
|
+
'last_30_days_revenue',
|
|
7
|
+
'year_to_date_revenue',
|
|
8
|
+
'last_month_revenue',
|
|
9
|
+
'last_3_months_revenue',
|
|
10
|
+
'last_6_months_revenue',
|
|
11
|
+
'last_12_months_revenue',
|
|
12
|
+
'previous_year_revenue',
|
|
13
|
+
];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { RootState } from '../../../rootStateTypes';
|
|
4
|
+
import { ZeniAPI } from '../../../zeniAPI';
|
|
5
|
+
import { fetchAccountList } from '../../accountList/accountListReducer';
|
|
6
|
+
import { fetchClassList } from '../../classList/classListReducer';
|
|
7
|
+
import { fetchCustomerSummaryDetail, updateCustomerSummaryDetail, updateCustomerSummaryDetailFailure } from '../customerSummaryViewReducer';
|
|
8
|
+
export type ActionType = ReturnType<typeof fetchAccountList> | ReturnType<typeof fetchClassList> | ReturnType<typeof fetchCustomerSummaryDetail> | ReturnType<typeof updateCustomerSummaryDetail> | ReturnType<typeof updateCustomerSummaryDetailFailure>;
|
|
9
|
+
export declare const fetchCustomerSummaryDetailEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchCustomerSummaryDetailEpic = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const responsePayload_1 = require("../../../responsePayload");
|
|
7
|
+
const accountListReducer_1 = require("../../accountList/accountListReducer");
|
|
8
|
+
const classListReducer_1 = require("../../classList/classListReducer");
|
|
9
|
+
const customerSummaryViewReducer_1 = require("../customerSummaryViewReducer");
|
|
10
|
+
const fetchCustomerSummaryDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(customerSummaryViewReducer_1.fetchCustomerSummaryDetail.match), (0, operators_1.mergeMap)(({ payload: customerId }) => {
|
|
11
|
+
// Category / class pickers on the detail page need the account and class lists.
|
|
12
|
+
const { accountListState, classListState } = state$.value;
|
|
13
|
+
const listActions = [];
|
|
14
|
+
const accountList = accountListState.byReportId.accountList;
|
|
15
|
+
if (!accountList.hasValidState() &&
|
|
16
|
+
accountList.fetchState !== 'In-Progress') {
|
|
17
|
+
listActions.push((0, accountListReducer_1.fetchAccountList)('accountList', true));
|
|
18
|
+
}
|
|
19
|
+
if (!classListState.hasValidState() &&
|
|
20
|
+
classListState.fetchState !== 'In-Progress') {
|
|
21
|
+
listActions.push((0, classListReducer_1.fetchClassList)());
|
|
22
|
+
}
|
|
23
|
+
const customer$ = zeniAPI
|
|
24
|
+
.getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/customers/summary/${encodeURIComponent(customerId)}`)
|
|
25
|
+
.pipe((0, operators_1.map)((response) => {
|
|
26
|
+
const customer = response.data?.customers?.[0];
|
|
27
|
+
return (0, responsePayload_1.isSuccessResponse)(response) && customer != null
|
|
28
|
+
? (0, customerSummaryViewReducer_1.updateCustomerSummaryDetail)(customerId, customer)
|
|
29
|
+
: (0, customerSummaryViewReducer_1.updateCustomerSummaryDetailFailure)(customerId, response.status);
|
|
30
|
+
}), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, customerSummaryViewReducer_1.updateCustomerSummaryDetailFailure)(customerId, (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Fetch customer summary REST API call errored out' +
|
|
31
|
+
JSON.stringify(error))))));
|
|
32
|
+
return (0, rxjs_1.concat)((0, rxjs_1.from)(listActions), customer$);
|
|
33
|
+
}));
|
|
34
|
+
exports.fetchCustomerSummaryDetailEpic = fetchCustomerSummaryDetailEpic;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { RootState } from '../../../rootStateTypes';
|
|
4
|
+
import { ZeniAPI } from '../../../zeniAPI';
|
|
5
|
+
import { fetchCustomerSummaryList, updateCustomerSummaryList, updateCustomerSummaryListFailure } from '../customerSummaryViewReducer';
|
|
6
|
+
export type ActionType = ReturnType<typeof fetchCustomerSummaryList> | ReturnType<typeof updateCustomerSummaryList> | ReturnType<typeof updateCustomerSummaryListFailure>;
|
|
7
|
+
export declare const fetchCustomerSummaryListEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchCustomerSummaryListEpic = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const responsePayload_1 = require("../../../responsePayload");
|
|
7
|
+
const customerSummaryViewReducer_1 = require("../customerSummaryViewReducer");
|
|
8
|
+
const fetchCustomerSummaryListEpic = (actions$, state$, zeniAPI) => {
|
|
9
|
+
const fetch$ = actions$.pipe((0, operators_1.filter)(customerSummaryViewReducer_1.fetchCustomerSummaryList.match));
|
|
10
|
+
const fetchPage = (action) => {
|
|
11
|
+
const { keepExistingListItems, pageToken, searchString } = action.payload;
|
|
12
|
+
const { uiState } = state$.value.customerSummaryViewState;
|
|
13
|
+
const query = {
|
|
14
|
+
page_token: pageToken,
|
|
15
|
+
sort_by: uiState.sortKey,
|
|
16
|
+
sort_order: uiState.sortOrder === 'ascending' ? 'asc' : 'desc',
|
|
17
|
+
search_text: searchString,
|
|
18
|
+
};
|
|
19
|
+
return zeniAPI
|
|
20
|
+
.getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/customers/summary?query=${encodeURIComponent(JSON.stringify(query))}`)
|
|
21
|
+
.pipe((0, operators_1.map)((response) => (0, responsePayload_1.isSuccessResponse)(response)
|
|
22
|
+
? (0, customerSummaryViewReducer_1.updateCustomerSummaryList)(response, keepExistingListItems)
|
|
23
|
+
: (0, customerSummaryViewReducer_1.updateCustomerSummaryListFailure)(response.status)), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, customerSummaryViewReducer_1.updateCustomerSummaryListFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Fetch customer summary list REST API call errored out' +
|
|
24
|
+
JSON.stringify(error))))));
|
|
25
|
+
};
|
|
26
|
+
// A new search / sort cancels whatever is in flight; a load-more is dropped while any page is in flight
|
|
27
|
+
// (the reducer ignores it too), so the in-flight page isn't restarted.
|
|
28
|
+
const loadMore$ = fetch$.pipe((0, operators_1.filter)(({ payload }) => payload.keepExistingListItems));
|
|
29
|
+
return fetch$.pipe((0, operators_1.filter)(({ payload }) => !payload.keepExistingListItems), (0, operators_1.map)((action) => loadMore$.pipe((0, operators_1.startWith)(action))), (0, operators_1.startWith)(loadMore$), (0, operators_1.switchMap)((fetches$) => fetches$.pipe((0, operators_1.exhaustMap)(fetchPage))));
|
|
30
|
+
};
|
|
31
|
+
exports.fetchCustomerSummaryListEpic = fetchCustomerSummaryListEpic;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
4
|
+
import { RootState } from '../../../rootStateTypes';
|
|
5
|
+
import { ZeniAPI } from '../../../zeniAPI';
|
|
6
|
+
import { saveCustomerSummaryDetail, updateCustomerSummaryDetail, updateCustomerSummarySaveState } from '../customerSummaryViewReducer';
|
|
7
|
+
export type ActionType = ReturnType<typeof saveCustomerSummaryDetail> | ReturnType<typeof updateCustomerSummaryDetail> | ReturnType<typeof updateCustomerSummarySaveState> | ReturnType<typeof openSnackbar>;
|
|
8
|
+
export declare const saveCustomerSummaryDetailEpic: (actions$: ActionsObservable<ActionType>, _: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.saveCustomerSummaryDetailEpic = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
7
|
+
const responsePayload_1 = require("../../../responsePayload");
|
|
8
|
+
const customerSummaryViewReducer_1 = require("../customerSummaryViewReducer");
|
|
9
|
+
// Zeni-only edit of a customer's default category / class from the Customers tab.
|
|
10
|
+
const saveCustomerSummaryDetailEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(customerSummaryViewReducer_1.saveCustomerSummaryDetail.match),
|
|
11
|
+
// concatMap: quick successive saves resolve in order, so the latest one wins
|
|
12
|
+
(0, operators_1.concatMap)(({ payload: { customerId, changes } }) => {
|
|
13
|
+
const failure = () => [
|
|
14
|
+
(0, customerSummaryViewReducer_1.updateCustomerSummarySaveState)(customerId, 'Error'),
|
|
15
|
+
(0, snackbarReducer_1.openSnackbar)({
|
|
16
|
+
messageSection: 'update_customer',
|
|
17
|
+
messageText: 'failed',
|
|
18
|
+
type: 'error',
|
|
19
|
+
}),
|
|
20
|
+
];
|
|
21
|
+
return zeniAPI
|
|
22
|
+
.putAndGetJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/customers/summary/${encodeURIComponent(customerId)}`,
|
|
23
|
+
// Only the changed fields: an omitted one keeps its (possibly history-based) default
|
|
24
|
+
{
|
|
25
|
+
...(changes.accountId !== undefined
|
|
26
|
+
? { account_id: changes.accountId }
|
|
27
|
+
: {}),
|
|
28
|
+
...(changes.accountingClassId !== undefined
|
|
29
|
+
? { accounting_class_id: changes.accountingClassId }
|
|
30
|
+
: {}),
|
|
31
|
+
})
|
|
32
|
+
.pipe((0, operators_1.mergeMap)((response) => {
|
|
33
|
+
const customer = response.data?.customers?.[0];
|
|
34
|
+
if (!(0, responsePayload_1.isSuccessResponse)(response) || customer == null) {
|
|
35
|
+
return (0, rxjs_1.from)(failure());
|
|
36
|
+
}
|
|
37
|
+
return (0, rxjs_1.from)([
|
|
38
|
+
(0, customerSummaryViewReducer_1.updateCustomerSummaryDetail)(customerId, customer),
|
|
39
|
+
(0, customerSummaryViewReducer_1.updateCustomerSummarySaveState)(customerId, 'Completed'),
|
|
40
|
+
(0, snackbarReducer_1.openSnackbar)({
|
|
41
|
+
messageSection: 'update_customer',
|
|
42
|
+
messageText: 'success',
|
|
43
|
+
type: 'success',
|
|
44
|
+
}),
|
|
45
|
+
]);
|
|
46
|
+
}), (0, operators_1.catchError)(() => (0, rxjs_1.from)(failure())));
|
|
47
|
+
}));
|
|
48
|
+
exports.saveCustomerSummaryDetailEpic = saveCustomerSummaryDetailEpic;
|
|
@@ -29,9 +29,10 @@ const fetchReconciliationViewEpic = (actions$, state$, zeniAPI) => actions$.pipe
|
|
|
29
29
|
}
|
|
30
30
|
let fetchState;
|
|
31
31
|
if (accountId != null) {
|
|
32
|
+
// Period bucket can be unhydrated during app-shell load.
|
|
32
33
|
fetchState =
|
|
33
34
|
accountReconciliationRecords[(0, timePeriod_1.toMonthYearPeriodId)(selectedPeriod)]
|
|
34
|
-
|
|
35
|
+
?.reconciliationByAccountID[accountId]?.transactionFetchState
|
|
35
36
|
.fetchState;
|
|
36
37
|
}
|
|
37
38
|
else {
|