@zeniai/client-epic-state 5.2.34 → 5.2.35-beta0MM

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 (94) hide show
  1. package/lib/entity/actualMatching/actualMatchingPayload.d.ts +25 -0
  2. package/lib/entity/actualMatching/actualMatchingPayload.js +43 -0
  3. package/lib/entity/actualMatching/actualMatchingReducer.d.ts +8 -0
  4. package/lib/entity/actualMatching/actualMatchingReducer.js +33 -0
  5. package/lib/entity/actualMatching/actualMatchingSelector.d.ts +3 -0
  6. package/lib/entity/actualMatching/actualMatchingSelector.js +6 -0
  7. package/lib/entity/actualMatching/actualMatchingState.d.ts +22 -0
  8. package/lib/entity/actualMatching/actualMatchingState.js +2 -0
  9. package/lib/entity/actualMatching/actualMatchingTypes.d.ts +1 -0
  10. package/lib/entity/actualMatching/actualMatchingTypes.js +2 -0
  11. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +29 -0
  12. package/lib/entity/jeSchedules/jeSchedulesPayload.js +49 -0
  13. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +31 -0
  14. package/lib/epic.d.ts +8 -1
  15. package/lib/epic.js +14 -0
  16. package/lib/esm/entity/actualMatching/actualMatchingPayload.js +40 -0
  17. package/lib/esm/entity/actualMatching/actualMatchingReducer.js +30 -0
  18. package/lib/esm/entity/actualMatching/actualMatchingSelector.js +3 -0
  19. package/lib/esm/entity/actualMatching/actualMatchingState.js +1 -0
  20. package/lib/esm/entity/actualMatching/actualMatchingTypes.js +1 -0
  21. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +49 -0
  22. package/lib/esm/epic.js +14 -0
  23. package/lib/esm/index.js +6 -2
  24. package/lib/esm/reducer.js +6 -0
  25. package/lib/esm/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingEpic.js +46 -0
  26. package/lib/esm/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingMatchEpic.js +35 -0
  27. package/lib/esm/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingPageEpic.js +7 -0
  28. package/lib/esm/view/expenseAutomationView/epics/actualMatching/matchAndReverseAccrualsEpic.js +52 -0
  29. package/lib/esm/view/expenseAutomationView/epics/actualMatching/searchMatchAccrualsEpic.js +44 -0
  30. package/lib/esm/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.js +73 -0
  31. package/lib/esm/view/expenseAutomationView/epics/actualMatching/undoReversalAccrualsEpic.js +52 -0
  32. package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +28 -11
  33. package/lib/esm/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.js +9 -1
  34. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/prefetchOtherJeSchedulesTabEpic.js +3 -1
  35. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +5 -0
  36. package/lib/esm/view/expenseAutomationView/expenseAutomationViewSelector.js +22 -7
  37. package/lib/esm/view/expenseAutomationView/payload/actualMatchingPayload.js +68 -0
  38. package/lib/esm/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +364 -0
  39. package/lib/esm/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.js +1 -0
  40. package/lib/esm/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +281 -0
  41. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +3 -0
  42. package/lib/esm/view/expenseAutomationView/types/actualMatchingViewState.js +32 -0
  43. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +5 -1
  44. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewPayload.js +4 -0
  45. package/lib/index.d.ts +13 -5
  46. package/lib/index.js +78 -48
  47. package/lib/reducer.d.ts +2 -0
  48. package/lib/reducer.js +6 -0
  49. package/lib/rootStateTypes.d.ts +4 -0
  50. package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingEpic.d.ts +9 -0
  51. package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingEpic.js +50 -0
  52. package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingMatchEpic.d.ts +12 -0
  53. package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingMatchEpic.js +39 -0
  54. package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingPageEpic.d.ts +5 -0
  55. package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingPageEpic.js +11 -0
  56. package/lib/view/expenseAutomationView/epics/actualMatching/matchAndReverseAccrualsEpic.d.ts +8 -0
  57. package/lib/view/expenseAutomationView/epics/actualMatching/matchAndReverseAccrualsEpic.js +56 -0
  58. package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchAccrualsEpic.d.ts +8 -0
  59. package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchAccrualsEpic.js +48 -0
  60. package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.d.ts +8 -0
  61. package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.js +77 -0
  62. package/lib/view/expenseAutomationView/epics/actualMatching/undoReversalAccrualsEpic.d.ts +8 -0
  63. package/lib/view/expenseAutomationView/epics/actualMatching/undoReversalAccrualsEpic.js +56 -0
  64. package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.d.ts +2 -1
  65. package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +28 -11
  66. package/lib/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.d.ts +2 -1
  67. package/lib/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.js +9 -1
  68. package/lib/view/expenseAutomationView/epics/jeSchedule/prefetchOtherJeSchedulesTabEpic.js +3 -1
  69. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.d.ts +2 -1
  70. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +5 -0
  71. package/lib/view/expenseAutomationView/expenseAutomationViewSelector.js +22 -7
  72. package/lib/view/expenseAutomationView/payload/actualMatchingPayload.d.ts +85 -0
  73. package/lib/view/expenseAutomationView/payload/actualMatchingPayload.js +74 -0
  74. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.d.ts +74 -0
  75. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +368 -0
  76. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +4 -4
  77. package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.d.ts +83 -0
  78. package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.js +2 -0
  79. package/lib/view/expenseAutomationView/selectorTypes/expenseAutomationViewSelectorTypes.d.ts +2 -0
  80. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.d.ts +29 -0
  81. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +296 -0
  82. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +3 -0
  83. package/lib/view/expenseAutomationView/types/actualMatchingViewState.d.ts +99 -0
  84. package/lib/view/expenseAutomationView/types/actualMatchingViewState.js +38 -0
  85. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +1 -1
  86. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +5 -1
  87. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewPayload.d.ts +1 -11
  88. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewPayload.js +4 -0
  89. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer.d.ts +1 -2
  90. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewSelector.d.ts +1 -2
  91. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewState.d.ts +15 -1
  92. package/lib/view/invoicing/invoicingCustomerListView/invoicingCustomerListViewReducer.d.ts +1 -1
  93. package/lib/view/invoicing/invoicingCustomerListView/invoicingCustomerListViewState.d.ts +1 -1
  94. package/package.json +1 -1
@@ -4,6 +4,7 @@ import { convertToPeriod, toAbsoluteDay, } from '../../../../commonStateTypes/ti
4
4
  import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
5
5
  import { fetchCompanyMonthEndReportTemplates, fetchCompanyMonthEndReportView, } from '../../../companyMonthEndReportView/companyMonthEndReportViewReducer';
6
6
  import { refreshExpenseAutomationCurrentTab } from '../../expenseAutomationViewReducer';
7
+ import { fetchActualMatchingPage } from '../../reducers/actualMatchingViewReducer';
7
8
  import { fetchFluxAnalysisView } from '../../reducers/fluxAnalysisViewReducer';
8
9
  import { fetchJeSchedulesPage } from '../../reducers/jeSchedulesViewReducer';
9
10
  import { fetchMissingReceipts } from '../../reducers/missingReceiptsViewReducer';
@@ -38,10 +39,17 @@ export const refreshExpenseAutomationCurrentTabEpic = (actions$, state$) => acti
38
39
  return from([
39
40
  fetchFluxAnalysisView(selectedPeriod, true, true, null),
40
41
  ]);
41
- case 'je_schedules':
42
+ case 'je_schedules': {
43
+ const selectedPageTab = state.expenseAutomationJESchedulesViewState.uiState.selectedPageTab;
44
+ if (selectedPageTab === 'actual_matching') {
45
+ return from([
46
+ fetchActualMatchingPage({ start: timePeriodStart, end: timePeriodEnd }, true),
47
+ ]);
48
+ }
42
49
  return from([
43
50
  fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, true),
44
51
  ]);
52
+ }
45
53
  case 'month_end_insights':
46
54
  return from([
47
55
  fetchCompanyMonthEndReportView(true, companyId, currentTenant.tenantId, period.end, true),
@@ -14,7 +14,9 @@ export const prefetchOtherJeSchedulesTabEpic = (actions$, state$) => actions$.pi
14
14
  const state = state$.value;
15
15
  const { period } = action.payload;
16
16
  const { selectedPageTab } = state.expenseAutomationJESchedulesViewState.uiState;
17
- const otherPageTab = ALL_JE_PAGE_TABS.find((pageTab) => pageTab !== selectedPageTab);
17
+ // Actual Matching has its own CES slice and API; warming it with fetchJeSchedules
18
+ // would prefetch the wrong endpoint. Only Review <-> Existing share that fetch.
19
+ const otherPageTab = ALL_JE_PAGE_TABS.find((pageTab) => pageTab !== selectedPageTab && pageTab !== 'actual_matching');
18
20
  if (otherPageTab == null) {
19
21
  return EMPTY;
20
22
  }
@@ -2,6 +2,7 @@ import { EMPTY, of } from 'rxjs';
2
2
  import { filter, mergeMap } from 'rxjs/operators';
3
3
  import { convertToPeriod, toAbsoluteDay, } from '../../../../commonStateTypes/timePeriod';
4
4
  import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
5
+ import { fetchActualMatchingPage } from '../../reducers/actualMatchingViewReducer';
5
6
  import { fetchJeSchedulesPage, updateJESchedulesUIState, } from '../../reducers/jeSchedulesViewReducer';
6
7
  export const switchJESchedulesTabEpic = (actions$, state$) => actions$.pipe(filter(updateJESchedulesUIState.match), filter((action) => action.payload.selectedPageTab != null), mergeMap(() => {
7
8
  const state = state$.value;
@@ -24,5 +25,9 @@ export const switchJESchedulesTabEpic = (actions$, state$) => actions$.pipe(filt
24
25
  if (timePeriodStart == null || timePeriodEnd == null) {
25
26
  return EMPTY;
26
27
  }
28
+ const { selectedPageTab } = state.expenseAutomationJESchedulesViewState.uiState;
29
+ if (selectedPageTab === 'actual_matching') {
30
+ return of(fetchActualMatchingPage({ start: timePeriodStart, end: timePeriodEnd }, true));
31
+ }
27
32
  return of(fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, true));
28
33
  }));
@@ -4,6 +4,7 @@ import { getMonthEndCloseChecksForATenantForSelectedPeriod } from '../../entity/
4
4
  import { getCurrentTenant, } from '../../entity/tenant/tenantSelector';
5
5
  import { getCompanyMonthEndReportSelectorView } from '../companyMonthEndReportView/companyMonthEndReportViewSelector';
6
6
  import { getMonthEndCloseChecksViewByTenantId, isMonthEndInsightDisabled, } from '../monthEndCloseChecksView/monthEndCloseChecksViewSelector';
7
+ import { getExpenseAutomationActualMatchingView } from './selectors/actualMatchingViewSelector';
7
8
  import { getExpenseAutomationFluxAnalysisView } from './selectors/fluxAnalysisViewSelector';
8
9
  import { getAllSteps } from './selectors/getAllStepsHelper';
9
10
  import { getExpenseAutomationJESchedulesView } from './selectors/jeSchedulesViewSelector';
@@ -21,7 +22,7 @@ const isPreviousStepDisabled = (selectedTransactionCategorizationTab, allSteps,
21
22
  return allSteps[stepIndex - 1].isDisabled;
22
23
  };
23
24
  export function getExpenseAutomationView(state) {
24
- const { expenseAutomationViewState, tenantState, expenseAutomationMissingReceiptsViewState, expenseAutomationJESchedulesViewState, expenseAutomationTransactionsViewState, expenseAutomationReconciliationViewState, monthEndCloseChecksState, companyState, } = state;
25
+ const { expenseAutomationViewState, tenantState, expenseAutomationMissingReceiptsViewState, expenseAutomationJESchedulesViewState, expenseAutomationActualMatchingViewState, expenseAutomationTransactionsViewState, expenseAutomationReconciliationViewState, monthEndCloseChecksState, companyState, } = state;
25
26
  const { loggedInUser, currentTenantId } = tenantState;
26
27
  const currentTenant = getCurrentTenant(state);
27
28
  const { currentSelectedView, selectedPeriodByTenantId } = expenseAutomationViewState;
@@ -42,6 +43,7 @@ export function getExpenseAutomationView(state) {
42
43
  const reconciliation = getExpenseAutomationReconciliationView(state);
43
44
  const expenseAutomationTransactionsView = getExpenseAutomationTransactionView(state);
44
45
  const jeSchedules = getExpenseAutomationJESchedulesView(state);
46
+ const actualMatching = getExpenseAutomationActualMatchingView(state);
45
47
  switch (currentSelectedView) {
46
48
  case 'reconciliation':
47
49
  currentSelectedViewFetchState = reconciliation.fetchStatus;
@@ -54,12 +56,23 @@ export function getExpenseAutomationView(state) {
54
56
  fluxAnalysis.refreshStatus;
55
57
  break;
56
58
  case 'je_schedules':
57
- currentSelectedViewFetchState = {
58
- fetchState: jeSchedules.fetchState,
59
- error: jeSchedules.error,
60
- };
61
- currentSelectedViewBackgroundRefreshFetchState =
62
- jeSchedules.refreshStatus;
59
+ if (expenseAutomationJESchedulesViewState.uiState.selectedPageTab ===
60
+ 'actual_matching') {
61
+ currentSelectedViewFetchState = {
62
+ fetchState: actualMatching.fetchState,
63
+ error: actualMatching.error,
64
+ };
65
+ currentSelectedViewBackgroundRefreshFetchState =
66
+ actualMatching.refreshStatus;
67
+ }
68
+ else {
69
+ currentSelectedViewFetchState = {
70
+ fetchState: jeSchedules.fetchState,
71
+ error: jeSchedules.error,
72
+ };
73
+ currentSelectedViewBackgroundRefreshFetchState =
74
+ jeSchedules.refreshStatus;
75
+ }
63
76
  break;
64
77
  case 'missing_receipts':
65
78
  currentSelectedViewFetchState = {
@@ -91,6 +104,7 @@ export function getExpenseAutomationView(state) {
91
104
  const fetchStateVariables = [
92
105
  expenseAutomationMissingReceiptsViewState,
93
106
  expenseAutomationJESchedulesViewState,
107
+ expenseAutomationActualMatchingViewState,
94
108
  expenseAutomationTransactionsView,
95
109
  expenseAutomationReconciliationViewState,
96
110
  ];
@@ -176,6 +190,7 @@ export function getExpenseAutomationView(state) {
176
190
  ]);
177
191
  return {
178
192
  jeSchedules,
193
+ actualMatching,
179
194
  transactionView: expenseAutomationTransactionsView,
180
195
  missingReceipts,
181
196
  reconciliation,
@@ -0,0 +1,68 @@
1
+ import { toString } from '../../../commonStateTypes/timePeriod';
2
+ import { toMatchAndReverseResultStatus, toUndoReversalResultStatus, } from '../types/actualMatchingViewState';
3
+ export function toServiceMonthFromPeriod(period) {
4
+ return toString(period.start).slice(0, 7);
5
+ }
6
+ const DEFAULT_CURRENCY_CODE = 'USD';
7
+ const DEFAULT_CURRENCY_SYMBOL = '$';
8
+ function resolveMatchSearchAmount(payload) {
9
+ const raw = payload.total_amount ?? payload.amount;
10
+ if (typeof raw === 'number' && Number.isFinite(raw)) {
11
+ return raw;
12
+ }
13
+ if (typeof raw === 'string' && raw !== '') {
14
+ const parsed = Number(raw);
15
+ if (Number.isFinite(parsed)) {
16
+ return parsed;
17
+ }
18
+ }
19
+ return 0;
20
+ }
21
+ function resolveMatchSearchCurrencySymbol(payload, currencyCode) {
22
+ if (payload.currency_symbol != null && payload.currency_symbol !== '') {
23
+ return payload.currency_symbol;
24
+ }
25
+ return currencyCode === DEFAULT_CURRENCY_CODE
26
+ ? DEFAULT_CURRENCY_SYMBOL
27
+ : currencyCode;
28
+ }
29
+ export function toActualMatchingTransactionSearchResult(payload) {
30
+ const currencyCode = payload.currency_code != null && payload.currency_code !== ''
31
+ ? payload.currency_code
32
+ : DEFAULT_CURRENCY_CODE;
33
+ return {
34
+ transactionId: payload.transaction_id,
35
+ transactionIntegrationId: payload.transaction_integration_id,
36
+ transactionType: payload.transaction_type,
37
+ lineId: payload.line_id,
38
+ vendorId: payload.vendor_id ?? undefined,
39
+ vendorName: payload.vendor_name ?? '',
40
+ amount: resolveMatchSearchAmount(payload),
41
+ transactionDate: payload.transaction_date,
42
+ accountId: payload.account_id ?? undefined,
43
+ accountName: payload.account_name ?? undefined,
44
+ accountDescription: payload.account_description ?? undefined,
45
+ accountingClassId: payload.accounting_class_id ?? undefined,
46
+ accountingClassName: payload.accounting_class_name ?? undefined,
47
+ currencyCode,
48
+ currencySymbol: resolveMatchSearchCurrencySymbol(payload, currencyCode),
49
+ transactionMemo: payload.transaction_memo ?? undefined,
50
+ transactionDescription: payload.transaction_description ?? undefined,
51
+ transactionTypeName: payload.transaction_type_name ?? undefined,
52
+ syncToken: payload.sync_token == null ? '' : String(payload.sync_token),
53
+ };
54
+ }
55
+ export function toMatchAndReverseResult(payload) {
56
+ return {
57
+ accrualId: payload.accrual_id,
58
+ status: toMatchAndReverseResultStatus(payload.status),
59
+ reason: payload.reason ?? undefined,
60
+ };
61
+ }
62
+ export function toUndoReversalResult(payload) {
63
+ return {
64
+ accrualId: payload.accrual_id,
65
+ status: toUndoReversalResultStatus(payload.status),
66
+ reason: payload.reason ?? undefined,
67
+ };
68
+ }
@@ -0,0 +1,364 @@
1
+ import { createSlice } from '@reduxjs/toolkit';
2
+ import { toMonthYearPeriodId, } from '../../../commonStateTypes/timePeriod';
3
+ import { generateJEOneTimeAccrualKey } from '../../../entity/jeSchedules/jeScheduleHelper';
4
+ import { clearAll } from '../../../rootActions';
5
+ export const initialTransactionSearchState = {
6
+ query: '',
7
+ results: [],
8
+ fetchState: 'Not-Started',
9
+ error: undefined,
10
+ nextPageToken: null,
11
+ isLoadingMore: false,
12
+ };
13
+ export const initialAccrualSearchState = {
14
+ query: '',
15
+ results: [],
16
+ fetchState: 'Not-Started',
17
+ error: undefined,
18
+ nextPageToken: null,
19
+ isLoadingMore: false,
20
+ };
21
+ export const initialMatchModalState = {
22
+ isOpen: false,
23
+ openedFromMatchId: undefined,
24
+ pinnedTransactionResults: [],
25
+ transactionSearch: initialTransactionSearchState,
26
+ accrualSearch: initialAccrualSearchState,
27
+ confirmStatus: { fetchState: 'Not-Started', error: undefined },
28
+ };
29
+ export const initialState = {
30
+ matchIdsByPeriod: {},
31
+ fetchState: 'Not-Started',
32
+ error: undefined,
33
+ refreshStatus: {
34
+ fetchState: 'Not-Started',
35
+ error: undefined,
36
+ },
37
+ detailFetchStateByMatchId: {},
38
+ detailRefreshStatusByMatchId: {},
39
+ uiState: {
40
+ sortKey: 'date',
41
+ sortOrder: 'descending',
42
+ searchString: '',
43
+ scrollPosition: { scrollTop: 0, scrollLeft: undefined },
44
+ },
45
+ matchModal: initialMatchModalState,
46
+ undoReversalStatus: { fetchState: 'Not-Started', error: undefined },
47
+ hasValidState() {
48
+ return this.fetchState == 'Completed';
49
+ },
50
+ };
51
+ function resetMatchModalSearches(draft) {
52
+ draft.matchModal.transactionSearch = initialTransactionSearchState;
53
+ draft.matchModal.accrualSearch = initialAccrualSearchState;
54
+ draft.matchModal.confirmStatus = {
55
+ fetchState: 'Not-Started',
56
+ error: undefined,
57
+ };
58
+ draft.matchModal.lastBatchResults = undefined;
59
+ draft.matchModal.openedFromMatchId = undefined;
60
+ draft.matchModal.pinnedTransactionResults = [];
61
+ }
62
+ const expenseAutomationActualMatchingView = createSlice({
63
+ name: 'expenseAutomationActualMatchingView',
64
+ initialState,
65
+ reducers: {
66
+ fetchActualMatchingPage: {
67
+ prepare(period, refreshViewInBackground = false) {
68
+ return {
69
+ payload: {
70
+ period,
71
+ refreshViewInBackground,
72
+ },
73
+ };
74
+ },
75
+ reducer() {
76
+ // Epic-only fan-out.
77
+ },
78
+ },
79
+ fetchActualMatching: {
80
+ reducer(draft, action) {
81
+ const { refreshViewInBackground } = action.payload;
82
+ if (refreshViewInBackground) {
83
+ draft.refreshStatus = { fetchState: 'In-Progress', error: undefined };
84
+ }
85
+ else {
86
+ draft.fetchState = 'In-Progress';
87
+ draft.error = undefined;
88
+ }
89
+ },
90
+ prepare(period, refreshViewInBackground = false) {
91
+ return {
92
+ payload: {
93
+ period,
94
+ refreshViewInBackground,
95
+ },
96
+ };
97
+ },
98
+ },
99
+ fetchActualMatchingSuccess(draft, action) {
100
+ const { matchIds, selectedPeriod, refreshViewInBackground } = action.payload;
101
+ const periodId = toMonthYearPeriodId(selectedPeriod);
102
+ draft.matchIdsByPeriod[periodId] = matchIds;
103
+ if (refreshViewInBackground) {
104
+ draft.refreshStatus = { fetchState: 'Completed', error: undefined };
105
+ }
106
+ else {
107
+ draft.fetchState = 'Completed';
108
+ draft.error = undefined;
109
+ }
110
+ },
111
+ fetchActualMatchingFailure(draft, action) {
112
+ const { status, refreshViewInBackground } = action.payload;
113
+ if (refreshViewInBackground) {
114
+ draft.refreshStatus = { fetchState: 'Error', error: status };
115
+ }
116
+ else {
117
+ draft.fetchState = 'Error';
118
+ draft.error = status;
119
+ }
120
+ },
121
+ fetchActualMatchingMatch: {
122
+ prepare(matchId, refreshViewInBackground = false) {
123
+ return { payload: { matchId, refreshViewInBackground } };
124
+ },
125
+ reducer(draft, action) {
126
+ const { matchId, refreshViewInBackground } = action.payload;
127
+ if (refreshViewInBackground) {
128
+ draft.detailRefreshStatusByMatchId[matchId] = {
129
+ fetchState: 'In-Progress',
130
+ error: undefined,
131
+ };
132
+ }
133
+ else {
134
+ draft.detailFetchStateByMatchId[matchId] = {
135
+ fetchState: 'In-Progress',
136
+ error: undefined,
137
+ };
138
+ }
139
+ },
140
+ },
141
+ fetchActualMatchingMatchSuccess(draft, action) {
142
+ const { matchId, refreshViewInBackground } = action.payload;
143
+ if (refreshViewInBackground) {
144
+ draft.detailRefreshStatusByMatchId[matchId] = {
145
+ fetchState: 'Completed',
146
+ error: undefined,
147
+ };
148
+ }
149
+ else {
150
+ draft.detailFetchStateByMatchId[matchId] = {
151
+ fetchState: 'Completed',
152
+ error: undefined,
153
+ };
154
+ }
155
+ },
156
+ fetchActualMatchingMatchFailure(draft, action) {
157
+ const { matchId, refreshViewInBackground, status } = action.payload;
158
+ if (refreshViewInBackground) {
159
+ draft.detailRefreshStatusByMatchId[matchId] = {
160
+ fetchState: 'Error',
161
+ error: status,
162
+ };
163
+ }
164
+ else {
165
+ draft.detailFetchStateByMatchId[matchId] = {
166
+ fetchState: 'Error',
167
+ error: status,
168
+ };
169
+ }
170
+ },
171
+ updateActualMatchingUIState(draft, action) {
172
+ if (action.payload.sortKey != null) {
173
+ draft.uiState.sortKey = action.payload.sortKey;
174
+ }
175
+ if (action.payload.sortOrder != null) {
176
+ draft.uiState.sortOrder = action.payload.sortOrder;
177
+ }
178
+ if (action.payload.searchString != null) {
179
+ draft.uiState.searchString = action.payload.searchString;
180
+ }
181
+ if (action.payload.scrollPosition != null) {
182
+ draft.uiState.scrollPosition = action.payload.scrollPosition;
183
+ }
184
+ },
185
+ openMatchNewModal: {
186
+ prepare(matchId) {
187
+ return { payload: { matchId } };
188
+ },
189
+ reducer(draft, action) {
190
+ resetMatchModalSearches(draft);
191
+ draft.matchModal.isOpen = true;
192
+ const matchId = action.payload.matchId;
193
+ draft.matchModal.openedFromMatchId =
194
+ matchId != null && matchId !== '' ? matchId : undefined;
195
+ if (draft.matchModal.openedFromMatchId != null) {
196
+ draft.matchModal.accrualSearch.fetchState = 'Completed';
197
+ }
198
+ },
199
+ },
200
+ closeMatchNewModal(draft) {
201
+ draft.matchModal.isOpen = false;
202
+ resetMatchModalSearches(draft);
203
+ },
204
+ clearMatchNewModal(draft) {
205
+ draft.matchModal.isOpen = false;
206
+ resetMatchModalSearches(draft);
207
+ },
208
+ searchMatchTransactions: {
209
+ reducer(draft, action) {
210
+ const { query, pageToken } = action.payload;
211
+ const isLoadMore = pageToken != null;
212
+ draft.matchModal.transactionSearch.query = query;
213
+ if (isLoadMore) {
214
+ draft.matchModal.transactionSearch.isLoadingMore = true;
215
+ }
216
+ else {
217
+ draft.matchModal.transactionSearch.isLoadingMore = false;
218
+ draft.matchModal.transactionSearch.results = [];
219
+ draft.matchModal.transactionSearch.nextPageToken = null;
220
+ draft.matchModal.transactionSearch.fetchState = 'In-Progress';
221
+ draft.matchModal.transactionSearch.error = undefined;
222
+ }
223
+ },
224
+ prepare({ query, pageToken, transactionType, transactionIntegrationId, }) {
225
+ return {
226
+ payload: {
227
+ query,
228
+ pageToken: pageToken ?? undefined,
229
+ transactionType,
230
+ transactionIntegrationId,
231
+ },
232
+ };
233
+ },
234
+ },
235
+ searchMatchTransactionsSuccess(draft, action) {
236
+ const { append, nextPageToken, results } = action.payload;
237
+ if (append) {
238
+ const merged = [
239
+ ...draft.matchModal.transactionSearch.results,
240
+ ...results,
241
+ ];
242
+ const byKey = new Map(merged.map((result) => [
243
+ `${result.transactionId}:${result.lineId}`,
244
+ result,
245
+ ]));
246
+ draft.matchModal.transactionSearch.results = Array.from(byKey.values());
247
+ }
248
+ else {
249
+ draft.matchModal.transactionSearch.results = results;
250
+ if (draft.matchModal.openedFromMatchId != null &&
251
+ draft.matchModal.pinnedTransactionResults.length === 0) {
252
+ draft.matchModal.pinnedTransactionResults = results;
253
+ }
254
+ }
255
+ draft.matchModal.transactionSearch.nextPageToken = nextPageToken;
256
+ draft.matchModal.transactionSearch.isLoadingMore = false;
257
+ draft.matchModal.transactionSearch.fetchState = 'Completed';
258
+ draft.matchModal.transactionSearch.error = undefined;
259
+ },
260
+ searchMatchTransactionsFailure(draft, action) {
261
+ draft.matchModal.transactionSearch.isLoadingMore = false;
262
+ draft.matchModal.transactionSearch.fetchState = 'Error';
263
+ draft.matchModal.transactionSearch.error = action.payload.error;
264
+ },
265
+ searchMatchAccruals: {
266
+ reducer(draft, action) {
267
+ const { query, pageToken } = action.payload;
268
+ const isLoadMore = pageToken != null;
269
+ draft.matchModal.accrualSearch.query = query;
270
+ if (isLoadMore) {
271
+ draft.matchModal.accrualSearch.isLoadingMore = true;
272
+ }
273
+ else {
274
+ draft.matchModal.accrualSearch.isLoadingMore = false;
275
+ draft.matchModal.accrualSearch.results = [];
276
+ draft.matchModal.accrualSearch.nextPageToken = null;
277
+ draft.matchModal.accrualSearch.fetchState = 'In-Progress';
278
+ draft.matchModal.accrualSearch.error = undefined;
279
+ }
280
+ },
281
+ prepare({ query, pageToken }) {
282
+ return { payload: { query, pageToken: pageToken ?? undefined } };
283
+ },
284
+ },
285
+ searchMatchAccrualsSuccess(draft, action) {
286
+ const { append, nextPageToken, results } = action.payload;
287
+ const keys = results.map((accrual) => generateJEOneTimeAccrualKey(accrual._id));
288
+ if (append) {
289
+ const merged = [...draft.matchModal.accrualSearch.results, ...keys];
290
+ draft.matchModal.accrualSearch.results = Array.from(new Set(merged));
291
+ }
292
+ else {
293
+ draft.matchModal.accrualSearch.results = keys;
294
+ }
295
+ draft.matchModal.accrualSearch.nextPageToken = nextPageToken;
296
+ draft.matchModal.accrualSearch.isLoadingMore = false;
297
+ draft.matchModal.accrualSearch.fetchState = 'Completed';
298
+ draft.matchModal.accrualSearch.error = undefined;
299
+ },
300
+ searchMatchAccrualsFailure(draft, action) {
301
+ draft.matchModal.accrualSearch.isLoadingMore = false;
302
+ draft.matchModal.accrualSearch.fetchState = 'Error';
303
+ draft.matchModal.accrualSearch.error = action.payload.error;
304
+ },
305
+ matchAndReverseAccruals: {
306
+ reducer(draft) {
307
+ draft.matchModal.confirmStatus = {
308
+ fetchState: 'In-Progress',
309
+ error: undefined,
310
+ };
311
+ },
312
+ prepare(params) {
313
+ return { payload: params };
314
+ },
315
+ },
316
+ matchAndReverseAccrualsSuccess(draft, action) {
317
+ draft.matchModal.confirmStatus = {
318
+ fetchState: 'Completed',
319
+ error: undefined,
320
+ };
321
+ draft.matchModal.lastBatchResults = action.payload.results;
322
+ },
323
+ matchAndReverseAccrualsFailure(draft, action) {
324
+ draft.matchModal.confirmStatus = {
325
+ fetchState: 'Error',
326
+ error: action.payload.status,
327
+ };
328
+ },
329
+ undoReversalAccruals: {
330
+ reducer(draft) {
331
+ draft.undoReversalStatus = {
332
+ fetchState: 'In-Progress',
333
+ error: undefined,
334
+ };
335
+ },
336
+ prepare(params) {
337
+ return { payload: params };
338
+ },
339
+ },
340
+ undoReversalAccrualsSuccess(draft, action) {
341
+ draft.undoReversalStatus = {
342
+ fetchState: 'Completed',
343
+ error: undefined,
344
+ };
345
+ void action;
346
+ },
347
+ undoReversalAccrualsFailure(draft, action) {
348
+ draft.undoReversalStatus = {
349
+ fetchState: 'Error',
350
+ error: action.payload.status,
351
+ };
352
+ },
353
+ clearActualMatchingView(draft) {
354
+ Object.assign(draft, initialState);
355
+ },
356
+ },
357
+ extraReducers: (builder) => {
358
+ builder.addCase(clearAll, (draft) => {
359
+ Object.assign(draft, initialState);
360
+ });
361
+ },
362
+ });
363
+ export const { clearActualMatchingView, clearMatchNewModal, closeMatchNewModal, fetchActualMatching, fetchActualMatchingFailure, fetchActualMatchingMatch, fetchActualMatchingMatchFailure, fetchActualMatchingMatchSuccess, fetchActualMatchingPage, fetchActualMatchingSuccess, matchAndReverseAccruals, matchAndReverseAccrualsFailure, matchAndReverseAccrualsSuccess, openMatchNewModal, searchMatchAccruals, searchMatchAccrualsFailure, searchMatchAccrualsSuccess, searchMatchTransactions, searchMatchTransactionsFailure, searchMatchTransactionsSuccess, undoReversalAccruals, undoReversalAccrualsFailure, undoReversalAccrualsSuccess, updateActualMatchingUIState, } = expenseAutomationActualMatchingView.actions;
364
+ export default expenseAutomationActualMatchingView.reducer;