@zeniai/client-epic-state 4.19.96-betaJK21 → 4.19.96-betaJK4

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.
Files changed (123) hide show
  1. package/lib/commonStateTypes/animations.d.ts +1 -1
  2. package/lib/entity/accountRecon/accountReconState.d.ts +1 -1
  3. package/lib/entity/accountRecon/accountReconState.js +0 -1
  4. package/lib/entity/aiCfo/aiCfoSelector.d.ts +1 -2
  5. package/lib/entity/billPay/billTransaction/billTransactionState.d.ts +2 -2
  6. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +35 -0
  7. package/lib/entity/jeSchedules/jeSchedulesPayload.js +44 -0
  8. package/lib/entity/jeSchedules/jeSchedulesSelector.d.ts +2 -1
  9. package/lib/entity/jeSchedules/jeSchedulesSelector.js +2 -1
  10. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +13 -0
  11. package/lib/entity/tenant/tenantPayload.d.ts +1 -0
  12. package/lib/entity/tenant/tenantReducer.js +1 -0
  13. package/lib/entity/tenant/tenantSelector.d.ts +1 -0
  14. package/lib/entity/tenant/tenantSelector.js +9 -1
  15. package/lib/entity/tenant/tenantState.d.ts +1 -0
  16. package/lib/entity/transaction/payloadTypes/transactionPayload.d.ts +3 -0
  17. package/lib/entity/transaction/payloadTypes/transactionPayload.js +11 -0
  18. package/lib/entity/transaction/stateTypes/transaction.d.ts +3 -0
  19. package/lib/entity/transaction/stateTypes/transactionLine.d.ts +1 -1
  20. package/lib/epic.d.ts +3 -1
  21. package/lib/epic.js +3 -1
  22. package/lib/esm/entity/accountRecon/accountReconState.js +0 -1
  23. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +44 -0
  24. package/lib/esm/entity/jeSchedules/jeSchedulesSelector.js +2 -1
  25. package/lib/esm/entity/tenant/tenantReducer.js +1 -0
  26. package/lib/esm/entity/tenant/tenantSelector.js +7 -0
  27. package/lib/esm/entity/transaction/payloadTypes/transactionPayload.js +11 -0
  28. package/lib/esm/epic.js +3 -1
  29. package/lib/esm/index.js +9 -7
  30. package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +82 -1
  31. package/lib/esm/view/aiCfoView/aiCfoViewSelector.js +8 -2
  32. package/lib/esm/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.js +29 -0
  33. package/lib/esm/view/classList/fetchClassListEpic.js +9 -2
  34. package/lib/esm/view/commonVendorView/vendorView/vendorViewSelector.js +15 -5
  35. package/lib/esm/view/commonVendorView/vendorsTabVendorView/vendorsTabVendorViewSelector.js +6 -2
  36. package/lib/esm/view/expenseAutomationView/epics/accountRecon/fetchReconExcludedAccountsEpic.js +27 -0
  37. package/lib/esm/view/expenseAutomationView/epics/accountRecon/fetchReconciliationViewEpic.js +0 -2
  38. package/lib/esm/view/expenseAutomationView/epics/accountRecon/initialiseLocalDataForSelectedAccountIdEpic.js +0 -1
  39. package/lib/esm/view/expenseAutomationView/epics/accountRecon/saveReconciliationReviewEpic.js +2 -29
  40. package/lib/esm/view/expenseAutomationView/epics/accountRecon/uploadAccountStatementDocumentAIHelper.js +1 -2
  41. package/lib/esm/view/expenseAutomationView/helpers/saveTransactionHelper.js +2 -2
  42. package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +2 -2
  43. package/lib/esm/view/expenseAutomationView/payload/reconciliationPayload.js +18 -0
  44. package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +17 -1
  45. package/lib/esm/view/expenseAutomationView/reducers/reconciliationViewReducer.js +39 -1
  46. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +50 -3
  47. package/lib/esm/view/expenseAutomationView/selectors/missingReceiptsSelector.js +1 -1
  48. package/lib/esm/view/expenseAutomationView/selectors/reconciliationViewSelector.js +152 -0
  49. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +17 -1
  50. package/lib/esm/view/spendManagement/billPay/billList/billListSelector.js +10 -0
  51. package/lib/esm/view/spendManagement/billPay/billList/billListState.js +1 -0
  52. package/lib/esm/view/spendManagement/billPay/billPayReview/billPayReviewSelector.js +7 -3
  53. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewSelector.js +5 -5
  54. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPayApproversDetailsEpic.js +7 -2
  55. package/lib/esm/view/spendManagement/billPay/editBillView/editBillViewSelector.js +13 -6
  56. package/lib/esm/view/spendManagement/chargeCards/chargeCardList/chargeCardList.js +1 -0
  57. package/lib/esm/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.js +2 -0
  58. package/lib/esm/view/spendManagement/reimbursement/editRemiView/editRemiViewSelector.js +7 -4
  59. package/lib/esm/view/spendManagement/reimbursement/remiListView/remiListSelector.js +12 -0
  60. package/lib/esm/view/spendManagement/reimbursement/remiListView/remiListState.js +1 -0
  61. package/lib/esm/view/taskManager/taskDetailView/taskDetailSelector.js +2 -2
  62. package/lib/esm/view/transactionDetail/epics/saveTransactionHelper.js +2 -2
  63. package/lib/esm/view/transactionDetail/transactionDetailLocalDataHelper.js +16 -14
  64. package/lib/index.d.ts +14 -10
  65. package/lib/index.js +44 -32
  66. package/lib/view/aiCfoView/aiCfoViewPayload.d.ts +7 -0
  67. package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +15 -1
  68. package/lib/view/aiCfoView/aiCfoViewReducer.js +83 -2
  69. package/lib/view/aiCfoView/aiCfoViewSelector.d.ts +4 -1
  70. package/lib/view/aiCfoView/aiCfoViewSelector.js +9 -2
  71. package/lib/view/aiCfoView/aiCfoViewState.d.ts +18 -1
  72. package/lib/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.d.ts +8 -0
  73. package/lib/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.js +33 -0
  74. package/lib/view/auditReportView/auditReportViewState.d.ts +1 -1
  75. package/lib/view/classList/fetchClassListEpic.d.ts +1 -1
  76. package/lib/view/classList/fetchClassListEpic.js +8 -1
  77. package/lib/view/commonVendorView/vendorView/vendorViewSelector.d.ts +1 -0
  78. package/lib/view/commonVendorView/vendorView/vendorViewSelector.js +15 -5
  79. package/lib/view/commonVendorView/vendorsTabVendorView/vendorsTabVendorViewSelector.d.ts +1 -0
  80. package/lib/view/commonVendorView/vendorsTabVendorView/vendorsTabVendorViewSelector.js +6 -2
  81. package/lib/view/expenseAutomationView/epics/accountRecon/fetchReconExcludedAccountsEpic.d.ts +7 -0
  82. package/lib/view/expenseAutomationView/epics/accountRecon/fetchReconExcludedAccountsEpic.js +31 -0
  83. package/lib/view/expenseAutomationView/epics/accountRecon/fetchReconciliationViewEpic.js +0 -2
  84. package/lib/view/expenseAutomationView/epics/accountRecon/initialiseLocalDataForSelectedAccountIdEpic.js +0 -1
  85. package/lib/view/expenseAutomationView/epics/accountRecon/saveReconciliationReviewEpic.js +2 -29
  86. package/lib/view/expenseAutomationView/epics/accountRecon/uploadAccountStatementDocumentAIHelper.d.ts +1 -1
  87. package/lib/view/expenseAutomationView/epics/accountRecon/uploadAccountStatementDocumentAIHelper.js +1 -2
  88. package/lib/view/expenseAutomationView/helpers/saveTransactionHelper.js +2 -2
  89. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +2 -2
  90. package/lib/view/expenseAutomationView/payload/reconciliationPayload.d.ts +23 -1
  91. package/lib/view/expenseAutomationView/payload/reconciliationPayload.js +20 -0
  92. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +2 -2
  93. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +18 -2
  94. package/lib/view/expenseAutomationView/reducers/reconciliationViewReducer.d.ts +9 -2
  95. package/lib/view/expenseAutomationView/reducers/reconciliationViewReducer.js +40 -2
  96. package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +2 -0
  97. package/lib/view/expenseAutomationView/selectorTypes/reconciliationViewSelectorTypes.d.ts +1 -0
  98. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +50 -3
  99. package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.js +1 -1
  100. package/lib/view/expenseAutomationView/selectors/reconciliationViewSelector.js +152 -0
  101. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +5 -0
  102. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +19 -0
  103. package/lib/view/expenseAutomationView/types/reconciliationViewState.d.ts +20 -4
  104. package/lib/view/scheduleView/scheduleListView/scheduleListTypes.d.ts +1 -1
  105. package/lib/view/spendManagement/billPay/billList/billListSelector.js +10 -0
  106. package/lib/view/spendManagement/billPay/billList/billListState.d.ts +1 -1
  107. package/lib/view/spendManagement/billPay/billList/billListState.js +1 -0
  108. package/lib/view/spendManagement/billPay/billPayReview/billPayReviewSelector.js +7 -3
  109. package/lib/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewSelector.js +5 -5
  110. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPayApproversDetailsEpic.js +7 -2
  111. package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.js +13 -6
  112. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.d.ts +1 -1
  113. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.js +1 -0
  114. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.js +2 -0
  115. package/lib/view/spendManagement/reimbursement/editRemiView/editRemiViewSelector.js +6 -3
  116. package/lib/view/spendManagement/reimbursement/remiListView/remiListSelector.d.ts +1 -0
  117. package/lib/view/spendManagement/reimbursement/remiListView/remiListSelector.js +12 -0
  118. package/lib/view/spendManagement/reimbursement/remiListView/remiListState.d.ts +1 -1
  119. package/lib/view/spendManagement/reimbursement/remiListView/remiListState.js +1 -0
  120. package/lib/view/taskManager/taskDetailView/taskDetailSelector.js +2 -2
  121. package/lib/view/transactionDetail/epics/saveTransactionHelper.js +2 -2
  122. package/lib/view/transactionDetail/transactionDetailLocalDataHelper.js +16 -14
  123. 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
- ...getAiCfoSelectorView(state.aiCfoState),
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$, _state$, zeniAPI) => actions$.pipe(filter(fetchClassList.match), switchMap((action) => {
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 }))}`
@@ -1,4 +1,5 @@
1
1
  import { reduceAnyFetchState, reduceFetchState, } from '../../../commonStateTypes/reduceFetchState';
2
+ import { getIsAccountingClassesEnabled } from '../../../entity/tenant/tenantSelector';
2
3
  import { getAccountBase } from '../../../entity/account/accountSelector';
3
4
  import { getAddressByAddressId } from '../../../entity/address/addressSelector';
4
5
  import { getBankAccountsByBankAccountIds } from '../../../entity/bankAccount/bankAccountSelector';
@@ -60,13 +61,17 @@ export const getVendorView = (state, vendorIdFromUrl) => {
60
61
  ?.vendorDetailLocalData,
61
62
  supportedCountries: billPayConfigState.vendor.supportedCountries,
62
63
  };
63
- fetchState = reduceFetchState([
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,14 @@ 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({ fetchState: classList.fetchState, error: classList.error });
110
+ }
103
111
  if (entityRecommendations != null &&
104
112
  entityRecommendations.recommendations != null &&
105
113
  entityRecommendations.recommendations.length > 0) {
@@ -144,6 +152,7 @@ export const getVendorView = (state, vendorIdFromUrl) => {
144
152
  fetchState: fetchState.fetchState,
145
153
  hasWireTransfer,
146
154
  hasInternationalWireTransfer,
155
+ isAccountingClassesEnabled: getIsAccountingClassesEnabled(state),
147
156
  deleteFileStatusById,
148
157
  updateFileStatusById,
149
158
  loggedInUserVerification,
@@ -219,9 +228,10 @@ const getBasicVendorDetailsForNewVendor = (state, newVendor) => {
219
228
  };
220
229
  export const getVendorDetailPageView = (state, vendorId, entity) => {
221
230
  const trendWithTransactions = getTrendWithTransactions(state, entity, 'EntityDetail');
231
+ const isAccountingClassesEnabled = getIsAccountingClassesEnabled(state);
222
232
  const reducedFetchState = reduceAnyFetchState([
223
233
  state.accountListState.byReportId.accountList,
224
- state.classListState,
234
+ ...(isAccountingClassesEnabled ? [state.classListState] : []),
225
235
  state.vendorTypeListState,
226
236
  state.ownerListState,
227
237
  state.vendorViewState.editVendorStateById[vendorId]?.fetchStatus ?? {
@@ -3,6 +3,7 @@ import { getStartOfAndEndOfTimeframeForFY } from '../../../commonStateTypes/fisc
3
3
  import { reduceAnyFetchState, reduceFetchState, } from '../../../commonStateTypes/reduceFetchState';
4
4
  import { stringToUnion } from '../../../commonStateTypes/stringToUnion';
5
5
  import { getAccountBase } from '../../../entity/account/accountSelector';
6
+ import { getIsAccountingClassesEnabled } from '../../../entity/tenant/tenantSelector';
6
7
  import { getAddressByAddressId } from '../../../entity/address/addressSelector';
7
8
  import { getContactsByIds } from '../../../entity/billPay/contact/contactSelector';
8
9
  import { getClassById } from '../../../entity/class/classSelector';
@@ -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 ?? {
@@ -0,0 +1,27 @@
1
+ import { of } from 'rxjs';
2
+ import { catchError, filter, mergeMap } from 'rxjs/operators';
3
+ import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
4
+ import { fetchReconExcludedAccounts, fetchReconExcludedAccountsFailure, fetchReconExcludedAccountsSuccess, } from '../../reducers/reconciliationViewReducer';
5
+ export const fetchReconExcludedAccountsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(fetchReconExcludedAccounts.match), mergeMap((action) => {
6
+ const { accountId, exclusionReason } = action.payload;
7
+ const requestPayload = {
8
+ account_id: accountId,
9
+ exclusion_reason: exclusionReason,
10
+ };
11
+ return zeniAPI
12
+ .postAndGetJSON(`${zeniAPI.apiEndPoints.reconciliationMicroServiceBaseUrl}/1.0/reconciliation/excluded-accounts`, requestPayload)
13
+ .pipe(mergeMap((response) => {
14
+ if (isSuccessResponse(response) && response.data != null) {
15
+ return of(fetchReconExcludedAccountsSuccess({
16
+ excludedAccounts: response.data.excluded_account,
17
+ }));
18
+ }
19
+ else {
20
+ return of(fetchReconExcludedAccountsFailure({
21
+ error: response.status,
22
+ }));
23
+ }
24
+ }), catchError((error) => of(fetchReconExcludedAccountsFailure({
25
+ error: createZeniAPIStatus('Unexpected Error', `fetch excluded accounts REST API call errored out ${JSON.stringify(error)}`),
26
+ }))));
27
+ }));
@@ -2,7 +2,6 @@ import { from, of } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { convertToPeriod, toMonthYearPeriodId, } from '../../../../commonStateTypes/timePeriod';
4
4
  import { updateAccounts } from '../../../../entity/account/accountReducer';
5
- import { toRecommendedActionCodeType } from '../../../../entity/accountRecon/accountReconState';
6
5
  import { updateAccountRecon } from '../../../../entity/accountRecon/accountReconReducer';
7
6
  import { getAccountReconByAccountIdAndSelectedPeriod } from '../../../../entity/accountRecon/accountReconSelector';
8
7
  import { updateFiles } from '../../../../entity/file/fileReducer';
@@ -122,7 +121,6 @@ export const prepareReviewTabLocalData = (transactionsToReview) => {
122
121
  .recommended_transactions[0].merchant_name,
123
122
  }
124
123
  : undefined,
125
- recommendedActionType: toRecommendedActionCodeType(currentTransaction.recommended_action.recommended_actions),
126
124
  };
127
125
  return {
128
126
  ...prev,
@@ -45,7 +45,6 @@ export const prepareReviewTabLocalData = (transactionsToReview) => {
45
45
  .recommendedTransactions[0].merchantName,
46
46
  }
47
47
  : undefined,
48
- recommendedActionType: currentTransaction.recommendedAction.action,
49
48
  };
50
49
  return {
51
50
  ...prev,
@@ -30,10 +30,8 @@ export const saveReconciliationReviewEpic = (actions$, state$, zeniAPI) => actio
30
30
  reconciliationId = reconciliationData?.reconciliationId;
31
31
  updatedTransaction = reconciliationData?.transactionsToReview.find((transaction) => transaction.transactionId === transactionId);
32
32
  }
33
- const reviewAction = localData?.recommendedActionType ??
34
- updatedTransaction?.recommendedAction.action;
35
33
  const queryParam = {
36
- review_action: reviewAction,
34
+ review_action: updatedTransaction?.recommendedAction.action,
37
35
  reconciliation_id: reconciliationId ?? '',
38
36
  ref_account_id: selectedAccountId,
39
37
  ref_account_name: reconciliationData?.account.accountName,
@@ -43,7 +41,7 @@ export const saveReconciliationReviewEpic = (actions$, state$, zeniAPI) => actio
43
41
  if (reconciliationData != null &&
44
42
  updatedTransaction != null &&
45
43
  localData != null) {
46
- switch (reviewAction) {
44
+ switch (updatedTransaction.recommendedAction.action) {
47
45
  case 'record_expense':
48
46
  payload = getPayloadForExpenseRecord(updatedTransaction, localData);
49
47
  break;
@@ -65,9 +63,6 @@ export const saveReconciliationReviewEpic = (actions$, state$, zeniAPI) => actio
65
63
  case 'record_deposit':
66
64
  payload = getPayloadForDeposit(updatedTransaction, localData, entityState);
67
65
  break;
68
- case 'record_journal_entry':
69
- payload = getPayloadForJournalEntry(updatedTransaction, localData);
70
- break;
71
66
  }
72
67
  }
73
68
  payload = {
@@ -225,28 +220,6 @@ const getPayloadForBillPayment = (updatedTransaction, linkedTransaction, localDa
225
220
  vendor_name: linkedTransaction?.merchantName,
226
221
  };
227
222
  };
228
- function getPayloadForJournalEntry(updatedTransaction, localData) {
229
- return {
230
- transaction_id: updatedTransaction.transactionId,
231
- transaction_date: updatedTransaction.transactionDate.format(DEFAULT_DATE_FORMAT),
232
- transaction_memo: updatedTransaction.memo,
233
- amount: updatedTransaction.amount.amount,
234
- currency_code: updatedTransaction.amount.currencyCode,
235
- transaction_direction: updatedTransaction.transactionDirection,
236
- lines: [
237
- {
238
- class_id: localData.jeDebitClassId,
239
- posting_type: 'Debit',
240
- amount: updatedTransaction.amount.amount,
241
- },
242
- {
243
- class_id: localData.jeCreditClassId,
244
- posting_type: 'Credit',
245
- amount: updatedTransaction.amount.amount,
246
- },
247
- ],
248
- };
249
- }
250
223
  const getToastMessageSection = (updatedTransaction) => {
251
224
  if (updatedTransaction?.recommendedAction.action === 'record_bill_payment') {
252
225
  return 'recon_transaction_match';
@@ -1,6 +1,6 @@
1
1
  import fetch from 'cross-fetch';
2
2
  import { zeniAPI } from '../../../../init';
3
- export default async function uploadAccountStatementIntoDocumentAI(accountType, fileBlob, authParams, accountName) {
3
+ export default async function uploadAccountStatementIntoDocumentAI(accountType, fileBlob, authParams) {
4
4
  let statementUpload;
5
5
  const urlEndPoint = `${zeniAPI.apiEndPoints.documentAIMicroServiceBaseUrl}/1.0/processors/statement`;
6
6
  const data = new FormData();
@@ -10,7 +10,6 @@ export default async function uploadAccountStatementIntoDocumentAI(accountType,
10
10
  ? 'reconciliation_card_statement_upload'
11
11
  : 'reconciliation_bank_statement_upload',
12
12
  purpose_id: 'reconciliation',
13
- ...(accountName != null && { account_name: accountName }),
14
13
  });
15
14
  data.append('attachment_json_0', attachment_json);
16
15
  try {
@@ -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
- Boolean(lineItem.class?.qboId) &&
68
- lineItem.class?.qboId !== accountLine.class.qboId;
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 &&
@@ -234,7 +234,7 @@ const buildLineItemById = (transaction, uncategorizedIncomeExpense, recommendati
234
234
  isPreFilled: true,
235
235
  };
236
236
  }
237
- if (accountLine.class.classId === '' &&
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.classId !== ''
467
+ Boolean(accountLine.class?.classId) !== false
468
468
  ? accountLine.class
469
469
  : recommendations?.[0]?.class
470
470
  ? {
@@ -1,6 +1,7 @@
1
1
  import { convertToPeriod, } from '../../../commonStateTypes/timePeriod';
2
2
  import { toTransactionsToReviewPayload, } from '../../../entity/accountRecon/accountReconPayload';
3
3
  import { toMatchedTransactionPayload, } from '../../../entity/transaction/payloadTypes/reconciliationTransactionPayloads';
4
+ import { date } from '../../../zeniDayJS';
4
5
  export function createSaveReconciliationPayloadBasedOnActionAndMethod(state, selectedPeriod, localData, accountReconciliationEntity, action, method) {
5
6
  const { balance, initialClearedBalance } = accountReconciliationEntity;
6
7
  const { expenseAutomationReconciliationViewState: { selectedAccountId, reconTabsState: { reconcile: { localData: { selectedTransactionIds }, }, }, }, } = state;
@@ -67,3 +68,20 @@ function createReviewTransactionPayload(accountReconciliationEntity) {
67
68
  });
68
69
  return reviewTransactionsPayload;
69
70
  }
71
+ export const toExcludedAccount = (payload) => {
72
+ return {
73
+ accountId: payload.account_id,
74
+ createTime: date(payload.create_time),
75
+ detectionSignals: payload.detection_signals,
76
+ excludedAccountId: payload.excluded_account_id,
77
+ excludedByUserId: payload.excluded_by_user_id,
78
+ exclusionHistory: payload.exclusion_history.map((entry) => ({
79
+ action: entry.action,
80
+ at: entry.at,
81
+ by: entry.by,
82
+ reason: entry.reason,
83
+ })),
84
+ isDeleted: payload.is_deleted,
85
+ updateTime: date(payload.update_time),
86
+ };
87
+ };
@@ -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);
@@ -2,6 +2,7 @@ import { createSlice } from '@reduxjs/toolkit';
2
2
  import { toMonthYearPeriodId, } from '../../../commonStateTypes/timePeriod';
3
3
  import { toReconciliationAccountSource } from '../../../entity/account/accountState';
4
4
  import { toBankStatusCodeType } from '../../../entity/accountRecon/accountReconState';
5
+ import { toExcludedAccount, } from '../payload/reconciliationPayload';
5
6
  // Initial state
6
7
  export const initialReconciliationTabsState = {
7
8
  balances: {
@@ -51,6 +52,8 @@ export const initialActionFetchState = {
51
52
  export const initialState = {
52
53
  accountReconciliationRecordsBySelectedPeriod: {},
53
54
  accountConnectionStatusByAccountID: {},
55
+ excludedAccounts: [],
56
+ excludedAccountsFetchState: { fetchState: 'Not-Started', error: undefined },
54
57
  fetchState: 'Not-Started',
55
58
  error: undefined,
56
59
  selectedTab: 'review',
@@ -424,13 +427,48 @@ const expenseAutomationReconciliationView = createSlice({
424
427
  updateStatementUploadChosen: (draft, action) => {
425
428
  draft.statementUploadChosen = action.payload.statementUploadChosen;
426
429
  },
430
+ fetchReconExcludedAccounts: {
431
+ reducer(draft) {
432
+ draft.excludedAccountsFetchState = {
433
+ fetchState: 'In-Progress',
434
+ error: undefined,
435
+ };
436
+ },
437
+ prepare(accountId, exclusionReason) {
438
+ return {
439
+ payload: { accountId, exclusionReason },
440
+ };
441
+ },
442
+ },
443
+ fetchReconExcludedAccountsSuccess: (draft, action) => {
444
+ draft.excludedAccountsFetchState = {
445
+ fetchState: 'Completed',
446
+ error: undefined,
447
+ };
448
+ action.payload.excludedAccounts.forEach((excludedAccount) => {
449
+ const existingIndex = draft.excludedAccounts.findIndex((account) => account.excludedAccountId === excludedAccount.excluded_account_id);
450
+ if (existingIndex >= 0) {
451
+ draft.excludedAccounts[existingIndex] =
452
+ toExcludedAccount(excludedAccount);
453
+ }
454
+ else {
455
+ draft.excludedAccounts.push(toExcludedAccount(excludedAccount));
456
+ }
457
+ });
458
+ },
459
+ fetchReconExcludedAccountsFailure: (draft, action) => {
460
+ draft.excludedAccountsFetchState = {
461
+ fetchState: 'Error',
462
+ error: action.payload.error,
463
+ };
464
+ },
427
465
  clearExpenseAutomationReconciliationView: (draft) => {
428
466
  Object.assign(draft, initialState);
429
467
  },
430
468
  },
431
469
  });
432
470
  // Export actions
433
- export const { fetchReconciliation, fetchReconciliationFailure, fetchReconciliationSuccess, saveReconciliationDetail, saveReconciliationDetailFailure, updateSelectedAccountId, setConnectionInProgressForAccount, setStatementParseInProgress, updateReconcileTabLocalData, updateReconcileTabListSortState, updateReconcileTabListScrollState, saveReconciliationDetailSuccess, updateSelectedTab, updateBalancesLocalData, initialiseLocalDataForSelectedAccountId, clearExpenseAutomationReconciliationView, updateSelectedDrawerAccountId, updateReviewTabSortState, initializeReconciliationReviewTabLocalData, updateReviewTabLocalData, saveReconciliationReview, updateSaveReconciliationReviewFetchStatus, updateReconListScrollPosition, updateAccountReconciliationLocalData, deleteAccountStatement, deleteAccountStatementSuccess, deleteAccountStatementFailure, uploadAccountStatement, uploadAccountStatementSuccess, uploadAccountStatementFailure, updateStatementUploadChosen, } = expenseAutomationReconciliationView.actions;
471
+ export const { fetchReconciliation, fetchReconciliationFailure, fetchReconciliationSuccess, saveReconciliationDetail, saveReconciliationDetailFailure, updateSelectedAccountId, setConnectionInProgressForAccount, setStatementParseInProgress, updateReconcileTabLocalData, updateReconcileTabListSortState, updateReconcileTabListScrollState, saveReconciliationDetailSuccess, updateSelectedTab, updateBalancesLocalData, initialiseLocalDataForSelectedAccountId, clearExpenseAutomationReconciliationView, updateSelectedDrawerAccountId, updateReviewTabSortState, initializeReconciliationReviewTabLocalData, updateReviewTabLocalData, saveReconciliationReview, updateSaveReconciliationReviewFetchStatus, updateReconListScrollPosition, updateAccountReconciliationLocalData, deleteAccountStatement, deleteAccountStatementSuccess, deleteAccountStatementFailure, uploadAccountStatement, uploadAccountStatementSuccess, uploadAccountStatementFailure, updateStatementUploadChosen, fetchReconExcludedAccounts, fetchReconExcludedAccountsSuccess, fetchReconExcludedAccountsFailure, } = expenseAutomationReconciliationView.actions;
434
472
  // Export reducer
435
473
  export default expenseAutomationReconciliationView.reducer;
436
474
  function updateAllReconciliation(draft, accounts, selectedPeriod, reconciliationData, refreshViewInBackground) {