@zeniai/client-epic-state 4.20.1 → 4.20.2-beta0ND
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/common/aiCfo/aiCfoSuggestedQuestionsPageContext.d.ts +19 -0
- package/lib/common/aiCfo/aiCfoSuggestedQuestionsPageContext.js +2 -0
- package/lib/commonStateTypes/animations.d.ts +1 -1
- package/lib/entity/aiCfo/aiCfoSelector.d.ts +1 -2
- package/lib/entity/billPay/billTransaction/billTransactionState.d.ts +2 -2
- package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +38 -0
- package/lib/entity/jeSchedules/jeSchedulesPayload.js +78 -0
- package/lib/entity/jeSchedules/jeSchedulesSelector.d.ts +4 -1
- package/lib/entity/jeSchedules/jeSchedulesSelector.js +5 -1
- package/lib/entity/jeSchedules/jeSchedulesState.d.ts +37 -0
- package/lib/entity/tenant/tenantPayload.d.ts +1 -0
- package/lib/entity/tenant/tenantReducer.js +1 -0
- package/lib/entity/tenant/tenantSelector.d.ts +1 -0
- package/lib/entity/tenant/tenantSelector.js +9 -1
- package/lib/entity/tenant/tenantState.d.ts +1 -0
- package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.d.ts +4 -1
- package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.js +1 -0
- package/lib/entity/transaction/payloadTypes/transactionPayload.d.ts +3 -0
- package/lib/entity/transaction/payloadTypes/transactionPayload.js +17 -1
- package/lib/entity/transaction/stateTypes/scheduleTransaction.d.ts +1 -0
- package/lib/entity/transaction/stateTypes/transaction.d.ts +5 -0
- package/lib/entity/transaction/stateTypes/transactionLine.d.ts +1 -1
- package/lib/epic.d.ts +2 -1
- package/lib/epic.js +2 -1
- package/lib/esm/common/aiCfo/aiCfoSuggestedQuestionsPageContext.js +1 -0
- package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +78 -0
- package/lib/esm/entity/jeSchedules/jeSchedulesSelector.js +5 -1
- package/lib/esm/entity/tenant/tenantReducer.js +1 -0
- package/lib/esm/entity/tenant/tenantSelector.js +7 -0
- package/lib/esm/entity/transaction/payloadTypes/scheduleTransactionPayload.js +1 -0
- package/lib/esm/entity/transaction/payloadTypes/transactionPayload.js +17 -1
- package/lib/esm/epic.js +2 -1
- package/lib/esm/index.js +10 -8
- package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +82 -1
- package/lib/esm/view/aiCfoView/aiCfoViewSelector.js +8 -2
- package/lib/esm/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.js +29 -0
- package/lib/esm/view/classList/fetchClassListEpic.js +9 -2
- package/lib/esm/view/commonVendorView/vendorView/vendorViewSelector.js +18 -5
- package/lib/esm/view/commonVendorView/vendorsTabVendorView/vendorsTabVendorViewSelector.js +6 -2
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +2 -2
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.js +2 -2
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +4 -3
- package/lib/esm/view/expenseAutomationView/expenseAutomationViewSelector.js +0 -1
- package/lib/esm/view/expenseAutomationView/helpers/saveTransactionHelper.js +2 -2
- package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +2 -2
- package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +17 -1
- package/lib/esm/view/expenseAutomationView/selectors/fluxAnalysisViewSelector.js +10 -2
- package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +63 -6
- package/lib/esm/view/expenseAutomationView/selectors/missingReceiptsSelector.js +12 -4
- package/lib/esm/view/expenseAutomationView/selectors/reconciliationViewSelector.js +22 -9
- package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +12 -6
- package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +18 -1
- package/lib/esm/view/profitAndLossClassesView/horizontalSectionEmptyBalancesSlice.js +17 -0
- package/lib/esm/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelector.js +3 -0
- package/lib/esm/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +20 -29
- package/lib/esm/view/spendManagement/billPay/billList/billListSelector.js +10 -0
- package/lib/esm/view/spendManagement/billPay/billList/billListState.js +1 -0
- package/lib/esm/view/spendManagement/billPay/billPayReview/billPayReviewSelector.js +7 -3
- package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewSelector.js +5 -5
- package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPayApproversDetailsEpic.js +7 -2
- package/lib/esm/view/spendManagement/billPay/editBillView/editBillViewSelector.js +13 -6
- package/lib/esm/view/spendManagement/chargeCards/chargeCardList/chargeCardList.js +1 -0
- package/lib/esm/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.js +2 -0
- package/lib/esm/view/spendManagement/reimbursement/editRemiView/editRemiViewSelector.js +7 -4
- package/lib/esm/view/spendManagement/reimbursement/remiListView/remiListSelector.js +12 -0
- package/lib/esm/view/spendManagement/reimbursement/remiListView/remiListState.js +1 -0
- package/lib/esm/view/taskManager/taskDetailView/taskDetailSelector.js +2 -2
- package/lib/esm/view/transactionDetail/epics/saveTransactionHelper.js +2 -2
- package/lib/esm/view/transactionDetail/transactionDetailLocalDataHelper.js +16 -14
- package/lib/index.d.ts +15 -11
- package/lib/index.js +44 -32
- package/lib/tsconfig.typecheck.tsbuildinfo +1 -1
- package/lib/view/aiCfoView/aiCfoViewPayload.d.ts +7 -0
- package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +15 -1
- package/lib/view/aiCfoView/aiCfoViewReducer.js +83 -2
- package/lib/view/aiCfoView/aiCfoViewSelector.d.ts +4 -1
- package/lib/view/aiCfoView/aiCfoViewSelector.js +9 -2
- package/lib/view/aiCfoView/aiCfoViewState.d.ts +15 -1
- package/lib/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.d.ts +8 -0
- package/lib/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.js +33 -0
- package/lib/view/auditReportView/auditReportViewState.d.ts +1 -1
- package/lib/view/classList/fetchClassListEpic.d.ts +1 -1
- package/lib/view/classList/fetchClassListEpic.js +8 -1
- package/lib/view/commonVendorView/vendorView/vendorViewSelector.d.ts +1 -0
- package/lib/view/commonVendorView/vendorView/vendorViewSelector.js +18 -5
- package/lib/view/commonVendorView/vendorsTabVendorView/vendorsTabVendorViewSelector.d.ts +1 -0
- package/lib/view/commonVendorView/vendorsTabVendorView/vendorsTabVendorViewSelector.js +6 -2
- package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +2 -2
- package/lib/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.js +1 -1
- package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +4 -3
- package/lib/view/expenseAutomationView/expenseAutomationViewSelector.js +0 -1
- package/lib/view/expenseAutomationView/helpers/saveTransactionHelper.js +2 -2
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +2 -2
- package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.d.ts +1 -1
- package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +2 -2
- package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +18 -2
- package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +2 -0
- package/lib/view/expenseAutomationView/selectors/fluxAnalysisViewSelector.js +10 -2
- package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +63 -6
- package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.js +12 -4
- package/lib/view/expenseAutomationView/selectors/reconciliationViewSelector.js +22 -9
- package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +11 -5
- package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +5 -0
- package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +20 -0
- package/lib/view/profitAndLossClassesView/horizontalSectionEmptyBalancesSlice.d.ts +9 -0
- package/lib/view/profitAndLossClassesView/horizontalSectionEmptyBalancesSlice.js +20 -0
- package/lib/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelector.js +3 -0
- package/lib/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +20 -29
- package/lib/view/scheduleView/scheduleListView/scheduleListTypes.d.ts +1 -1
- package/lib/view/spendManagement/billPay/billList/billListSelector.js +10 -0
- package/lib/view/spendManagement/billPay/billList/billListState.d.ts +1 -1
- package/lib/view/spendManagement/billPay/billList/billListState.js +1 -0
- package/lib/view/spendManagement/billPay/billPayReview/billPayReviewSelector.js +7 -3
- package/lib/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewSelector.js +5 -5
- package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPayApproversDetailsEpic.js +7 -2
- package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.js +13 -6
- package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.d.ts +1 -1
- package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.js +1 -0
- package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.js +2 -0
- package/lib/view/spendManagement/reimbursement/editRemiView/editRemiViewSelector.js +6 -3
- package/lib/view/spendManagement/reimbursement/remiListView/remiListSelector.d.ts +1 -0
- package/lib/view/spendManagement/reimbursement/remiListView/remiListSelector.js +12 -0
- package/lib/view/spendManagement/reimbursement/remiListView/remiListState.d.ts +1 -1
- package/lib/view/spendManagement/reimbursement/remiListView/remiListState.js +1 -0
- package/lib/view/taskManager/taskDetailView/taskDetailSelector.js +2 -2
- package/lib/view/transactionDetail/epics/saveTransactionHelper.js +2 -2
- package/lib/view/transactionDetail/transactionDetailLocalDataHelper.js +16 -14
- package/package.json +1 -1
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
|
+
function removeSessionIdFromPageKeyMap(draft, sessionId) {
|
|
3
|
+
const map = draft.uiState.chatSessionIdByPageKey;
|
|
4
|
+
for (const key of Object.keys(map)) {
|
|
5
|
+
if (map[key] === sessionId) {
|
|
6
|
+
delete map[key];
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function mirrorCurrentSessionToPageKeyMapIfActive(draft) {
|
|
11
|
+
const key = draft.uiState.aiCfoSidePanelHostPageKey;
|
|
12
|
+
const sessionId = draft.uiState.currentChatSessionId;
|
|
13
|
+
if (key != null && sessionId != null) {
|
|
14
|
+
draft.uiState.chatSessionIdByPageKey[key] = sessionId;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
2
17
|
export const initialAiCfoViewState = {
|
|
3
18
|
fetchState: 'Not-Started',
|
|
4
19
|
error: undefined,
|
|
@@ -6,6 +21,8 @@ export const initialAiCfoViewState = {
|
|
|
6
21
|
currentInput: '',
|
|
7
22
|
scrollPositionByChatSessionId: {},
|
|
8
23
|
currentChatSessionId: undefined,
|
|
24
|
+
aiCfoSidePanelHostPageKey: undefined,
|
|
25
|
+
chatSessionIdByPageKey: {},
|
|
9
26
|
agentId: undefined,
|
|
10
27
|
chatHistoryNextPageToken: {},
|
|
11
28
|
chatSessionsNextPageToken: { nextPageToken: null, hasMore: false },
|
|
@@ -29,6 +46,7 @@ export const initialAiCfoViewState = {
|
|
|
29
46
|
fetchChatSessionHistoryByChatSessionId: {},
|
|
30
47
|
responseStateByChatSessionId: {},
|
|
31
48
|
stopSubmitStateByChatSessionId: {},
|
|
49
|
+
suggestedQuestionsByPageContext: {},
|
|
32
50
|
};
|
|
33
51
|
const aiCfoView = createSlice({
|
|
34
52
|
name: 'aiCfoView',
|
|
@@ -162,6 +180,7 @@ const aiCfoView = createSlice({
|
|
|
162
180
|
setSession(draft, action) {
|
|
163
181
|
draft.uiState.currentChatSessionId = action.payload.sessionId;
|
|
164
182
|
draft.uiState.agentId = action.payload.agentId;
|
|
183
|
+
mirrorCurrentSessionToPageKeyMapIfActive(draft);
|
|
165
184
|
},
|
|
166
185
|
createSession: {
|
|
167
186
|
reducer(draft, action) {
|
|
@@ -185,6 +204,7 @@ const aiCfoView = createSlice({
|
|
|
185
204
|
nextPageToken: null,
|
|
186
205
|
hasMore: false,
|
|
187
206
|
};
|
|
207
|
+
mirrorCurrentSessionToPageKeyMapIfActive(draft);
|
|
188
208
|
},
|
|
189
209
|
createSessionFailure(draft, action) {
|
|
190
210
|
draft.createSessionState.fetchState = 'Error';
|
|
@@ -222,6 +242,7 @@ const aiCfoView = createSlice({
|
|
|
222
242
|
nextPageToken: null,
|
|
223
243
|
hasMore: false,
|
|
224
244
|
};
|
|
245
|
+
mirrorCurrentSessionToPageKeyMapIfActive(draft);
|
|
225
246
|
},
|
|
226
247
|
createSessionAndSubmitSuccess(draft) {
|
|
227
248
|
// Note: currentChatSessionId, agentId, and chatHistoryNextPageToken are set by initializeNewSessionState
|
|
@@ -338,6 +359,7 @@ const aiCfoView = createSlice({
|
|
|
338
359
|
draft.uiState.currentChatSessionId = undefined;
|
|
339
360
|
draft.uiState.agentId = undefined;
|
|
340
361
|
}
|
|
362
|
+
removeSessionIdFromPageKeyMap(draft, chatSessionId);
|
|
341
363
|
delete draft.uiState.chatHistoryNextPageToken[chatSessionId];
|
|
342
364
|
delete draft.uiState.scrollPositionByChatSessionId[chatSessionId];
|
|
343
365
|
delete draft.fetchChatSessionHistoryByChatSessionId[chatSessionId];
|
|
@@ -360,6 +382,65 @@ const aiCfoView = createSlice({
|
|
|
360
382
|
},
|
|
361
383
|
clearCurrentSessionId(draft) {
|
|
362
384
|
draft.uiState.currentChatSessionId = undefined;
|
|
385
|
+
const key = draft.uiState.aiCfoSidePanelHostPageKey;
|
|
386
|
+
if (key != null) {
|
|
387
|
+
delete draft.uiState.chatSessionIdByPageKey[key];
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
applyAiCfoSidePanelHostPageTransition(draft, action) {
|
|
391
|
+
const { newAiCfoSidePanelHostPageKey, nextCurrentChatSessionId } = action.payload;
|
|
392
|
+
const prevKey = draft.uiState.aiCfoSidePanelHostPageKey;
|
|
393
|
+
const curId = draft.uiState.currentChatSessionId;
|
|
394
|
+
if (prevKey != null &&
|
|
395
|
+
prevKey !== newAiCfoSidePanelHostPageKey &&
|
|
396
|
+
curId != null) {
|
|
397
|
+
draft.uiState.chatSessionIdByPageKey[prevKey] = curId;
|
|
398
|
+
}
|
|
399
|
+
draft.uiState.aiCfoSidePanelHostPageKey = newAiCfoSidePanelHostPageKey;
|
|
400
|
+
draft.uiState.currentChatSessionId =
|
|
401
|
+
nextCurrentChatSessionId != null ? nextCurrentChatSessionId : undefined;
|
|
402
|
+
draft.uiState.currentInput = '';
|
|
403
|
+
mirrorCurrentSessionToPageKeyMapIfActive(draft);
|
|
404
|
+
},
|
|
405
|
+
clearAiCfoSidePanelHostPageContext(draft) {
|
|
406
|
+
const key = draft.uiState.aiCfoSidePanelHostPageKey;
|
|
407
|
+
const curId = draft.uiState.currentChatSessionId;
|
|
408
|
+
if (key != null && curId != null) {
|
|
409
|
+
draft.uiState.chatSessionIdByPageKey[key] = curId;
|
|
410
|
+
}
|
|
411
|
+
draft.uiState.aiCfoSidePanelHostPageKey = undefined;
|
|
412
|
+
},
|
|
413
|
+
fetchSuggestedQuestions(draft, action) {
|
|
414
|
+
const { pageContext } = action.payload;
|
|
415
|
+
const prev = draft.suggestedQuestionsByPageContext[pageContext];
|
|
416
|
+
draft.suggestedQuestionsByPageContext[pageContext] = {
|
|
417
|
+
fetchState: 'In-Progress',
|
|
418
|
+
pageContext,
|
|
419
|
+
suggestedQuestions: prev?.suggestedQuestions ?? [],
|
|
420
|
+
generatedAt: prev?.generatedAt,
|
|
421
|
+
error: undefined,
|
|
422
|
+
};
|
|
423
|
+
},
|
|
424
|
+
fetchSuggestedQuestionsSuccess(draft, action) {
|
|
425
|
+
const { pageContext, generatedAt, suggestedQuestions } = action.payload;
|
|
426
|
+
draft.suggestedQuestionsByPageContext[pageContext] = {
|
|
427
|
+
fetchState: 'Completed',
|
|
428
|
+
pageContext,
|
|
429
|
+
generatedAt,
|
|
430
|
+
suggestedQuestions,
|
|
431
|
+
error: undefined,
|
|
432
|
+
};
|
|
433
|
+
},
|
|
434
|
+
fetchSuggestedQuestionsFailure(draft, action) {
|
|
435
|
+
const { pageContext, error } = action.payload;
|
|
436
|
+
const prev = draft.suggestedQuestionsByPageContext[pageContext];
|
|
437
|
+
draft.suggestedQuestionsByPageContext[pageContext] = {
|
|
438
|
+
fetchState: 'Error',
|
|
439
|
+
pageContext,
|
|
440
|
+
suggestedQuestions: prev?.suggestedQuestions ?? [],
|
|
441
|
+
generatedAt: prev?.generatedAt,
|
|
442
|
+
error,
|
|
443
|
+
};
|
|
363
444
|
},
|
|
364
445
|
clearAiCfoView(draft) {
|
|
365
446
|
Object.assign(draft, initialAiCfoViewState);
|
|
@@ -371,5 +452,5 @@ const aiCfoView = createSlice({
|
|
|
371
452
|
},
|
|
372
453
|
},
|
|
373
454
|
});
|
|
374
|
-
export const { submitQuestion, submitQuestionSuccess, submitQuestionFailure, updateResponseState, updateAiCfoViewScrollPosition, updateCurrentInput, clearInput, setSession, createSession, createSessionSuccess, createSessionFailure, createSessionAndSubmit, initializeNewSessionState, createSessionAndSubmitSuccess, createSessionAndSubmitFailure, fetchChatSessionsForUser, fetchChatSessionsForUserSuccess, fetchChatSessionsForUserFailure, fetchChatHistory, fetchChatHistorySuccess, fetchChatHistoryFailure, clearCurrentSessionId, clearLastContextMessage, stopSubmit, stopSubmitSuccess, stopSubmitFailure, stopSubmitQuestion, stopSubmitQuestionSuccess, stopSubmitQuestionFailure, acceptMasterTOS, acceptMasterTOSSuccess, acceptMasterTOSFailure, deleteChatSession, deleteChatSessionSuccess, deleteChatSessionFailure, clearDeleteChatSessionStatus, clearAiCfoView, updateCotCollapsedState, } = aiCfoView.actions;
|
|
455
|
+
export const { submitQuestion, submitQuestionSuccess, submitQuestionFailure, updateResponseState, updateAiCfoViewScrollPosition, updateCurrentInput, clearInput, setSession, createSession, createSessionSuccess, createSessionFailure, createSessionAndSubmit, initializeNewSessionState, createSessionAndSubmitSuccess, createSessionAndSubmitFailure, fetchChatSessionsForUser, fetchChatSessionsForUserSuccess, fetchChatSessionsForUserFailure, fetchChatHistory, fetchChatHistorySuccess, fetchChatHistoryFailure, clearCurrentSessionId, clearLastContextMessage, stopSubmit, stopSubmitSuccess, stopSubmitFailure, stopSubmitQuestion, stopSubmitQuestionSuccess, stopSubmitQuestionFailure, acceptMasterTOS, acceptMasterTOSSuccess, acceptMasterTOSFailure, deleteChatSession, deleteChatSessionSuccess, deleteChatSessionFailure, clearDeleteChatSessionStatus, clearAiCfoView, updateCotCollapsedState, fetchSuggestedQuestions, fetchSuggestedQuestionsSuccess, fetchSuggestedQuestionsFailure, applyAiCfoSidePanelHostPageTransition, clearAiCfoSidePanelHostPageContext, } = aiCfoView.actions;
|
|
375
456
|
export default aiCfoView.reducer;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { initialAiCfoState } from '../../entity/aiCfo/aiCfoReducer';
|
|
1
2
|
import { getAiCfoSelectorView, } from '../../entity/aiCfo/aiCfoSelector';
|
|
3
|
+
import { initialAiCfoViewState } from './aiCfoViewReducer';
|
|
2
4
|
export const getAiCfoView = (state) => {
|
|
3
|
-
const { fetchState, error, uiState, createSessionState, createSessionAndSubmitState, deleteChatSessionStateByChatSessionId, stopSubmitStateByChatSessionId, responseStateByChatSessionId, fetchChatSessionHistoryByChatSessionId, masterTOSAcceptanceState, } = state.aiCfoViewState;
|
|
5
|
+
const { fetchState, error, uiState, createSessionState, createSessionAndSubmitState, deleteChatSessionStateByChatSessionId, stopSubmitStateByChatSessionId, responseStateByChatSessionId, fetchChatSessionHistoryByChatSessionId, masterTOSAcceptanceState, suggestedQuestionsByPageContext, } = state.aiCfoViewState ?? initialAiCfoViewState;
|
|
4
6
|
return {
|
|
5
7
|
fetchState,
|
|
6
8
|
error,
|
|
@@ -12,7 +14,11 @@ export const getAiCfoView = (state) => {
|
|
|
12
14
|
uiState,
|
|
13
15
|
fetchChatSessionHistoryByChatSessionId,
|
|
14
16
|
masterTOSAcceptanceState,
|
|
15
|
-
|
|
17
|
+
suggestedQuestionsByPageContext,
|
|
18
|
+
...getAiCfoSelectorView(state.aiCfoState ?? initialAiCfoState),
|
|
16
19
|
version: 1,
|
|
17
20
|
};
|
|
18
21
|
};
|
|
22
|
+
export function getSuggestedQuestionsForPageContext(state, pageContext) {
|
|
23
|
+
return state.aiCfoViewState?.suggestedQuestionsByPageContext?.[pageContext];
|
|
24
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { of } from 'rxjs';
|
|
2
|
+
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
|
+
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
4
|
+
import { fetchSuggestedQuestions, fetchSuggestedQuestionsFailure, fetchSuggestedQuestionsSuccess, } from '../aiCfoViewReducer';
|
|
5
|
+
/** GET {aiCfoMicroServiceBaseUrl}/1.0/suggested-questions?page_context=... */
|
|
6
|
+
export const fetchSuggestedQuestionsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(fetchSuggestedQuestions.match),
|
|
7
|
+
// mergeMap (not switchMap): each page_context is keyed separately in Redux; switchMap
|
|
8
|
+
// would cancel in-flight HTTP for context A when B is requested, leaving A stuck In-Progress.
|
|
9
|
+
mergeMap((action) => {
|
|
10
|
+
const { pageContext } = action.payload;
|
|
11
|
+
const query = new URLSearchParams({ page_context: pageContext });
|
|
12
|
+
const url = `${zeniAPI.apiEndPoints.aiCfoMicroServiceBaseUrl}/1.0/suggested-questions?${query.toString()}`;
|
|
13
|
+
return zeniAPI.getJSON(url).pipe(mergeMap((response) => {
|
|
14
|
+
if (isSuccessResponse(response) && response.data != null) {
|
|
15
|
+
return of(fetchSuggestedQuestionsSuccess({
|
|
16
|
+
pageContext: response.data.page_context,
|
|
17
|
+
generatedAt: response.data.generated_at,
|
|
18
|
+
suggestedQuestions: response.data.suggested_questions,
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
return of(fetchSuggestedQuestionsFailure({
|
|
22
|
+
pageContext,
|
|
23
|
+
error: response.status,
|
|
24
|
+
}));
|
|
25
|
+
}), catchError((error) => of(fetchSuggestedQuestionsFailure({
|
|
26
|
+
pageContext,
|
|
27
|
+
error: createZeniAPIStatus('Unexpected Error', 'Fetch suggested questions REST API call failed', error instanceof Error ? { message: error.message } : undefined),
|
|
28
|
+
}))));
|
|
29
|
+
}));
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
2
|
+
import { catchError, filter, mergeMap, switchMap, withLatestFrom, } from 'rxjs/operators';
|
|
3
3
|
import { updateClasses } from '../../entity/class/classReducer';
|
|
4
|
+
import { getIsAccountingClassesEnabled } from '../../entity/tenant/tenantSelector';
|
|
4
5
|
import { createZeniAPIStatus, isSuccessResponse } from '../../responsePayload';
|
|
5
6
|
import { fetchClassList, updateClassList, updateClassListFailure, } from './classListReducer';
|
|
6
|
-
export const fetchClassListEpic = (actions$,
|
|
7
|
+
export const fetchClassListEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchClassList.match), withLatestFrom(state$), switchMap(([action, state]) => {
|
|
8
|
+
if (!getIsAccountingClassesEnabled(state)) {
|
|
9
|
+
return of(updateClassList({
|
|
10
|
+
status: createZeniAPIStatus('Success', ''),
|
|
11
|
+
data: { accounting_classes: [] },
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
7
14
|
const { isIncludeDeleted } = action.payload;
|
|
8
15
|
const queryParams = isIncludeDeleted === true
|
|
9
16
|
? `?query=${encodeURIComponent(JSON.stringify({ is_include_deleted: true }))}`
|
|
@@ -6,6 +6,7 @@ import { getContactsByIds } from '../../../entity/billPay/contact/contactSelecto
|
|
|
6
6
|
import { getClassById } from '../../../entity/class/classSelector';
|
|
7
7
|
import { getFilesByFileIds } from '../../../entity/file/fileSelector';
|
|
8
8
|
import { getPaymentInstrumentsByIds } from '../../../entity/paymentInstrument/paymentInstrumentSelector';
|
|
9
|
+
import { getIsAccountingClassesEnabled } from '../../../entity/tenant/tenantSelector';
|
|
9
10
|
import { getUserByUserId, getUsersByUserIds, } from '../../../entity/user/userSelector';
|
|
10
11
|
import { getVendorByVendorId } from '../../../entity/vendor/vendorSelector';
|
|
11
12
|
import { getAccountList, getNestedAccountListHierarchy, } from '../../accountList/accountListSelector';
|
|
@@ -60,13 +61,17 @@ export const getVendorView = (state, vendorIdFromUrl) => {
|
|
|
60
61
|
?.vendorDetailLocalData,
|
|
61
62
|
supportedCountries: billPayConfigState.vendor.supportedCountries,
|
|
62
63
|
};
|
|
63
|
-
|
|
64
|
+
const isAccountingClassesEnabled = getIsAccountingClassesEnabled(state);
|
|
65
|
+
const editFetchStateList = [
|
|
64
66
|
accountList,
|
|
65
|
-
classList,
|
|
66
67
|
vendorTypeListState,
|
|
67
68
|
vendorViewState.editVendorStateById[vendorIdFromUrl]?.fetchStatus ??
|
|
68
69
|
vendorViewInitialState.newVendorState.fetchStatus,
|
|
69
|
-
]
|
|
70
|
+
];
|
|
71
|
+
if (isAccountingClassesEnabled) {
|
|
72
|
+
editFetchStateList.push(classList);
|
|
73
|
+
}
|
|
74
|
+
fetchState = reduceFetchState(editFetchStateList);
|
|
70
75
|
}
|
|
71
76
|
else {
|
|
72
77
|
const basicVendorDetails = getBasicVendorDetailsForNewVendor(state, vendorViewState.newVendorState);
|
|
@@ -95,11 +100,17 @@ export const getVendorView = (state, vendorIdFromUrl) => {
|
|
|
95
100
|
if (tentativeName != null) {
|
|
96
101
|
entityRecommendations = getRecommendationsForEntity(state, tentativeName, 'vendor');
|
|
97
102
|
}
|
|
103
|
+
const isAccountingClassesEnabled = getIsAccountingClassesEnabled(state);
|
|
98
104
|
const fetchStateList = [
|
|
99
105
|
{ fetchState: accountList.fetchState, error: accountList.error },
|
|
100
|
-
{ fetchState: classList.fetchState, error: classList.error },
|
|
101
106
|
vendorTypeListState,
|
|
102
107
|
];
|
|
108
|
+
if (isAccountingClassesEnabled) {
|
|
109
|
+
fetchStateList.push({
|
|
110
|
+
fetchState: classList.fetchState,
|
|
111
|
+
error: classList.error,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
103
114
|
if (entityRecommendations != null &&
|
|
104
115
|
entityRecommendations.recommendations != null &&
|
|
105
116
|
entityRecommendations.recommendations.length > 0) {
|
|
@@ -144,6 +155,7 @@ export const getVendorView = (state, vendorIdFromUrl) => {
|
|
|
144
155
|
fetchState: fetchState.fetchState,
|
|
145
156
|
hasWireTransfer,
|
|
146
157
|
hasInternationalWireTransfer,
|
|
158
|
+
isAccountingClassesEnabled: getIsAccountingClassesEnabled(state),
|
|
147
159
|
deleteFileStatusById,
|
|
148
160
|
updateFileStatusById,
|
|
149
161
|
loggedInUserVerification,
|
|
@@ -219,9 +231,10 @@ const getBasicVendorDetailsForNewVendor = (state, newVendor) => {
|
|
|
219
231
|
};
|
|
220
232
|
export const getVendorDetailPageView = (state, vendorId, entity) => {
|
|
221
233
|
const trendWithTransactions = getTrendWithTransactions(state, entity, 'EntityDetail');
|
|
234
|
+
const isAccountingClassesEnabled = getIsAccountingClassesEnabled(state);
|
|
222
235
|
const reducedFetchState = reduceAnyFetchState([
|
|
223
236
|
state.accountListState.byReportId.accountList,
|
|
224
|
-
state.classListState,
|
|
237
|
+
...(isAccountingClassesEnabled ? [state.classListState] : []),
|
|
225
238
|
state.vendorTypeListState,
|
|
226
239
|
state.ownerListState,
|
|
227
240
|
state.vendorViewState.editVendorStateById[vendorId]?.fetchStatus ?? {
|
|
@@ -6,6 +6,7 @@ import { getAccountBase } from '../../../entity/account/accountSelector';
|
|
|
6
6
|
import { getAddressByAddressId } from '../../../entity/address/addressSelector';
|
|
7
7
|
import { getContactsByIds } from '../../../entity/billPay/contact/contactSelector';
|
|
8
8
|
import { getClassById } from '../../../entity/class/classSelector';
|
|
9
|
+
import { getIsAccountingClassesEnabled } from '../../../entity/tenant/tenantSelector';
|
|
9
10
|
import { getUserByUserId, getUsersByUserIds, } from '../../../entity/user/userSelector';
|
|
10
11
|
import { getVendorByVendorId } from '../../../entity/vendor/vendorSelector';
|
|
11
12
|
import { dateNow } from '../../../zeniDayJS';
|
|
@@ -20,6 +21,7 @@ const ALL_VENDOR_DETAIL_TABS_TYPES = [
|
|
|
20
21
|
export const toVendorDetailTabsType = (v) => stringToUnion(v, ALL_VENDOR_DETAIL_TABS_TYPES);
|
|
21
22
|
export const getVendorsTabVendorView = (state, vendorIdFromUrl) => {
|
|
22
23
|
const { accountListState, accountState, classListState, classState, vendorState, userState, vendorsTabVendorViewState, vendorTypeListState, addressState, addressViewState, contactState, } = state;
|
|
24
|
+
const isAccountingClassesEnabled = getIsAccountingClassesEnabled(state);
|
|
23
25
|
const accountList = getAccountList(accountState, accountListState, 'accountList');
|
|
24
26
|
const classList = getClassList(classState, classListState);
|
|
25
27
|
const ownerList = getUsersByUserIds(state.userState, state.ownerListState.ownerIds);
|
|
@@ -51,7 +53,7 @@ export const getVendorsTabVendorView = (state, vendorIdFromUrl) => {
|
|
|
51
53
|
}
|
|
52
54
|
fetchState = reduceFetchState([
|
|
53
55
|
accountList,
|
|
54
|
-
classList,
|
|
56
|
+
...(isAccountingClassesEnabled ? [classList] : []),
|
|
55
57
|
vendorTypeListState,
|
|
56
58
|
vendorsTabVendorViewState.vendorStateById[vendorIdFromUrl]?.fetchStatus ?? {
|
|
57
59
|
fetchState: 'Not-Started',
|
|
@@ -62,6 +64,7 @@ export const getVendorsTabVendorView = (state, vendorIdFromUrl) => {
|
|
|
62
64
|
return {
|
|
63
65
|
accountList: accountList,
|
|
64
66
|
classList: classList,
|
|
67
|
+
isAccountingClassesEnabled,
|
|
65
68
|
vendorTypeList: vendorTypeList,
|
|
66
69
|
accountsHierarchyList,
|
|
67
70
|
classHierarchyList,
|
|
@@ -102,9 +105,10 @@ export const getVendorsTabDetailPageView = (state, vendorId, entity) => {
|
|
|
102
105
|
? getTransactionListByEntityForSinglePeriod(state, entity, state.vendorsTabVendorViewState.allTransactionsTabData
|
|
103
106
|
.numberOfQuartersFetched)
|
|
104
107
|
: undefined;
|
|
108
|
+
const isAccountingClassesEnabled = getIsAccountingClassesEnabled(state);
|
|
105
109
|
const reducedFetchState = reduceAnyFetchState([
|
|
106
110
|
state.accountListState.byReportId.accountList,
|
|
107
|
-
state.classListState,
|
|
111
|
+
...(isAccountingClassesEnabled ? [state.classListState] : []),
|
|
108
112
|
state.ownerListState,
|
|
109
113
|
state.vendorTypeListState,
|
|
110
114
|
state.vendorsTabVendorViewState.vendorStateById[vendorId]?.fetchStatus ?? {
|
|
@@ -21,13 +21,13 @@ export const fetchJeSchedulesEpic = (actions$, state$, zeniAPI) => actions$.pipe
|
|
|
21
21
|
if (isSuccessResponse(response) && response.data != null) {
|
|
22
22
|
const updateActions = [];
|
|
23
23
|
updateActions.push(updateJESchedules([
|
|
24
|
-
...response.data.
|
|
24
|
+
...response.data.je_schedules,
|
|
25
25
|
...response.data.failed_je_postings.je_schedules,
|
|
26
26
|
]), updateJESchedulesDetails([...response.data.failed_je_postings.je_schedules], response.data.failed_je_postings.scheduled_journal_entries), initializeJeScheduleLocalData([
|
|
27
27
|
...response.data.failed_je_postings.je_schedules,
|
|
28
28
|
]));
|
|
29
29
|
updateActions.push(fetchJeSchedulesSuccess({
|
|
30
|
-
jeSchedules: [...response.data.
|
|
30
|
+
jeSchedules: [...response.data.je_schedules],
|
|
31
31
|
failedJeSchedules: [
|
|
32
32
|
...response.data.failed_je_postings.je_schedules,
|
|
33
33
|
],
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { concat, of, timer } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
2
|
+
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
3
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
4
4
|
import { BULK_UPLOAD_BAR_COMPLETE_HOLD_MS } from '../../bulkUploadTiming';
|
|
5
5
|
import { bulkUploadReceipts, bulkUploadReceiptsFailure, bulkUploadReceiptsSuccess, updateBulkUploadProgress, } from '../../reducers/missingReceiptsViewReducer';
|
|
6
|
-
export const bulkUploadReceiptsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(bulkUploadReceipts.match),
|
|
6
|
+
export const bulkUploadReceiptsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(bulkUploadReceipts.match), switchMap((action) => {
|
|
7
7
|
const { files } = action.payload;
|
|
8
8
|
const formData = new FormData();
|
|
9
9
|
for (const file of files) {
|
package/lib/esm/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js
CHANGED
|
@@ -25,7 +25,7 @@ export const pusherBatchStatusCompletionEpic = (actions$) => actions$.pipe(filte
|
|
|
25
25
|
* force `phase` to `completed` (dismiss automatching banner) and refresh the batch list.
|
|
26
26
|
* Cancels when the batch completes normally, bulk state is cleared, or another upload supersedes.
|
|
27
27
|
*/
|
|
28
|
-
export const bulkUploadAutomatchingTimeoutEpic = (actions$, state$) => actions$.pipe(filter(bulkUploadReceiptsSuccess.match),
|
|
28
|
+
export const bulkUploadAutomatchingTimeoutEpic = (actions$, state$) => actions$.pipe(filter(bulkUploadReceiptsSuccess.match), switchMap((action) => {
|
|
29
29
|
const { batchId } = action.payload;
|
|
30
30
|
return timer(BULK_UPLOAD_AUTOMATCHING_TIMEOUT_MS).pipe(mergeMap(() => {
|
|
31
31
|
const bulk = state$.value.expenseAutomationMissingReceiptsViewState.bulkUpload;
|
|
@@ -44,10 +44,11 @@ export const bulkUploadAutomatchingTimeoutEpic = (actions$, state$) => actions$.
|
|
|
44
44
|
* error snackbar per upload session (first failure only) so the user is not spammed every
|
|
45
45
|
* interval; Pusher or a later successful poll still completes the flow.
|
|
46
46
|
*/
|
|
47
|
-
export const pollBulkUploadBatchStatusEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(bulkUploadReceiptsSuccess.match),
|
|
47
|
+
export const pollBulkUploadBatchStatusEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(bulkUploadReceiptsSuccess.match), switchMap((action) => {
|
|
48
48
|
const { batchId } = action.payload;
|
|
49
49
|
let pollErrorNotified = false;
|
|
50
|
-
return timer(FALLBACK_FIRST_DELAY_MS, FALLBACK_POLL_INTERVAL_MS).pipe(takeUntil(merge(actions$.pipe(filter(clearBulkUpload.match)), actions$.pipe(filter(pusherBatchStatusUpdate.match), filter((action) => action.payload.batchId === batchId
|
|
50
|
+
return timer(FALLBACK_FIRST_DELAY_MS, FALLBACK_POLL_INTERVAL_MS).pipe(takeUntil(merge(actions$.pipe(filter(clearBulkUpload.match)), actions$.pipe(filter(pusherBatchStatusUpdate.match), filter((action) => action.payload.batchId === batchId &&
|
|
51
|
+
action.payload.status === 'completed')), actions$.pipe(filter(fetchBulkUploadBatchDetailsSuccess.match), filter((action) => action.payload.batchId === batchId)), actions$.pipe(filter(bulkUploadAutomatchingTimedOut.match), filter((action) => action.payload.batchId === batchId)))), switchMap(() => zeniAPI
|
|
51
52
|
.getJSON(`${zeniAPI.apiEndPoints.communicationAgentMicroServiceBaseUrl}/1.0/batches/${batchId}`)
|
|
52
53
|
.pipe(mergeMap((response) => {
|
|
53
54
|
/** Same batch-details URL; polls until `status` is completed (Pusher may win first). */
|
|
@@ -91,7 +91,6 @@ export function getExpenseAutomationView(state) {
|
|
|
91
91
|
const fetchStateVariables = [
|
|
92
92
|
expenseAutomationMissingReceiptsViewState,
|
|
93
93
|
expenseAutomationJESchedulesViewState,
|
|
94
|
-
monthEndCloseChecksView,
|
|
95
94
|
expenseAutomationTransactionsView,
|
|
96
95
|
expenseAutomationReconciliationViewState,
|
|
97
96
|
];
|
|
@@ -64,8 +64,8 @@ export const toTransactionUpdatesFromTransactionCategorizationLocalData = (trans
|
|
|
64
64
|
lineItem.account?.qboId !== accountLine.account.qboId &&
|
|
65
65
|
Boolean(lineItem.account?.qboId);
|
|
66
66
|
hasClassChanged =
|
|
67
|
-
|
|
68
|
-
lineItem.class?.qboId !== accountLine.class
|
|
67
|
+
(lineItem.class?.qboId != null || accountLine.class?.qboId != null) &&
|
|
68
|
+
lineItem.class?.qboId !== accountLine.class?.qboId;
|
|
69
69
|
const recommendedAccountBase = toRecommendedAccountBase(lineItem.amount.amount, lineItem.account);
|
|
70
70
|
const recommendedClassBase = toRecommendedClassBase(lineItem.amount.amount, lineItem.class);
|
|
71
71
|
if (entityDetails != null &&
|
package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js
CHANGED
|
@@ -234,7 +234,7 @@ const buildLineItemById = (transaction, uncategorizedIncomeExpense, recommendati
|
|
|
234
234
|
isPreFilled: true,
|
|
235
235
|
};
|
|
236
236
|
}
|
|
237
|
-
if (accountLine.class
|
|
237
|
+
if (Boolean(accountLine.class?.classId) === false &&
|
|
238
238
|
higherPreferenceRecommendation?.class != null) {
|
|
239
239
|
record.class = {
|
|
240
240
|
...higherPreferenceRecommendation.class,
|
|
@@ -464,7 +464,7 @@ export const setEntityRecommendationForLineIdInLocalData = (draft, transaction,
|
|
|
464
464
|
}
|
|
465
465
|
: accountLine.account;
|
|
466
466
|
record.class =
|
|
467
|
-
accountLine.class
|
|
467
|
+
Boolean(accountLine.class?.classId) !== false
|
|
468
468
|
? accountLine.class
|
|
469
469
|
: recommendations?.[0]?.class
|
|
470
470
|
? {
|
|
@@ -44,6 +44,8 @@ export const initialState = {
|
|
|
44
44
|
uiState: {
|
|
45
45
|
searchString: '',
|
|
46
46
|
scrollPosition: { scrollTop: 0, scrollLeft: undefined },
|
|
47
|
+
sortKey: 'startMonth',
|
|
48
|
+
sortOrder: 'descending',
|
|
47
49
|
totalCount: 0,
|
|
48
50
|
limit: 10,
|
|
49
51
|
},
|
|
@@ -365,12 +367,26 @@ const expenseAutomationJESchedulesView = createSlice({
|
|
|
365
367
|
clearJeAccountSettingsLocalData(draft) {
|
|
366
368
|
draft.accountSettings.localData = accountSettingsInitialState.localData;
|
|
367
369
|
},
|
|
370
|
+
updateJESchedulesUIState(draft, action) {
|
|
371
|
+
if (action.payload.sortKey != null) {
|
|
372
|
+
draft.uiState.sortKey = action.payload.sortKey;
|
|
373
|
+
}
|
|
374
|
+
if (action.payload.sortOrder != null) {
|
|
375
|
+
draft.uiState.sortOrder = action.payload.sortOrder;
|
|
376
|
+
}
|
|
377
|
+
if (action.payload.searchString != null) {
|
|
378
|
+
draft.uiState.searchString = action.payload.searchString;
|
|
379
|
+
}
|
|
380
|
+
if (action.payload.scrollPosition != null) {
|
|
381
|
+
draft.uiState.scrollPosition = action.payload.scrollPosition;
|
|
382
|
+
}
|
|
383
|
+
},
|
|
368
384
|
clearExpenseAutomationJESchedulesView(draft) {
|
|
369
385
|
Object.assign(draft, initialState);
|
|
370
386
|
},
|
|
371
387
|
},
|
|
372
388
|
});
|
|
373
|
-
export const { clearExpenseAutomationJESchedulesView, clearJeAccountSettingsLocalData, clearJeScheduleLocalData, fetchAccountSettingsListForAccountTypes, fetchJeSchedules, fetchJeSchedulesFailure, fetchJeSchedulesPage, fetchJeSchedulesSuccess, fetchRecommendationForAccountSettings, ignoreRecommendedJeSchedule, ignoreRecommendedJeScheduleFailure, ignoreRecommendedJeScheduleSuccess, initializeAccountSettingsView, initializeJeScheduleLocalData, removeFailedJeScheduleTransactionKey, removeJeScheduleLocalDataById, removeJeScheduleTransactionKey, retryJeSchedule, retryJeScheduleFailure, retryJeScheduleSuccess, saveAccountSettings, saveAccountSettingsFailure, saveAccountSettingsLocalData, saveAccountSettingsSuccess, updateAccountSettingsListForAccountTypes, updateAccountSettingsListForAccountTypesFailure, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys, updateRecommendationForAccountSettings, updateRecommendationForAccountSettingsFailure, } = expenseAutomationJESchedulesView.actions;
|
|
389
|
+
export const { clearExpenseAutomationJESchedulesView, clearJeAccountSettingsLocalData, clearJeScheduleLocalData, fetchAccountSettingsListForAccountTypes, fetchJeSchedules, fetchJeSchedulesFailure, fetchJeSchedulesPage, fetchJeSchedulesSuccess, fetchRecommendationForAccountSettings, ignoreRecommendedJeSchedule, ignoreRecommendedJeScheduleFailure, ignoreRecommendedJeScheduleSuccess, initializeAccountSettingsView, initializeJeScheduleLocalData, removeFailedJeScheduleTransactionKey, removeJeScheduleLocalDataById, removeJeScheduleTransactionKey, retryJeSchedule, retryJeScheduleFailure, retryJeScheduleSuccess, saveAccountSettings, saveAccountSettingsFailure, saveAccountSettingsLocalData, saveAccountSettingsSuccess, updateAccountSettingsListForAccountTypes, updateAccountSettingsListForAccountTypesFailure, updateJESchedulesUIState, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys, updateRecommendationForAccountSettings, updateRecommendationForAccountSettingsFailure, } = expenseAutomationJESchedulesView.actions;
|
|
374
390
|
export default expenseAutomationJESchedulesView.reducer;
|
|
375
391
|
const doUpdateRecommendationForAccountSettings = (draft, payload) => {
|
|
376
392
|
const { prepaidExpensesRecommendations, fixedAssetsRecommendations, accruedExpensesRecommendations, } = mapAccountTypeRecommendationPayloadToAccountRecommendationByType(payload);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { reduceAnyFetchState } from '../../../commonStateTypes/reduceFetchState';
|
|
1
2
|
import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
|
|
2
3
|
import { getAccountBase } from '../../../entity/account/accountSelector';
|
|
3
4
|
import { getClassById } from '../../../entity/class/classSelector';
|
|
@@ -6,7 +7,7 @@ import { getUserByUserId } from '../../../entity/user/userSelector';
|
|
|
6
7
|
import { getVendorByVendorId } from '../../../entity/vendor/vendorSelector';
|
|
7
8
|
import { getAllSteps } from '../selectorTypes/expenseAutomationViewSelectorTypes';
|
|
8
9
|
export function getExpenseAutomationFluxAnalysisView(state) {
|
|
9
|
-
const { expenseAutomationFluxAnalysisViewState, monthEndCloseChecksState } = state;
|
|
10
|
+
const { expenseAutomationFluxAnalysisViewState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
|
|
10
11
|
const { fetchState, error, refreshStatus, uiState, reviewOperatingExpenseIdsByPeriod, selectedSectionIdsByPeriod, groupsBySelectedPeriod, fluxAnalysisEntities, bulkReviewStatus, currency, totalBalancesAndVariance, } = expenseAutomationFluxAnalysisViewState;
|
|
11
12
|
const fetchStateAndError = {
|
|
12
13
|
fetchState,
|
|
@@ -91,10 +92,17 @@ export function getExpenseAutomationFluxAnalysisView(state) {
|
|
|
91
92
|
},
|
|
92
93
|
};
|
|
93
94
|
const completionStatus = fluxCompletionStatus != null ? fluxCompletionStatus : 'incomplete';
|
|
95
|
+
const monthEndFetchState = monthYearPeriodId != null
|
|
96
|
+
? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? { fetchState: 'Not-Started', error: undefined })
|
|
97
|
+
: { fetchState: 'Not-Started', error: undefined };
|
|
98
|
+
const reducedFetchStatus = reduceAnyFetchState([
|
|
99
|
+
fetchStateAndError,
|
|
100
|
+
monthEndFetchState,
|
|
101
|
+
]);
|
|
94
102
|
return {
|
|
95
103
|
sections,
|
|
96
104
|
totalBalancesAndVariance,
|
|
97
|
-
fetchStatus:
|
|
105
|
+
fetchStatus: reducedFetchStatus,
|
|
98
106
|
bulkReviewStatus,
|
|
99
107
|
reviewOperatingExpensesIds,
|
|
100
108
|
selectedSectionIds,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import omit from 'lodash/omit';
|
|
2
|
+
import orderBy from 'lodash/orderBy';
|
|
3
|
+
import { reduceAnyFetchState } from '../../../commonStateTypes/reduceFetchState';
|
|
2
4
|
import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
|
|
3
5
|
import { getAccountIdsForTypes } from '../../../entity/account/accountSelector';
|
|
4
6
|
import { getJEScheduledTransactionByJEScheduleTransactionKey, } from '../../../entity/jeSchedules/jeSchedulesSelector';
|
|
@@ -10,10 +12,48 @@ import { filterNestedAccountHierarchyById } from '../../scheduleView/scheduleDet
|
|
|
10
12
|
import { getAccountLabelForScheduleType, getAccountsTypesForScheduleList, } from '../../scheduleView/scheduleListView/scheduleListHelper';
|
|
11
13
|
import { getAllSteps } from '../selectorTypes/expenseAutomationViewSelectorTypes';
|
|
12
14
|
import { getJEAccountSettingsView } from './jeAccountSettingsViewSelector';
|
|
15
|
+
function getJEScheduleSortAccessor(sortKey) {
|
|
16
|
+
switch (sortKey) {
|
|
17
|
+
case 'vendor':
|
|
18
|
+
return (s) => s.vendor.name?.toLowerCase();
|
|
19
|
+
case 'category':
|
|
20
|
+
return (s) => s.jeDebit.account?.accountName?.toLowerCase();
|
|
21
|
+
case 'class':
|
|
22
|
+
return (s) => s.jeDebit.accountingClass?.className?.toLowerCase();
|
|
23
|
+
case 'depCategory':
|
|
24
|
+
return (s) => s.jeCredit.account?.accountName?.toLowerCase();
|
|
25
|
+
case 'scheduleCategory':
|
|
26
|
+
return (s) => s.jeScheduleType;
|
|
27
|
+
case 'startMonth':
|
|
28
|
+
return (s) => s.startDate?.valueOf();
|
|
29
|
+
case 'type':
|
|
30
|
+
return (s) => s.baseTransaction.typeOfTransaction;
|
|
31
|
+
case 'amortizationPeriod':
|
|
32
|
+
return (s) => s.period;
|
|
33
|
+
case 'jePostingDate':
|
|
34
|
+
return (s) => s.dayOfPostingDate;
|
|
35
|
+
case 'remainingMonths':
|
|
36
|
+
return (s) => s.period;
|
|
37
|
+
case 'runningBalance':
|
|
38
|
+
return (s) => s.balanceAsOfToday?.amount;
|
|
39
|
+
case 'totalAmount':
|
|
40
|
+
return (s) => s.baseTransaction.amount.amount;
|
|
41
|
+
case 'transactionDate':
|
|
42
|
+
return (s) => s.baseTransaction.date.valueOf();
|
|
43
|
+
case 'memo':
|
|
44
|
+
return (s) => s.baseTransaction.memo?.toLowerCase();
|
|
45
|
+
default:
|
|
46
|
+
return (s) => s.startDate?.valueOf();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function sortJEScheduledTransactions(transactions, sortKey, sortOrder) {
|
|
50
|
+
const accessor = getJEScheduleSortAccessor(sortKey);
|
|
51
|
+
return orderBy(transactions, [accessor], [sortOrder === 'ascending' ? 'asc' : 'desc']);
|
|
52
|
+
}
|
|
13
53
|
export function getExpenseAutomationJESchedulesView(state) {
|
|
14
54
|
const jeScheduledTransaction = [];
|
|
15
55
|
const failedJeScheduledTransaction = [];
|
|
16
|
-
const { accountState, accountListState, classState, classListState, expenseAutomationJESchedulesViewState, expenseAutomationViewState, monthEndCloseChecksState, } = state;
|
|
56
|
+
const { accountState, accountListState, classState, classListState, expenseAutomationJESchedulesViewState, expenseAutomationViewState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
|
|
17
57
|
const { jeScheduleTransactionKeysByPeriod, failedJeScheduleTransactionKeysByPeriod, jeScheduleLocalDataById, postStatusById, ignoreStatusById, uiState, error, fetchState, refreshStatus, } = expenseAutomationJESchedulesViewState;
|
|
18
58
|
const accountSettingsView = getJEAccountSettingsView(state);
|
|
19
59
|
const currentTenant = getCurrentTenant(state);
|
|
@@ -59,18 +99,33 @@ export function getExpenseAutomationJESchedulesView(state) {
|
|
|
59
99
|
const jeScheduleDetails = getJEScheduledTransactionByJEScheduleTransactionKey(jeScheduleKey, state);
|
|
60
100
|
failedJeScheduledTransaction.push(jeScheduleDetails);
|
|
61
101
|
});
|
|
62
|
-
const
|
|
63
|
-
const
|
|
102
|
+
const { sortKey, sortOrder } = uiState;
|
|
103
|
+
const draftSchedules = sortJEScheduledTransactions(jeScheduledTransaction.filter((schedule) => schedule.status.code === 'draft'), sortKey, sortOrder);
|
|
104
|
+
const ongoingSchedules = sortJEScheduledTransactions(jeScheduledTransaction.filter((schedule) => schedule.status.code === 'ongoing'), sortKey, sortOrder);
|
|
105
|
+
const completedSchedules = sortJEScheduledTransactions(jeScheduledTransaction.filter((schedule) => schedule.status.code === 'completed' ||
|
|
106
|
+
schedule.status.code === 'marked_as_completed'), sortKey, sortOrder);
|
|
107
|
+
const unsortedResolveSchedules = [];
|
|
64
108
|
failedJeScheduledTransaction.forEach((schedule) => {
|
|
65
109
|
schedule.scheduledJournalEntry.forEach((journalEntry) => {
|
|
66
|
-
|
|
110
|
+
unsortedResolveSchedules.push({
|
|
111
|
+
...schedule,
|
|
112
|
+
scheduledJournalEntry: journalEntry,
|
|
113
|
+
});
|
|
67
114
|
});
|
|
68
115
|
});
|
|
116
|
+
const resolveSchedules = sortJEScheduledTransactions(unsortedResolveSchedules, sortKey, sortOrder);
|
|
69
117
|
const allSteps = monthYearPeriodId != null
|
|
70
118
|
? getAllSteps(monthEndCloseChecksState, monthYearPeriodId, currentTenant.tenantId)
|
|
71
119
|
: [];
|
|
72
120
|
const jeCompletionStatus = allSteps.find((step) => step.step === 'je_schedules')?.completionStatus;
|
|
73
121
|
const completionStatus = jeCompletionStatus != null ? jeCompletionStatus : 'incomplete';
|
|
122
|
+
const monthEndFetchState = monthYearPeriodId != null
|
|
123
|
+
? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? { fetchState: 'Not-Started', error: undefined })
|
|
124
|
+
: { fetchState: 'Not-Started', error: undefined };
|
|
125
|
+
const reducedFetchStatus = reduceAnyFetchState([
|
|
126
|
+
{ fetchState, error },
|
|
127
|
+
monthEndFetchState,
|
|
128
|
+
]);
|
|
74
129
|
return {
|
|
75
130
|
uncategorizedAccounts,
|
|
76
131
|
allDepreciationAccountList: filteredDepAccounts,
|
|
@@ -79,15 +134,17 @@ export function getExpenseAutomationJESchedulesView(state) {
|
|
|
79
134
|
allAccountList: filteredAccounts,
|
|
80
135
|
accountListNestedAccountHierarchy,
|
|
81
136
|
allClassList: allClasses,
|
|
137
|
+
completedSchedules,
|
|
82
138
|
draftSchedules,
|
|
139
|
+
ongoingSchedules,
|
|
83
140
|
resolveSchedules: resolveSchedules,
|
|
84
141
|
accountSettingsView,
|
|
85
142
|
postStatusById: postStatusById,
|
|
86
143
|
ignoreStatusById: ignoreStatusById,
|
|
87
|
-
fetchState: fetchState,
|
|
144
|
+
fetchState: reducedFetchStatus.fetchState,
|
|
88
145
|
jeScheduleLocalDataById: jeScheduleLocalDataById,
|
|
89
146
|
uiState: uiState,
|
|
90
|
-
error: error,
|
|
147
|
+
error: reducedFetchStatus.error,
|
|
91
148
|
refreshStatus,
|
|
92
149
|
completionStatus,
|
|
93
150
|
};
|