@zeniai/client-epic-state 5.2.40 → 5.2.41-beta2MM

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 (122) hide show
  1. package/lib/entity/actualMatching/actualMatchingPayload.d.ts +31 -0
  2. package/lib/entity/actualMatching/actualMatchingPayload.js +52 -0
  3. package/lib/entity/actualMatching/actualMatchingReducer.d.ts +11 -0
  4. package/lib/entity/actualMatching/actualMatchingReducer.js +42 -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 +23 -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/file/fileReducer.d.ts +8 -0
  12. package/lib/entity/file/fileReducer.js +10 -2
  13. package/lib/entity/invoicing/invoicingCommonPayload.d.ts +14 -1
  14. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +31 -0
  15. package/lib/entity/jeSchedules/jeSchedulesPayload.js +53 -0
  16. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +33 -0
  17. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  18. package/lib/entity/snackbar/snackbarTypes.js +3 -0
  19. package/lib/epic.d.ts +9 -1
  20. package/lib/epic.js +16 -0
  21. package/lib/esm/entity/actualMatching/actualMatchingPayload.js +48 -0
  22. package/lib/esm/entity/actualMatching/actualMatchingReducer.js +38 -0
  23. package/lib/esm/entity/actualMatching/actualMatchingSelector.js +3 -0
  24. package/lib/esm/entity/actualMatching/actualMatchingState.js +1 -0
  25. package/lib/esm/entity/actualMatching/actualMatchingTypes.js +1 -0
  26. package/lib/esm/entity/file/fileReducer.js +10 -2
  27. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +53 -0
  28. package/lib/esm/entity/snackbar/snackbarTypes.js +3 -0
  29. package/lib/esm/epic.js +16 -0
  30. package/lib/esm/index.js +7 -3
  31. package/lib/esm/reducer.js +6 -0
  32. package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +25 -12
  33. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingEpic.js +46 -0
  34. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.js +36 -0
  35. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingPageEpic.js +7 -0
  36. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.js +49 -0
  37. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.js +108 -0
  38. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/refreshActualMatchingList.js +16 -0
  39. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchAccrualsEpic.js +60 -0
  40. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchTransactionsEpic.js +74 -0
  41. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/undoReversalAccrualsEpic.js +78 -0
  42. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +13 -3
  43. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/prefetchOtherJeSchedulesTabEpic.js +40 -15
  44. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +19 -8
  45. package/lib/esm/view/expenseAutomationView/expenseAutomationViewReducer.js +2 -1
  46. package/lib/esm/view/expenseAutomationView/expenseAutomationViewSelector.js +24 -6
  47. package/lib/esm/view/expenseAutomationView/expenseAutomationViewState.js +4 -2
  48. package/lib/esm/view/expenseAutomationView/payload/actualMatchingPayload.js +68 -0
  49. package/lib/esm/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +497 -0
  50. package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +2 -1
  51. package/lib/esm/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.js +1 -0
  52. package/lib/esm/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +432 -0
  53. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +4 -0
  54. package/lib/esm/view/expenseAutomationView/types/actualMatchingViewState.js +47 -0
  55. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +8 -1
  56. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewSelector.js +1 -1
  57. package/lib/esm/view/invoicing/settingsView/epics/fetchInvoicingSettingsEpic.js +6 -0
  58. package/lib/esm/view/invoicing/settingsView/epics/saveInvoicingSettingsEpic.js +7 -0
  59. package/lib/esm/view/invoicing/settingsView/invoicingBrandingFormConfig.js +1 -1
  60. package/lib/esm/view/invoicing/settingsView/settingsViewSelector.js +5 -0
  61. package/lib/esm/view/invoicing/settingsView/submitInvoicingBrandingFormEpic.js +9 -0
  62. package/lib/index.d.ts +14 -5
  63. package/lib/index.js +87 -48
  64. package/lib/reducer.d.ts +2 -0
  65. package/lib/reducer.js +6 -0
  66. package/lib/rootStateTypes.d.ts +4 -0
  67. package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +25 -12
  68. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingEpic.d.ts +9 -0
  69. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingEpic.js +50 -0
  70. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.d.ts +12 -0
  71. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.js +40 -0
  72. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingPageEpic.d.ts +5 -0
  73. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingPageEpic.js +11 -0
  74. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.d.ts +10 -0
  75. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.js +53 -0
  76. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.d.ts +9 -0
  77. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.js +112 -0
  78. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/refreshActualMatchingList.d.ts +3 -0
  79. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/refreshActualMatchingList.js +19 -0
  80. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchAccrualsEpic.d.ts +9 -0
  81. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchAccrualsEpic.js +64 -0
  82. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchTransactionsEpic.d.ts +8 -0
  83. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchTransactionsEpic.js +78 -0
  84. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/undoReversalAccrualsEpic.d.ts +9 -0
  85. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/undoReversalAccrualsEpic.js +82 -0
  86. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.d.ts +2 -1
  87. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +13 -3
  88. package/lib/view/expenseAutomationView/epics/jeSchedule/prefetchOtherJeSchedulesTabEpic.d.ts +5 -1
  89. package/lib/view/expenseAutomationView/epics/jeSchedule/prefetchOtherJeSchedulesTabEpic.js +39 -14
  90. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +18 -7
  91. package/lib/view/expenseAutomationView/expenseAutomationViewReducer.d.ts +2 -1
  92. package/lib/view/expenseAutomationView/expenseAutomationViewReducer.js +2 -1
  93. package/lib/view/expenseAutomationView/expenseAutomationViewSelector.js +24 -6
  94. package/lib/view/expenseAutomationView/expenseAutomationViewState.d.ts +2 -1
  95. package/lib/view/expenseAutomationView/expenseAutomationViewState.js +6 -3
  96. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  97. package/lib/view/expenseAutomationView/payload/actualMatchingPayload.d.ts +91 -0
  98. package/lib/view/expenseAutomationView/payload/actualMatchingPayload.js +74 -0
  99. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.d.ts +88 -0
  100. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +501 -0
  101. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +6 -5
  102. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +2 -1
  103. package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.d.ts +88 -0
  104. package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.js +2 -0
  105. package/lib/view/expenseAutomationView/selectorTypes/expenseAutomationViewSelectorTypes.d.ts +11 -0
  106. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.d.ts +40 -0
  107. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +452 -0
  108. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +4 -0
  109. package/lib/view/expenseAutomationView/types/actualMatchingViewState.d.ts +116 -0
  110. package/lib/view/expenseAutomationView/types/actualMatchingViewState.js +56 -0
  111. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +1 -1
  112. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +8 -1
  113. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewSelector.js +1 -1
  114. package/lib/view/invoicing/settingsView/epics/fetchInvoicingSettingsEpic.js +6 -0
  115. package/lib/view/invoicing/settingsView/epics/saveInvoicingSettingsEpic.js +7 -0
  116. package/lib/view/invoicing/settingsView/epics/settingsViewActionType.d.ts +2 -1
  117. package/lib/view/invoicing/settingsView/invoicingBrandingFormConfig.js +1 -1
  118. package/lib/view/invoicing/settingsView/settingsViewSelector.d.ts +8 -0
  119. package/lib/view/invoicing/settingsView/settingsViewSelector.js +5 -0
  120. package/lib/view/invoicing/settingsView/submitInvoicingBrandingFormEpic.d.ts +2 -1
  121. package/lib/view/invoicing/settingsView/submitInvoicingBrandingFormEpic.js +9 -0
  122. package/package.json +1 -1
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.searchMatchTransactionsEpic = void 0;
4
+ const rxjs_1 = require("rxjs");
5
+ const operators_1 = require("rxjs/operators");
6
+ const actualMatchingSelector_1 = require("../../../../../entity/actualMatching/actualMatchingSelector");
7
+ const responsePayload_1 = require("../../../../../responsePayload");
8
+ const rootActions_1 = require("../../../../../rootActions");
9
+ const actualMatchingPayload_1 = require("../../../payload/actualMatchingPayload");
10
+ const actualMatchingViewReducer_1 = require("../../../reducers/actualMatchingViewReducer");
11
+ const actualMatchingViewSelector_1 = require("../../../selectors/actualMatchingViewSelector");
12
+ const actualMatchingViewState_1 = require("../../../types/actualMatchingViewState");
13
+ const searchMatchTransactionsEpic = (actions$, state$, zeniAPI) => {
14
+ const openModal$ = actions$.pipe((0, operators_1.filter)(actualMatchingViewReducer_1.openMatchNewModal.match), (0, operators_1.mergeMap)((action) => {
15
+ const matchId = action.payload.matchId;
16
+ if (matchId == null || matchId === '') {
17
+ return (0, rxjs_1.from)([
18
+ (0, actualMatchingViewReducer_1.searchMatchTransactions)(''),
19
+ (0, actualMatchingViewReducer_1.searchMatchAccruals)(''),
20
+ ]);
21
+ }
22
+ const match = (0, actualMatchingSelector_1.getActualMatchingMatchById)(state$.value.actualMatchingState, matchId);
23
+ const parsed = (0, actualMatchingViewSelector_1.parseActualMatchingMatchId)(matchId);
24
+ const transactionType = match?.transactionType != null && match.transactionType !== ''
25
+ ? match.transactionType
26
+ : parsed?.transactionType;
27
+ const transactionIntegrationId = match?.transactionIntegrationId != null &&
28
+ match.transactionIntegrationId !== ''
29
+ ? match.transactionIntegrationId
30
+ : parsed?.transactionIntegrationId;
31
+ return (0, rxjs_1.from)([
32
+ (0, actualMatchingViewReducer_1.searchMatchTransactions)('', undefined, transactionType, transactionIntegrationId),
33
+ ]);
34
+ }));
35
+ const searchActions$ = actions$.pipe((0, operators_1.filter)(actualMatchingViewReducer_1.searchMatchTransactions.match));
36
+ const pagination$ = searchActions$.pipe((0, operators_1.filter)((action) => action.payload.pageToken != null));
37
+ const newSearchDebounced$ = searchActions$.pipe((0, operators_1.filter)((action) => action.payload.pageToken == null), (0, operators_1.debounceTime)(actualMatchingViewState_1.MATCH_SEARCH_DEBOUNCE_MS));
38
+ const search$ = (0, rxjs_1.merge)(pagination$, newSearchDebounced$).pipe((0, operators_1.switchMap)((action) => {
39
+ const { query, pageToken, transactionType, transactionIntegrationId } = action.payload;
40
+ const queryParam = {
41
+ search_text: query,
42
+ page_size: actualMatchingViewState_1.MATCH_TRANSACTION_SEARCH_PAGE_SIZE,
43
+ ...(pageToken != null ? { page_token: pageToken } : {}),
44
+ ...(transactionType != null && transactionType !== ''
45
+ ? { transaction_type: transactionType }
46
+ : {}),
47
+ ...(transactionIntegrationId != null && transactionIntegrationId !== ''
48
+ ? { transaction_integration_id: transactionIntegrationId }
49
+ : {}),
50
+ };
51
+ return zeniAPI
52
+ .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals/match-transaction-search?query=${encodeURIComponent(JSON.stringify(queryParam))}`)
53
+ .pipe((0, operators_1.mergeMap)((response) => {
54
+ if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
55
+ const { transactions, next_page_token } = response.data;
56
+ const append = pageToken != null;
57
+ const fallbackCurrency = (0, actualMatchingViewSelector_1.getTenantDisplayCurrency)(state$.value);
58
+ const results = transactions.map((transaction) => (0, actualMatchingPayload_1.toActualMatchingTransactionSearchResult)(transaction, fallbackCurrency));
59
+ return (0, rxjs_1.of)((0, actualMatchingViewReducer_1.searchMatchTransactionsSuccess)({
60
+ append,
61
+ nextPageToken: next_page_token ?? null,
62
+ results,
63
+ }));
64
+ }
65
+ return (0, rxjs_1.of)((0, actualMatchingViewReducer_1.searchMatchTransactionsFailure)({
66
+ error: response.status,
67
+ }));
68
+ }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, actualMatchingViewReducer_1.searchMatchTransactionsFailure)({
69
+ error: (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Search match transactions REST API call errored out' +
70
+ JSON.stringify(error)),
71
+ }))),
72
+ // On the HTTP stream only. Wrapping `merge(openModal$, search$)`
73
+ // would complete the epic on the first `clearAll` and drop later searches.
74
+ (0, operators_1.takeUntil)(actions$.pipe((0, operators_1.filter)(rootActions_1.clearAll.match))));
75
+ }));
76
+ return (0, rxjs_1.merge)(openModal$, search$);
77
+ };
78
+ exports.searchMatchTransactionsEpic = searchMatchTransactionsEpic;
@@ -0,0 +1,9 @@
1
+ import { ActionsObservable, StateObservable } from 'redux-observable';
2
+ import { Observable } from 'rxjs';
3
+ import { openSnackbar } from '../../../../../entity/snackbar/snackbarReducer';
4
+ import { clearAll } from '../../../../../rootActions';
5
+ import { RootState } from '../../../../../rootStateTypes';
6
+ import { ZeniAPI } from '../../../../../zeniAPI';
7
+ import { fetchActualMatching, fetchActualMatchingMatch, undoReversalAccruals, undoReversalAccrualsFailure, undoReversalAccrualsSuccess } from '../../../reducers/actualMatchingViewReducer';
8
+ export type ActionType = ReturnType<typeof clearAll> | ReturnType<typeof fetchActualMatching> | ReturnType<typeof fetchActualMatchingMatch> | ReturnType<typeof openSnackbar> | ReturnType<typeof undoReversalAccruals> | ReturnType<typeof undoReversalAccrualsFailure> | ReturnType<typeof undoReversalAccrualsSuccess>;
9
+ export declare const undoReversalAccrualsEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.undoReversalAccrualsEpic = void 0;
4
+ const rxjs_1 = require("rxjs");
5
+ const operators_1 = require("rxjs/operators");
6
+ const actualMatchingSelector_1 = require("../../../../../entity/actualMatching/actualMatchingSelector");
7
+ const snackbarReducer_1 = require("../../../../../entity/snackbar/snackbarReducer");
8
+ const responsePayload_1 = require("../../../../../responsePayload");
9
+ const rootActions_1 = require("../../../../../rootActions");
10
+ const actualMatchingPayload_1 = require("../../../payload/actualMatchingPayload");
11
+ const actualMatchingViewReducer_1 = require("../../../reducers/actualMatchingViewReducer");
12
+ const refreshActualMatchingList_1 = require("./refreshActualMatchingList");
13
+ function undoReversalSnackbar(results, vendorName) {
14
+ const undoneCount = results.filter((result) => result.status === 'undone').length;
15
+ const failedCount = results.length - undoneCount;
16
+ const variables = [
17
+ { variableName: '_count_', variableValue: String(undoneCount) },
18
+ { variableName: '_vendor_name_', variableValue: vendorName },
19
+ ];
20
+ if (results.length > 0 && failedCount === 0) {
21
+ return (0, snackbarReducer_1.openSnackbar)({
22
+ messageSection: 'actual_matching_undo_reversal',
23
+ messageText: 'success',
24
+ type: 'success',
25
+ variables,
26
+ });
27
+ }
28
+ if (undoneCount > 0 && failedCount > 0) {
29
+ return (0, snackbarReducer_1.openSnackbar)({
30
+ messageSection: 'actual_matching_undo_reversal',
31
+ messageText: 'notification',
32
+ type: 'warning',
33
+ variables,
34
+ });
35
+ }
36
+ return (0, snackbarReducer_1.openSnackbar)({
37
+ messageSection: 'actual_matching_undo_reversal',
38
+ messageText: 'failed',
39
+ type: 'error',
40
+ variables,
41
+ });
42
+ }
43
+ function matchVendorName(state, matchId) {
44
+ return ((0, actualMatchingSelector_1.getActualMatchingMatchById)(state.actualMatchingState, matchId)?.vendorName ??
45
+ '');
46
+ }
47
+ const undoReversalAccrualsEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(actualMatchingViewReducer_1.undoReversalAccruals.match),
48
+ // Per-match exhaust: a second click on the same match drops while HTTP is in
49
+ // flight. A different match must still run — a global exhaustMap left the
50
+ // other match's reducer In-Progress with no request.
51
+ (0, operators_1.groupBy)((action) => action.payload.matchId), (0, operators_1.mergeMap)((perMatch$) => perMatch$.pipe((0, operators_1.exhaustMap)((action) => {
52
+ const { accrualIds, matchId } = action.payload;
53
+ const body = {
54
+ accrual_ids: accrualIds,
55
+ };
56
+ const vendorName = matchVendorName(state$.value, matchId);
57
+ return zeniAPI
58
+ .postAndGetJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals/undo-reversal`, body)
59
+ .pipe((0, operators_1.mergeMap)((response) => {
60
+ if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
61
+ const results = response.data.results.map(actualMatchingPayload_1.toUndoReversalResult);
62
+ const successActions = [
63
+ (0, actualMatchingViewReducer_1.undoReversalAccrualsSuccess)(matchId, results),
64
+ ];
65
+ const anyUndone = results.some((result) => result.status === 'undone');
66
+ if (anyUndone) {
67
+ successActions.push(...(0, refreshActualMatchingList_1.refreshActualMatchingList)(state$.value), (0, actualMatchingViewReducer_1.fetchActualMatchingMatch)(matchId, true));
68
+ }
69
+ successActions.push(undoReversalSnackbar(results, vendorName));
70
+ return (0, rxjs_1.from)(successActions);
71
+ }
72
+ return (0, rxjs_1.of)((0, actualMatchingViewReducer_1.undoReversalAccrualsFailure)({
73
+ matchId,
74
+ status: response.status,
75
+ }), undoReversalSnackbar([], vendorName));
76
+ }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, actualMatchingViewReducer_1.undoReversalAccrualsFailure)({
77
+ matchId,
78
+ status: (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Undo reversal accruals REST API call errored out' +
79
+ JSON.stringify(error)),
80
+ }), undoReversalSnackbar([], vendorName))), (0, operators_1.takeUntil)(actions$.pipe((0, operators_1.filter)(rootActions_1.clearAll.match))));
81
+ }))));
82
+ exports.undoReversalAccrualsEpic = undoReversalAccrualsEpic;
@@ -2,6 +2,7 @@ import { ActionsObservable, StateObservable } from 'redux-observable';
2
2
  import { Observable } from 'rxjs';
3
3
  import { RootState } from '../../../../rootStateTypes';
4
4
  import { fetchAccountList } from '../../../accountList/accountListReducer';
5
+ import { fetchActualMatchingPage } from '../../reducers/actualMatchingViewReducer';
5
6
  import { fetchJeSchedules, fetchJeSchedulesPage, initializeAccountSettingsView } from '../../reducers/jeSchedulesViewReducer';
6
- export type ActionType = ReturnType<typeof fetchAccountList> | ReturnType<typeof fetchJeSchedules> | ReturnType<typeof fetchJeSchedulesPage> | ReturnType<typeof initializeAccountSettingsView>;
7
+ export type ActionType = ReturnType<typeof fetchAccountList> | ReturnType<typeof fetchActualMatchingPage> | ReturnType<typeof fetchJeSchedules> | ReturnType<typeof fetchJeSchedulesPage> | ReturnType<typeof initializeAccountSettingsView>;
7
8
  export declare const fetchJeSchedulesPageEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>) => Observable<ActionType>;
@@ -5,24 +5,34 @@ const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
6
  const accountListReducer_1 = require("../../../accountList/accountListReducer");
7
7
  const scheduleListHelper_1 = require("../../../scheduleView/scheduleListView/scheduleListHelper");
8
+ const actualMatchingViewReducer_1 = require("../../reducers/actualMatchingViewReducer");
8
9
  const jeSchedulesViewReducer_1 = require("../../reducers/jeSchedulesViewReducer");
9
10
  const fetchJeSchedulesPageEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)(jeSchedulesViewReducer_1.fetchJeSchedulesPage.match), (0, operators_1.mergeMap)((action) => {
10
11
  const jeSchedulePageActions = [];
11
12
  const { period, refreshViewInBackground } = action.payload;
13
+ const state = state$.value;
14
+ const { selectedPageTab } = state.expenseAutomationJESchedulesViewState.uiState;
12
15
  const accountType = (0, scheduleListHelper_1.getAccountsTypesForScheduleEpics)();
13
- const accountListState = state$.value.accountListState;
16
+ const accountListState = state.accountListState;
14
17
  if (accountListState.byReportId[accountType.accountListKey].fetchState ===
15
18
  'Not-Started') {
16
19
  // call this only if the account list for schedules is not fetched already
17
20
  jeSchedulePageActions.push((0, accountListReducer_1.fetchAccountList)(accountType.accountListKey, true, false, false, false, accountType.allowedAccountList));
18
21
  }
19
- jeSchedulePageActions.push((0, jeSchedulesViewReducer_1.fetchJeSchedules)(period, refreshViewInBackground));
22
+ // AM is chrome on this page but a different endpoint. fetchJeSchedules with
23
+ // selectedPageTab === 'actual_matching' would hit /1.0/schedules and write a bogus cache slot.
24
+ if (selectedPageTab === 'actual_matching') {
25
+ jeSchedulePageActions.push((0, actualMatchingViewReducer_1.fetchActualMatchingPage)(period, refreshViewInBackground));
26
+ }
27
+ else {
28
+ jeSchedulePageActions.push((0, jeSchedulesViewReducer_1.fetchJeSchedules)(period, refreshViewInBackground));
29
+ }
20
30
  // Only on the first page load. Account settings cannot change from a tab switch or a
21
31
  // refresh, and re-initializing puts accountSettingsView back to 'In-Progress' -- which the
22
32
  // page reads as "still loading" and answers with a full skeleton over rows it already has.
23
33
  // The action also resets localData, so re-dispatching it blindly would empty the settings
24
34
  // form until the refetch lands. Saving account settings still re-initializes explicitly.
25
- if (!state$.value.expenseAutomationJESchedulesViewState.accountSettings
35
+ if (!state.expenseAutomationJESchedulesViewState.accountSettings
26
36
  .hasLoadedAccountSettings) {
27
37
  jeSchedulePageActions.push((0, jeSchedulesViewReducer_1.initializeAccountSettingsView)());
28
38
  }
@@ -1,12 +1,16 @@
1
1
  import { ActionsObservable, StateObservable } from 'redux-observable';
2
2
  import { Observable } from 'rxjs';
3
3
  import { RootState } from '../../../../rootStateTypes';
4
+ import { fetchActualMatchingPage } from '../../reducers/actualMatchingViewReducer';
4
5
  import { fetchJeSchedules, fetchJeSchedulesPage } from '../../reducers/jeSchedulesViewReducer';
5
- export type ActionType = ReturnType<typeof fetchJeSchedules> | ReturnType<typeof fetchJeSchedulesPage>;
6
+ export type ActionType = ReturnType<typeof fetchActualMatchingPage> | ReturnType<typeof fetchJeSchedules> | ReturnType<typeof fetchJeSchedulesPage>;
6
7
  /**
7
8
  * Warms the tab the user is not looking at, so switching to it renders rows instead of a skeleton.
8
9
  *
9
10
  * Listens for `fetchJeSchedulesPage` rather than `fetchJeSchedules` on purpose: the prefetch emits
10
11
  * `fetchJeSchedules`, so listening for that would make this epic feed itself.
12
+ *
13
+ * Review <-> Existing share `/1.0/schedules`. Actual Matching is a different endpoint; it is
14
+ * warmed with `fetchActualMatchingPage` when the page action carries `isAccrualEnabled`.
11
15
  */
12
16
  export declare const prefetchOtherJeSchedulesTabEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>) => Observable<ActionType>;
@@ -5,6 +5,7 @@ const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
6
  const timePeriod_1 = require("../../../../commonStateTypes/timePeriod");
7
7
  const tenantSelector_1 = require("../../../../entity/tenant/tenantSelector");
8
+ const actualMatchingViewReducer_1 = require("../../reducers/actualMatchingViewReducer");
8
9
  const jeSchedulesViewReducer_1 = require("../../reducers/jeSchedulesViewReducer");
9
10
  const jeSchedulesViewState_1 = require("../../types/jeSchedulesViewState");
10
11
  /**
@@ -12,28 +13,52 @@ const jeSchedulesViewState_1 = require("../../types/jeSchedulesViewState");
12
13
  *
13
14
  * Listens for `fetchJeSchedulesPage` rather than `fetchJeSchedules` on purpose: the prefetch emits
14
15
  * `fetchJeSchedules`, so listening for that would make this epic feed itself.
16
+ *
17
+ * Review <-> Existing share `/1.0/schedules`. Actual Matching is a different endpoint; it is
18
+ * warmed with `fetchActualMatchingPage` when the page action carries `isAccrualEnabled`.
15
19
  */
16
20
  const prefetchOtherJeSchedulesTabEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)(jeSchedulesViewReducer_1.fetchJeSchedulesPage.match), (0, operators_1.mergeMap)((action) => {
17
21
  const state = state$.value;
18
- const { period } = action.payload;
22
+ const { period, isAccrualEnabled } = action.payload;
19
23
  const { selectedPageTab } = state.expenseAutomationJESchedulesViewState.uiState;
20
- const otherPageTab = jeSchedulesViewState_1.ALL_JE_PAGE_TABS.find((pageTab) => pageTab !== selectedPageTab);
21
- if (otherPageTab == null) {
22
- return rxjs_1.EMPTY;
23
- }
24
+ const actions = [];
25
+ // AM is chrome-only on ALL_JE_PAGE_TABS; warming it with fetchJeSchedules
26
+ // would hit the wrong endpoint. Warm every other JE tab, not just the first
27
+ // in ALL_JE_PAGE_TABS — from AM that first hit is always Review, and Existing
28
+ // would never prefetch.
29
+ const otherJeTabs = jeSchedulesViewState_1.ALL_JE_PAGE_TABS.filter((pageTab) => pageTab !== selectedPageTab && pageTab !== 'actual_matching');
24
30
  const currentTenant = (0, tenantSelector_1.getCurrentTenant)(state);
25
31
  const selectedPeriod = state.expenseAutomationViewState.selectedPeriodByTenantId[currentTenant.tenantId];
26
- if (selectedPeriod == null) {
27
- return rxjs_1.EMPTY;
32
+ if (selectedPeriod != null) {
33
+ otherJeTabs.forEach((otherPageTab) => {
34
+ const otherPeriodTabKey = (0, jeSchedulesViewState_1.getJESchedulePeriodTabKey)(otherPageTab, (0, timePeriod_1.toMonthYearPeriodId)(selectedPeriod));
35
+ const isOtherTabAlreadyLoaded = state.expenseAutomationJESchedulesViewState
36
+ .jeScheduleTransactionKeysByPeriodAndTab[otherPeriodTabKey] !=
37
+ null;
38
+ if (!isOtherTabAlreadyLoaded) {
39
+ actions.push((0, jeSchedulesViewReducer_1.fetchJeSchedules)(period, true, otherPageTab));
40
+ }
41
+ });
42
+ }
43
+ // GET /actual-matching is not Statsig-gated; CES has no Statsig. The screen
44
+ // passes is_accrual_enabled so disabled tenants do not pay for a list they
45
+ // cannot open. Visible AM is fetchJeSchedulesPageEpic's job.
46
+ if (isAccrualEnabled === true &&
47
+ selectedPageTab !== 'actual_matching') {
48
+ const periodId = (0, timePeriod_1.toMonthYearPeriodId)({
49
+ month: period.start.month,
50
+ year: period.start.year,
51
+ });
52
+ // `fetchState` is global across months. Skipping on In-Progress would drop
53
+ // October prefetch while September is still loading; September's success
54
+ // then marks the slice Completed and October looks loaded with no ids.
55
+ if (state.expenseAutomationActualMatchingViewState.matchIdsByPeriod[periodId] == null) {
56
+ actions.push((0, actualMatchingViewReducer_1.fetchActualMatchingPage)(period, true));
57
+ }
28
58
  }
29
- // Already warm for this period: without this check every tab switch would refetch the tab
30
- // just left, since a switch also fires fetchJeSchedulesPage.
31
- const otherPeriodTabKey = (0, jeSchedulesViewState_1.getJESchedulePeriodTabKey)(otherPageTab, (0, timePeriod_1.toMonthYearPeriodId)(selectedPeriod));
32
- const isOtherTabAlreadyLoaded = state.expenseAutomationJESchedulesViewState
33
- .jeScheduleTransactionKeysByPeriodAndTab[otherPeriodTabKey] != null;
34
- if (isOtherTabAlreadyLoaded) {
59
+ if (actions.length === 0) {
35
60
  return rxjs_1.EMPTY;
36
61
  }
37
- return (0, rxjs_1.of)((0, jeSchedulesViewReducer_1.fetchJeSchedules)(period, true, otherPageTab));
62
+ return (0, rxjs_1.from)(actions);
38
63
  }));
39
64
  exports.prefetchOtherJeSchedulesTabEpic = prefetchOtherJeSchedulesTabEpic;
@@ -6,21 +6,32 @@ const operators_1 = require("rxjs/operators");
6
6
  const timePeriod_1 = require("../../../../commonStateTypes/timePeriod");
7
7
  const tenantSelector_1 = require("../../../../entity/tenant/tenantSelector");
8
8
  const jeSchedulesViewReducer_1 = require("../../reducers/jeSchedulesViewReducer");
9
- const switchJESchedulesTabEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)(jeSchedulesViewReducer_1.updateJESchedulesUIState.match), (0, operators_1.filter)((action) => action.payload.selectedPageTab != null), (0, operators_1.mergeMap)(() => {
9
+ const jeSchedulesViewState_1 = require("../../types/jeSchedulesViewState");
10
+ const switchJESchedulesTabEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)(jeSchedulesViewReducer_1.updateJESchedulesUIState.match), (0, operators_1.filter)((action) => action.payload.selectedPageTab != null), (0, operators_1.mergeMap)((action) => {
10
11
  const state = state$.value;
11
- const { fetchState, refreshStatus } = state.expenseAutomationJESchedulesViewState;
12
- if (fetchState === 'In-Progress' ||
13
- refreshStatus.fetchState === 'In-Progress') {
14
- return rxjs_1.EMPTY;
15
- }
12
+ const nextTab = action.payload.selectedPageTab;
16
13
  const currentTenant = (0, tenantSelector_1.getCurrentTenant)(state);
17
14
  const selectedPeriod = state.expenseAutomationViewState.selectedPeriodByTenantId[currentTenant.tenantId];
18
15
  // convertToPeriod destructures, so an unset period throws and takes this epic's subscription
19
16
  // down for the rest of the session -- every later tab switch would then stop refreshing. A
20
17
  // skipped refresh is the cheaper failure, as in refreshCurrentPage.
21
- if (selectedPeriod == null) {
18
+ if (selectedPeriod == null || nextTab == null) {
22
19
  return rxjs_1.EMPTY;
23
20
  }
21
+ const { fetchState, refreshStatus, jeScheduleTransactionKeysByPeriodAndTab } = state.expenseAutomationJESchedulesViewState;
22
+ // Review/Existing share `/1.0/schedules` but not a cache slot. A Review
23
+ // prefetch must not skip Existing when Existing has no keys yet — AM→Existing
24
+ // would sit on a skeleton with no request. Skip only when this tab is warm.
25
+ // AM is a different endpoint — never block it on JE In-Progress.
26
+ if (nextTab !== 'actual_matching') {
27
+ const slotKey = (0, jeSchedulesViewState_1.getJESchedulePeriodTabKey)(nextTab, (0, timePeriod_1.toMonthYearPeriodId)(selectedPeriod));
28
+ const slotLoaded = jeScheduleTransactionKeysByPeriodAndTab[slotKey] != null;
29
+ if (slotLoaded &&
30
+ (fetchState === 'In-Progress' ||
31
+ refreshStatus.fetchState === 'In-Progress')) {
32
+ return rxjs_1.EMPTY;
33
+ }
34
+ }
24
35
  const period = (0, timePeriod_1.convertToPeriod)(selectedPeriod);
25
36
  const timePeriodStart = (0, timePeriod_1.toAbsoluteDay)(period.start);
26
37
  const timePeriodEnd = (0, timePeriod_1.toAbsoluteDay)(period.end);
@@ -2,9 +2,10 @@ import { ID } from '../../commonStateTypes/common';
2
2
  import { MonthYearPeriod } from '../../commonStateTypes/timePeriod';
3
3
  import { ExpenseAutomationViewState } from './expenseAutomationViewState';
4
4
  export declare const initialState: ExpenseAutomationViewState;
5
- export declare const fetchAllExpenseAutomationTabs: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[cacheOverride?: boolean | undefined, refreshViewInBackground?: boolean | undefined], {
5
+ export declare const fetchAllExpenseAutomationTabs: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[cacheOverride?: boolean | undefined, refreshViewInBackground?: boolean | undefined, isAccrualEnabled?: boolean | undefined], {
6
6
  cacheOverride: boolean;
7
7
  refreshViewInBackground: boolean;
8
+ isAccrualEnabled: boolean;
8
9
  }, "expenseAutomationView/fetchAllExpenseAutomationTabs", never, never>, updateCurrentSelectedPeriod: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[tenantId: string, newSelectedPeriod: MonthYearPeriod], {
9
10
  newSelectedPeriod: MonthYearPeriod;
10
11
  tenantId: string;
@@ -23,11 +23,12 @@ const expenseAutomationView = (0, toolkit_1.createSlice)({
23
23
  reducer() {
24
24
  //do nothing
25
25
  },
26
- prepare(cacheOverride = false, refreshViewInBackground = false) {
26
+ prepare(cacheOverride = false, refreshViewInBackground = false, isAccrualEnabled = false) {
27
27
  return {
28
28
  payload: {
29
29
  cacheOverride,
30
30
  refreshViewInBackground,
31
+ isAccrualEnabled,
31
32
  },
32
33
  };
33
34
  },
@@ -7,6 +7,7 @@ const monthEndCloseChecksSelector_1 = require("../../entity/monthEndCloseChecks/
7
7
  const tenantSelector_1 = require("../../entity/tenant/tenantSelector");
8
8
  const companyMonthEndReportViewSelector_1 = require("../companyMonthEndReportView/companyMonthEndReportViewSelector");
9
9
  const monthEndCloseChecksViewSelector_1 = require("../monthEndCloseChecksView/monthEndCloseChecksViewSelector");
10
+ const actualMatchingViewSelector_1 = require("./selectors/actualMatchingViewSelector");
10
11
  const fluxAnalysisViewSelector_1 = require("./selectors/fluxAnalysisViewSelector");
11
12
  const getAllStepsHelper_1 = require("./selectors/getAllStepsHelper");
12
13
  const jeSchedulesViewSelector_1 = require("./selectors/jeSchedulesViewSelector");
@@ -45,6 +46,8 @@ function getExpenseAutomationView(state) {
45
46
  const reconciliation = (0, reconciliationViewSelector_1.getExpenseAutomationReconciliationView)(state);
46
47
  const expenseAutomationTransactionsView = (0, transactionCategorizationSelector_1.getExpenseAutomationTransactionView)(state);
47
48
  const jeSchedules = (0, jeSchedulesViewSelector_1.getExpenseAutomationJESchedulesView)(state);
49
+ // Top-level sibling of `jeSchedules`: see ExpenseAutomationViewSelector.
50
+ const actualMatching = (0, actualMatchingViewSelector_1.getExpenseAutomationActualMatchingView)(state);
48
51
  switch (currentSelectedView) {
49
52
  case 'reconciliation':
50
53
  currentSelectedViewFetchState = reconciliation.fetchStatus;
@@ -57,12 +60,23 @@ function getExpenseAutomationView(state) {
57
60
  fluxAnalysis.refreshStatus;
58
61
  break;
59
62
  case 'je_schedules':
60
- currentSelectedViewFetchState = {
61
- fetchState: jeSchedules.fetchState,
62
- error: jeSchedules.error,
63
- };
64
- currentSelectedViewBackgroundRefreshFetchState =
65
- jeSchedules.refreshStatus;
63
+ if (expenseAutomationJESchedulesViewState.uiState.selectedPageTab ===
64
+ 'actual_matching') {
65
+ currentSelectedViewFetchState = {
66
+ fetchState: actualMatching.fetchState,
67
+ error: actualMatching.error,
68
+ };
69
+ currentSelectedViewBackgroundRefreshFetchState =
70
+ actualMatching.refreshStatus;
71
+ }
72
+ else {
73
+ currentSelectedViewFetchState = {
74
+ fetchState: jeSchedules.fetchState,
75
+ error: jeSchedules.error,
76
+ };
77
+ currentSelectedViewBackgroundRefreshFetchState =
78
+ jeSchedules.refreshStatus;
79
+ }
66
80
  break;
67
81
  case 'missing_receipts':
68
82
  currentSelectedViewFetchState = {
@@ -91,6 +105,9 @@ function getExpenseAutomationView(state) {
91
105
  };
92
106
  break;
93
107
  }
108
+ // AM is optional (flag-off / background prefetch) and must not keep the
109
+ // page-level AND-complete fetchState stuck on Not-Started. Tab chrome uses
110
+ // currentSelectedViewFetchState, which already switches to AM when selected.
94
111
  const fetchStateVariables = [
95
112
  expenseAutomationMissingReceiptsViewState,
96
113
  expenseAutomationJESchedulesViewState,
@@ -179,6 +196,7 @@ function getExpenseAutomationView(state) {
179
196
  ]);
180
197
  return {
181
198
  jeSchedules,
199
+ actualMatching,
182
200
  transactionView: expenseAutomationTransactionsView,
183
201
  missingReceipts,
184
202
  reconciliation,
@@ -1,8 +1,9 @@
1
1
  import { FetchStateAndError, FetchedState, ID } from '../../commonStateTypes/common';
2
2
  import { MonthYearPeriod } from '../../commonStateTypes/timePeriod';
3
- export declare const EXPENSE_AUTOMATION_VIEW_TYPES: readonly ["transaction_categorization", "je_schedules", "reconciliation", "missing_receipts", "flux_analysis", "month_end_insights"];
4
3
  export declare const toExpenseAutomationViewType: (v: string) => "transaction_categorization" | "je_schedules" | "reconciliation" | "missing_receipts" | "flux_analysis" | "month_end_insights";
5
4
  export type ExpenseAutomationViewType = ReturnType<typeof toExpenseAutomationViewType>;
5
+ /** Unlike `toExpenseAutomationViewType`, unknown strings return `undefined`. */
6
+ export declare const toExpenseAutomationViewTypeStrict: (v: string) => ExpenseAutomationViewType | undefined;
6
7
  export interface ExpenseAutomationViewState extends FetchedState {
7
8
  currentSelectedView: ExpenseAutomationViewType;
8
9
  saveStatus: FetchStateAndError;
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toExpenseAutomationViewType = exports.EXPENSE_AUTOMATION_VIEW_TYPES = void 0;
3
+ exports.toExpenseAutomationViewTypeStrict = exports.toExpenseAutomationViewType = void 0;
4
4
  const stringToUnion_1 = require("../../commonStateTypes/stringToUnion");
5
- exports.EXPENSE_AUTOMATION_VIEW_TYPES = [
5
+ const EXPENSE_AUTOMATION_VIEW_TYPES = [
6
6
  'transaction_categorization',
7
7
  'je_schedules',
8
8
  'reconciliation',
@@ -10,5 +10,8 @@ exports.EXPENSE_AUTOMATION_VIEW_TYPES = [
10
10
  'flux_analysis',
11
11
  'month_end_insights',
12
12
  ];
13
- const toExpenseAutomationViewType = (v) => (0, stringToUnion_1.stringToUnion)(v, exports.EXPENSE_AUTOMATION_VIEW_TYPES);
13
+ const toExpenseAutomationViewType = (v) => (0, stringToUnion_1.stringToUnion)(v, EXPENSE_AUTOMATION_VIEW_TYPES);
14
14
  exports.toExpenseAutomationViewType = toExpenseAutomationViewType;
15
+ /** Unlike `toExpenseAutomationViewType`, unknown strings return `undefined`. */
16
+ const toExpenseAutomationViewTypeStrict = (v) => (0, stringToUnion_1.stringToUnionStrict)(v, EXPENSE_AUTOMATION_VIEW_TYPES);
17
+ exports.toExpenseAutomationViewTypeStrict = toExpenseAutomationViewTypeStrict;
@@ -39,7 +39,7 @@ export declare const getLineItemsByTransactionsIdsFromResponse: (transactions: S
39
39
  export declare const getLineItemsByTransactionIdsFromLocalData: (transactionLocalData: TransactionReviewLocalDataSelectorView[], selectedTab: TransactionsTab) => Record<ID, string[]>;
40
40
  export declare const mergeTabSpecificLineItems: (currentTabSpecificLineItems: TabSpecificLineItems, selectedTab: TransactionsTab, newLineItems: TabSpecificLineItems) => TabSpecificLineItems;
41
41
  export declare const getSnackbarMessageForTransactionReview: (updatedCount: number, failedCount: number, categorizedCount: number) => {
42
- messageSection: "common" | "transactionDetails_updatingPastTransactions" | "transactionDetails_transactionUpdated" | "cockpit_month_end_email_sent" | "cockpit_month_end_email_save" | "cockpit_month_end_email_attachment_upload" | "je_bill_link" | "je_posted" | "audit_score_updated" | "people_invite_people" | "people_invite_multiple_people" | "people_delete_person" | "people_update_person" | "reimbursement_updated" | "reimbursement_deleted" | "reimbursement_cancelled_deleted" | "reimbursement_cancelled" | "reimbursement_approved" | "reimbursement_rejected" | "reimbursement_sent_for_approval" | "account_added" | "business_verification_save" | "business_verification_submit" | "business_verification_from_bills_submit" | "plaid_connection" | "unlink_deposit_account" | "reimbursement_setup" | "reimbursement_approval_create" | "reimbursement_duplicate_approval_create" | "reimbursement_approval_update" | "reimbursement_duplicate_approval_update" | "reimbursement_approval_delete" | "reimbursement_approval_reorder" | "reimbursement_create_mileage" | "reimbursement_update_mileage" | "reimbursement_accept_term" | "reimbursement_accept_employee_term" | "reimbursement_bulk_submit" | "reimbursement_bulk_processed" | "bill_pay_setup" | "zeni_accounts_setup" | "bill_pay_approval_create" | "bill_pay_duplicate_approval_create" | "bill_pay_approval_update" | "bill_pay_duplicate_approval_update" | "bill_pay_approval_delete" | "bill_pay_approval_reorder" | "bill_pay_updated" | "bill_pay_deleted" | "bill_pay_cancelled_deleted" | "bill_pay_cancelled" | "bill_pay_approved" | "real_time_approver_added" | "bill_pay_rejected" | "bill_pay_sent_for_approval" | "bill_pay_accept_term" | "bill_pay_bulk_submit" | "bill_pay_bulk_processed" | "bill_pay_refund" | "bill_pay_retry" | "bill_pay_marked_as_paid" | "zeni_account_accept_term" | "update_vendor" | "data_refresh_update" | "delete_bank_account" | "create_bank_account" | "create_bank_account_ach" | "create_bank_account_wire" | "create_bank_account_international" | "transfer_money" | "update_zeni_account_nickname" | "create_checking_account" | "deposit_check" | "create_vendor" | "onboarding_customer_view" | "onboarding_customer_view_complete" | "onboarding_customer_identity_verification_save" | "onboarding_customer_identity_verification_submit" | "onboarding_customer_business_verification_save" | "onboarding_customer_business_verification_submit" | "retry_bank_account_connection" | "dashboard_invite_sent" | "onboarding_info_saved" | "approve_original_merchant" | "approve_global_merchant" | "reject_global_merchant" | "create_global_merchant" | "fetch_global_merchant_no_recommendation" | "save_vendor_renamed" | "save_vendor_sent_for_review" | "save_vendor_marked_as_employee" | "save_vendor_marked_as_local_contractor" | "charge_card_setup" | "charge_card_accept_term" | "charge_card_receipt_upload" | "charge_card_resend_invite" | "charge_card_revoke_invite" | "card_policy_created" | "card_policy_updated" | "card_policy_deleted" | "charge_card_update_limit" | "charge_cards_update_limit" | "close_charge_card" | "lock_charge_card" | "lock_charge_card_card_user" | "lock_charge_cards" | "unlock_charge_card" | "unlock_charge_card_card_user" | "unlock_charge_cards" | "close_charge_cards" | "revoke_invite_charge_cards" | "charge_card_express_interest" | "create_schedule" | "save_schedule" | "delete_schedule" | "ignore_schedule" | "revert_schedule" | "ignore_accrual" | "revert_accrual" | "save_task_detail" | "fetch_task_detail" | "delete_task" | "archive_task" | "snooze_task" | "unsnooze_task" | "create_tag" | "delete_tag" | "update_charge_card" | "update_charge_card_name" | "update_charge_card_name_card_user" | "issue_charge_card" | "issue_charge_cards" | "notification_settings_saved" | "referral_invite_sent" | "notification_mark_as_read" | "mark_as_complete_schedule" | "cancel_journal_entry" | "settings_accounting_accounts_updated" | "create_card_setup" | "confirm_card_setup" | "add_card_payment_source" | "fetch_payment_sources" | "task_assigned_toast_notification" | "task_due_tomorrow_toast_notification" | "task_deleted_toast_notification" | "task_archived_toast_notification" | "task_overdue_toast_notification" | "task_overdue_toast_notification_creator" | "task_notification_count" | "task_activities_toast_notification" | "task_created_toast_notification" | "task_group_creation_success" | "task_group_deletion_success" | "task_group_update_success" | "primary_funding_account_updated" | "task_time_spent_validation" | "missing_receipts_attachment" | "flux_analysis_unreviewed" | "flux_analysis_reviewed" | "receipt_match" | "receipts_upload" | "receipts_bulk_match" | "billing_address_view" | "express_pay_submit" | "exclude_transaction" | "reconcile" | "save_reconcile_for_later" | "recon_transaction_categorize" | "recon_transaction_match" | "update_debit_card_pin_attempt" | "set_debit_card_pin" | "ai_cfo_create_session_and_submit" | "ai_cfo_chat_session_deleted" | "charge_card_auto_pay_enable" | "charge_card_auto_pay_disable" | "treasury_setup" | "treasury_accept_term" | "treasury_transfer_money" | "treasury_transfer_money_failed" | "auto_transfer_rule_create" | "auto_transfer_rule_update" | "auto_transfer_rule_delete" | "auto_transfer_rule_pause" | "auto_transfer_rule_resume" | "treasury_update_portfolio_allocation" | "send_email_magic_link_to_user" | "complete_profile_done" | "create_transfer_entry" | "reports_resync" | "invalid_phone_number" | "transactions_categorized_updated_failed" | "transaction_categorized_updated_failed" | "transactionsCategorized_transactionsUpdated" | "transactionsCategorized_transactionUpdated" | "transactionCategorized_transactionsUpdated" | "transactionCategorized_transactionUpdated" | "transactionsCategorized_transactionsFailed" | "transactionsCategorized_transactionFailed" | "transactionCategorized_transactionsFailed" | "transactionCategorized_transactionFailed" | "transactionsUpdated_transactionsFailed" | "transactionsUpdated_transactionFailed" | "transactionUpdated_transactionsFailed" | "transactionUpdated_transactionFailed" | "transactionsCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionsUpdated_transactionFailed" | "transactionsCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionUpdated_transactionFailed" | "transactionCategorized_transactionsUpdated_transactionFailed" | "transactionCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionUpdated_transactionFailed" | "accounting_classes_enabled_update" | "accounting_projects_enabled_update" | "accounting_projects_qbo_not_enabled" | "capitalization_threshold_update" | "account_excluded_from_reconciliation" | "account_included_in_reconciliation" | "confirm_statement_mapping" | "statement_parsing_in_progress" | "statement_parsing_complete" | "ai_accountant_trigger_job" | "oauth_consent_approve" | "oauth_consent_invalid_request" | "credit_agent_update_profile" | "credit_agent_save_macro" | "credit_agent_schedule_cron" | "create_sub_task" | "qbo_connection_already_linked" | "qbo_connection_failed" | "accounting_projects_qbo_reconnect_failed" | "product_services_update" | "qbo_realm_id_update" | "invoicing_dunning_case_resolved" | "invoicing_dunning_retry" | "invoicing_dunning_cancel" | "invoicing_dunning_settings_save" | "invoicing_qbo_backfill" | "invoicing_qbo_sync_health_retry" | "invoicing_qbo_settings_save" | "invoicing_branding_save" | "invoicing_discount_archive" | "invoicing_discount_unarchive" | "invoicing_discount_delete" | "invoicing_invoice_reminder_sent" | "invoicing_invoice_regenerated" | "invoicing_invoice_voided" | "invoicing_catalog_item_saved" | "invoicing_customer_saved" | "invoicing_subscription_saved" | "invoicing_coupon_saved" | "invoicing_invoice_saved" | "invoicing_credit_note_saved" | "invoicing_payment_recorded" | "invoicing_subscription_activated" | "invoicing_subscription_cancellation_removed" | "invoicing_subscription_cancelled" | "invoicing_subscription_non_renewing" | "invoicing_subscription_paused" | "invoicing_subscription_reactivated" | "invoicing_subscription_resumed" | "invoicing_subscription_term_end_changed";
42
+ messageSection: "common" | "transactionDetails_updatingPastTransactions" | "transactionDetails_transactionUpdated" | "cockpit_month_end_email_sent" | "cockpit_month_end_email_save" | "cockpit_month_end_email_attachment_upload" | "je_bill_link" | "je_posted" | "actual_matching_match_and_reverse" | "actual_matching_undo_reversal" | "actual_matching_ignore_suggestion" | "audit_score_updated" | "people_invite_people" | "people_invite_multiple_people" | "people_delete_person" | "people_update_person" | "reimbursement_updated" | "reimbursement_deleted" | "reimbursement_cancelled_deleted" | "reimbursement_cancelled" | "reimbursement_approved" | "reimbursement_rejected" | "reimbursement_sent_for_approval" | "account_added" | "business_verification_save" | "business_verification_submit" | "business_verification_from_bills_submit" | "plaid_connection" | "unlink_deposit_account" | "reimbursement_setup" | "reimbursement_approval_create" | "reimbursement_duplicate_approval_create" | "reimbursement_approval_update" | "reimbursement_duplicate_approval_update" | "reimbursement_approval_delete" | "reimbursement_approval_reorder" | "reimbursement_create_mileage" | "reimbursement_update_mileage" | "reimbursement_accept_term" | "reimbursement_accept_employee_term" | "reimbursement_bulk_submit" | "reimbursement_bulk_processed" | "bill_pay_setup" | "zeni_accounts_setup" | "bill_pay_approval_create" | "bill_pay_duplicate_approval_create" | "bill_pay_approval_update" | "bill_pay_duplicate_approval_update" | "bill_pay_approval_delete" | "bill_pay_approval_reorder" | "bill_pay_updated" | "bill_pay_deleted" | "bill_pay_cancelled_deleted" | "bill_pay_cancelled" | "bill_pay_approved" | "real_time_approver_added" | "bill_pay_rejected" | "bill_pay_sent_for_approval" | "bill_pay_accept_term" | "bill_pay_bulk_submit" | "bill_pay_bulk_processed" | "bill_pay_refund" | "bill_pay_retry" | "bill_pay_marked_as_paid" | "zeni_account_accept_term" | "update_vendor" | "data_refresh_update" | "delete_bank_account" | "create_bank_account" | "create_bank_account_ach" | "create_bank_account_wire" | "create_bank_account_international" | "transfer_money" | "update_zeni_account_nickname" | "create_checking_account" | "deposit_check" | "create_vendor" | "onboarding_customer_view" | "onboarding_customer_view_complete" | "onboarding_customer_identity_verification_save" | "onboarding_customer_identity_verification_submit" | "onboarding_customer_business_verification_save" | "onboarding_customer_business_verification_submit" | "retry_bank_account_connection" | "dashboard_invite_sent" | "onboarding_info_saved" | "approve_original_merchant" | "approve_global_merchant" | "reject_global_merchant" | "create_global_merchant" | "fetch_global_merchant_no_recommendation" | "save_vendor_renamed" | "save_vendor_sent_for_review" | "save_vendor_marked_as_employee" | "save_vendor_marked_as_local_contractor" | "charge_card_setup" | "charge_card_accept_term" | "charge_card_receipt_upload" | "charge_card_resend_invite" | "charge_card_revoke_invite" | "card_policy_created" | "card_policy_updated" | "card_policy_deleted" | "charge_card_update_limit" | "charge_cards_update_limit" | "close_charge_card" | "lock_charge_card" | "lock_charge_card_card_user" | "lock_charge_cards" | "unlock_charge_card" | "unlock_charge_card_card_user" | "unlock_charge_cards" | "close_charge_cards" | "revoke_invite_charge_cards" | "charge_card_express_interest" | "create_schedule" | "save_schedule" | "delete_schedule" | "ignore_schedule" | "revert_schedule" | "ignore_accrual" | "revert_accrual" | "save_task_detail" | "fetch_task_detail" | "delete_task" | "archive_task" | "snooze_task" | "unsnooze_task" | "create_tag" | "delete_tag" | "update_charge_card" | "update_charge_card_name" | "update_charge_card_name_card_user" | "issue_charge_card" | "issue_charge_cards" | "notification_settings_saved" | "referral_invite_sent" | "notification_mark_as_read" | "mark_as_complete_schedule" | "cancel_journal_entry" | "settings_accounting_accounts_updated" | "create_card_setup" | "confirm_card_setup" | "add_card_payment_source" | "fetch_payment_sources" | "task_assigned_toast_notification" | "task_due_tomorrow_toast_notification" | "task_deleted_toast_notification" | "task_archived_toast_notification" | "task_overdue_toast_notification" | "task_overdue_toast_notification_creator" | "task_notification_count" | "task_activities_toast_notification" | "task_created_toast_notification" | "task_group_creation_success" | "task_group_deletion_success" | "task_group_update_success" | "primary_funding_account_updated" | "task_time_spent_validation" | "missing_receipts_attachment" | "flux_analysis_unreviewed" | "flux_analysis_reviewed" | "receipt_match" | "receipts_upload" | "receipts_bulk_match" | "billing_address_view" | "express_pay_submit" | "exclude_transaction" | "reconcile" | "save_reconcile_for_later" | "recon_transaction_categorize" | "recon_transaction_match" | "update_debit_card_pin_attempt" | "set_debit_card_pin" | "ai_cfo_create_session_and_submit" | "ai_cfo_chat_session_deleted" | "charge_card_auto_pay_enable" | "charge_card_auto_pay_disable" | "treasury_setup" | "treasury_accept_term" | "treasury_transfer_money" | "treasury_transfer_money_failed" | "auto_transfer_rule_create" | "auto_transfer_rule_update" | "auto_transfer_rule_delete" | "auto_transfer_rule_pause" | "auto_transfer_rule_resume" | "treasury_update_portfolio_allocation" | "send_email_magic_link_to_user" | "complete_profile_done" | "create_transfer_entry" | "reports_resync" | "invalid_phone_number" | "transactions_categorized_updated_failed" | "transaction_categorized_updated_failed" | "transactionsCategorized_transactionsUpdated" | "transactionsCategorized_transactionUpdated" | "transactionCategorized_transactionsUpdated" | "transactionCategorized_transactionUpdated" | "transactionsCategorized_transactionsFailed" | "transactionsCategorized_transactionFailed" | "transactionCategorized_transactionsFailed" | "transactionCategorized_transactionFailed" | "transactionsUpdated_transactionsFailed" | "transactionsUpdated_transactionFailed" | "transactionUpdated_transactionsFailed" | "transactionUpdated_transactionFailed" | "transactionsCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionsUpdated_transactionFailed" | "transactionsCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionUpdated_transactionFailed" | "transactionCategorized_transactionsUpdated_transactionFailed" | "transactionCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionUpdated_transactionFailed" | "accounting_classes_enabled_update" | "accounting_projects_enabled_update" | "accounting_projects_qbo_not_enabled" | "capitalization_threshold_update" | "account_excluded_from_reconciliation" | "account_included_in_reconciliation" | "confirm_statement_mapping" | "statement_parsing_in_progress" | "statement_parsing_complete" | "ai_accountant_trigger_job" | "oauth_consent_approve" | "oauth_consent_invalid_request" | "credit_agent_update_profile" | "credit_agent_save_macro" | "credit_agent_schedule_cron" | "create_sub_task" | "qbo_connection_already_linked" | "qbo_connection_failed" | "accounting_projects_qbo_reconnect_failed" | "product_services_update" | "qbo_realm_id_update" | "invoicing_dunning_case_resolved" | "invoicing_dunning_retry" | "invoicing_dunning_cancel" | "invoicing_dunning_settings_save" | "invoicing_qbo_backfill" | "invoicing_qbo_sync_health_retry" | "invoicing_qbo_settings_save" | "invoicing_branding_save" | "invoicing_discount_archive" | "invoicing_discount_unarchive" | "invoicing_discount_delete" | "invoicing_invoice_reminder_sent" | "invoicing_invoice_regenerated" | "invoicing_invoice_voided" | "invoicing_catalog_item_saved" | "invoicing_customer_saved" | "invoicing_subscription_saved" | "invoicing_coupon_saved" | "invoicing_invoice_saved" | "invoicing_credit_note_saved" | "invoicing_payment_recorded" | "invoicing_subscription_activated" | "invoicing_subscription_cancellation_removed" | "invoicing_subscription_cancelled" | "invoicing_subscription_non_renewing" | "invoicing_subscription_paused" | "invoicing_subscription_reactivated" | "invoicing_subscription_resumed" | "invoicing_subscription_term_end_changed";
43
43
  messageText: "notification" | "failed" | "success";
44
44
  type: "error" | "success" | "info";
45
45
  variables: {