@zeniai/client-epic-state 5.2.7-betaAK2 → 5.2.7-betaRD2

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 (165) hide show
  1. package/lib/commonStateTypes/selectorTypes/pickAndMergeForecastSection.d.ts +0 -0
  2. package/lib/commonStateTypes/selectorTypes/pickAndMergeForecastSection.js +1 -0
  3. package/lib/entity/invoicing/coupon/couponConstants.d.ts +11 -0
  4. package/lib/entity/invoicing/coupon/couponConstants.js +29 -0
  5. package/lib/entity/invoicing/invoicingCommonPayload.d.ts +0 -22
  6. package/lib/entity/invoicing/invoicingCommonPayload.js +5 -22
  7. package/lib/entity/jeSchedules/jeScheduleHelper.d.ts +1 -0
  8. package/lib/entity/jeSchedules/jeScheduleHelper.js +7 -0
  9. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +66 -1
  10. package/lib/entity/jeSchedules/jeSchedulesPayload.js +135 -0
  11. package/lib/entity/jeSchedules/jeSchedulesReducer.d.ts +4 -2
  12. package/lib/entity/jeSchedules/jeSchedulesReducer.js +30 -2
  13. package/lib/entity/jeSchedules/jeSchedulesSelector.d.ts +11 -2
  14. package/lib/entity/jeSchedules/jeSchedulesSelector.js +38 -3
  15. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +79 -1
  16. package/lib/entity/jeSchedules/jeSchedulesTypes.d.ts +24 -1
  17. package/lib/entity/jeSchedules/jeSchedulesTypes.js +88 -1
  18. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  19. package/lib/entity/snackbar/snackbarTypes.js +3 -0
  20. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.d.ts +2 -0
  21. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.js +2 -0
  22. package/lib/entity/transaction/stateTypes/scheduleTransaction.d.ts +2 -0
  23. package/lib/epic.d.ts +9 -1
  24. package/lib/epic.js +16 -0
  25. package/lib/esm/commonStateTypes/selectorTypes/pickAndMergeForecastSection.js +1 -0
  26. package/lib/esm/entity/invoicing/coupon/couponConstants.js +26 -0
  27. package/lib/esm/entity/invoicing/invoicingCommonPayload.js +5 -22
  28. package/lib/esm/entity/jeSchedules/jeScheduleHelper.js +6 -0
  29. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +135 -1
  30. package/lib/esm/entity/jeSchedules/jeSchedulesReducer.js +30 -2
  31. package/lib/esm/entity/jeSchedules/jeSchedulesSelector.js +36 -2
  32. package/lib/esm/entity/jeSchedules/jeSchedulesTypes.js +78 -0
  33. package/lib/esm/entity/snackbar/snackbarTypes.js +3 -0
  34. package/lib/esm/entity/transaction/payloadTypes/scheduleTransactionPayload.js +2 -0
  35. package/lib/esm/epic.js +16 -0
  36. package/lib/esm/index.js +16 -9
  37. package/lib/esm/view/accountList/accountListReducer.js +1 -0
  38. package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +6 -3
  39. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +41 -5
  40. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchOneTimeAccrualEpic.js +45 -0
  41. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/ignoreRecommendedJeScheduleEpic.js +14 -2
  42. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.js +99 -0
  43. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +25 -0
  44. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +110 -0
  45. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +79 -0
  46. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.js +139 -0
  47. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.js +106 -0
  48. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +22 -0
  49. package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/backgroundRefetchReviewTabEpic.js +1 -0
  50. package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +1 -0
  51. package/lib/esm/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +140 -0
  52. package/lib/esm/view/expenseAutomationView/payload/jeSchedulesPayload.js +55 -0
  53. package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +306 -29
  54. package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +56 -11
  55. package/lib/esm/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +1 -0
  56. package/lib/esm/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +106 -0
  57. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +294 -22
  58. package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +2 -1
  59. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +5 -6
  60. package/lib/esm/view/expenseAutomationView/types/transactionGroup.js +21 -0
  61. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +1 -2
  62. package/lib/esm/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.js +0 -2
  63. package/lib/esm/view/invoicing/invoicingQboView/epics/fetchInvoicingAccountingPickersEpic.js +5 -10
  64. package/lib/esm/view/invoicing/invoicingQboView/epics/fetchInvoicingQboAccountsEpic.js +25 -0
  65. package/lib/esm/view/invoicing/invoicingQboView/epics/fetchInvoicingQboClassesEpic.js +15 -0
  66. package/lib/esm/view/invoicing/invoicingQboView/invoicingQboViewSelector.js +3 -27
  67. package/lib/esm/view/invoicing/settingsView/settingsViewSelector.js +3 -7
  68. package/lib/esm/view/scheduleView/scheduleListView/epics/fetchAccruedScheduleListEpic.js +1 -1
  69. package/lib/esm/view/scheduleView/scheduleListView/epics/fetchDownloadSchedulesEpic.js +7 -2
  70. package/lib/esm/view/scheduleView/scheduleListView/scheduleListReducer.js +5 -3
  71. package/lib/esm/view/spendManagement/treasury/treasurySetUp/epic/updateTreasuryPromoIntroClosedByOutsideClickEpic.js +18 -0
  72. package/lib/esm/view/spendManagement/treasury/treasurySetUp/epic/updateTreasuryPromoRemindMeLaterClickedEpic.js +18 -0
  73. package/lib/esm/view/spendManagement/treasury/treasurySetUp/epic/updateTreasuryVideoViewedEpic.js +18 -0
  74. package/lib/esm/view/zeniAccountsPromoCard/zeniAccountsPromoCardEpic.js +16 -0
  75. package/lib/esm/view/zeniAccountsPromoCard/zeniAccountsPromoCardPayload.js +1 -0
  76. package/lib/esm/view/zeniAccountsPromoCard/zeniAccountsPromoCardReducer.js +60 -0
  77. package/lib/esm/view/zeniAccountsPromoCard/zeniAccountsPromoCardSelector.js +12 -0
  78. package/lib/esm/view/zeniAccountsPromoCard/zeniAccountsPromoCardState.js +1 -0
  79. package/lib/index.d.ts +19 -13
  80. package/lib/index.js +97 -48
  81. package/lib/view/accountList/accountListReducer.js +1 -0
  82. package/lib/view/accountList/accountListState.d.ts +1 -1
  83. package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +6 -3
  84. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.d.ts +3 -2
  85. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +39 -3
  86. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchOneTimeAccrualEpic.d.ts +20 -0
  87. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchOneTimeAccrualEpic.js +49 -0
  88. package/lib/view/expenseAutomationView/epics/jeSchedule/ignoreRecommendedJeScheduleEpic.js +14 -2
  89. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.d.ts +8 -0
  90. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.js +103 -0
  91. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.d.ts +8 -0
  92. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +29 -0
  93. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.d.ts +45 -0
  94. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +114 -0
  95. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.d.ts +8 -0
  96. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +83 -0
  97. package/lib/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.d.ts +12 -0
  98. package/lib/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.js +146 -0
  99. package/lib/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.d.ts +64 -0
  100. package/lib/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.js +110 -0
  101. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.d.ts +6 -0
  102. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +26 -0
  103. package/lib/view/expenseAutomationView/epics/transactionCategorization/backgroundRefetchReviewTabEpic.js +1 -0
  104. package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +1 -0
  105. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.d.ts +36 -0
  106. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +145 -0
  107. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  108. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.d.ts +72 -3
  109. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.js +58 -1
  110. package/lib/view/expenseAutomationView/payload/transactionCategorizationPayload.d.ts +11 -0
  111. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +91 -12
  112. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +308 -29
  113. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +1 -1
  114. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +6 -3
  115. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +57 -12
  116. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.d.ts +42 -0
  117. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +2 -0
  118. package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +36 -7
  119. package/lib/view/expenseAutomationView/selectorTypes/transactionsViewSelectorTypes.d.ts +2 -0
  120. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.d.ts +21 -0
  121. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +112 -0
  122. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.d.ts +34 -0
  123. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +302 -21
  124. package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +2 -1
  125. package/lib/view/expenseAutomationView/types/completedSubTab.d.ts +1 -1
  126. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +82 -8
  127. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +8 -8
  128. package/lib/view/expenseAutomationView/types/reconciliationViewState.d.ts +1 -1
  129. package/lib/view/expenseAutomationView/types/transactionGroup.d.ts +21 -0
  130. package/lib/view/expenseAutomationView/types/transactionGroup.js +25 -0
  131. package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +11 -0
  132. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.d.ts +0 -5
  133. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +0 -1
  134. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.d.ts +0 -1
  135. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.js +0 -2
  136. package/lib/view/invoicing/invoicingQboView/epics/fetchInvoicingAccountingPickersEpic.js +5 -10
  137. package/lib/view/invoicing/invoicingQboView/epics/fetchInvoicingQboAccountsEpic.d.ts +6 -0
  138. package/lib/view/invoicing/invoicingQboView/epics/fetchInvoicingQboAccountsEpic.js +29 -0
  139. package/lib/view/invoicing/invoicingQboView/epics/fetchInvoicingQboClassesEpic.d.ts +6 -0
  140. package/lib/view/invoicing/invoicingQboView/epics/fetchInvoicingQboClassesEpic.js +19 -0
  141. package/lib/view/invoicing/invoicingQboView/invoicingQboViewSelector.d.ts +1 -9
  142. package/lib/view/invoicing/invoicingQboView/invoicingQboViewSelector.js +4 -30
  143. package/lib/view/invoicing/settingsView/settingsViewSelector.d.ts +4 -11
  144. package/lib/view/invoicing/settingsView/settingsViewSelector.js +3 -7
  145. package/lib/view/scheduleView/scheduleListView/epics/fetchAccruedScheduleListEpic.js +1 -1
  146. package/lib/view/scheduleView/scheduleListView/epics/fetchDownloadSchedulesEpic.js +7 -2
  147. package/lib/view/scheduleView/scheduleListView/scheduleListReducer.d.ts +4 -2
  148. package/lib/view/scheduleView/scheduleListView/scheduleListReducer.js +5 -3
  149. package/lib/view/spendManagement/treasury/treasurySetUp/epic/updateTreasuryPromoIntroClosedByOutsideClickEpic.d.ts +8 -0
  150. package/lib/view/spendManagement/treasury/treasurySetUp/epic/updateTreasuryPromoIntroClosedByOutsideClickEpic.js +22 -0
  151. package/lib/view/spendManagement/treasury/treasurySetUp/epic/updateTreasuryPromoRemindMeLaterClickedEpic.d.ts +8 -0
  152. package/lib/view/spendManagement/treasury/treasurySetUp/epic/updateTreasuryPromoRemindMeLaterClickedEpic.js +22 -0
  153. package/lib/view/spendManagement/treasury/treasurySetUp/epic/updateTreasuryVideoViewedEpic.d.ts +8 -0
  154. package/lib/view/spendManagement/treasury/treasurySetUp/epic/updateTreasuryVideoViewedEpic.js +22 -0
  155. package/lib/view/zeniAccountsPromoCard/zeniAccountsPromoCardEpic.d.ts +13 -0
  156. package/lib/view/zeniAccountsPromoCard/zeniAccountsPromoCardEpic.js +20 -0
  157. package/lib/view/zeniAccountsPromoCard/zeniAccountsPromoCardPayload.d.ts +11 -0
  158. package/lib/view/zeniAccountsPromoCard/zeniAccountsPromoCardPayload.js +2 -0
  159. package/lib/view/zeniAccountsPromoCard/zeniAccountsPromoCardReducer.d.ts +7 -0
  160. package/lib/view/zeniAccountsPromoCard/zeniAccountsPromoCardReducer.js +64 -0
  161. package/lib/view/zeniAccountsPromoCard/zeniAccountsPromoCardSelector.d.ts +12 -0
  162. package/lib/view/zeniAccountsPromoCard/zeniAccountsPromoCardSelector.js +15 -0
  163. package/lib/view/zeniAccountsPromoCard/zeniAccountsPromoCardState.d.ts +9 -0
  164. package/lib/view/zeniAccountsPromoCard/zeniAccountsPromoCardState.js +2 -0
  165. package/package.json +1 -1
@@ -1,5 +1,60 @@
1
1
  import { DEFAULT_DATE_FORMAT } from '../../../commonStateTypes/timePeriod';
2
+ import { getClassList } from '../../classList/classListSelector';
2
3
  import { mapScheduleTransactionToBaseScheduleTransactionPayload, mapVendorToVendorPayload, } from '../../scheduleView/scheduleDetailView/scheduleDetailPayload';
4
+ const BALANCE_SHEET_CLASS_LABEL = 'balance_sheet';
5
+ const SERVICE_MONTH_FORMAT = 'YYYY-MM';
6
+ /**
7
+ * The credit line is the accrued liability, which always sits on the balance sheet — the
8
+ * recurring accrued path resolves the same class the same way (see
9
+ * prepareNewScheduleAccruedDetailPayload). Omitted rather than sent empty when the tenant has
10
+ * no balance_sheet class, since the API treats the field as optional.
11
+ */
12
+ export const prepareCreateOneTimeAccrualPayload = (state, localData) => {
13
+ const { classListState, classState } = state;
14
+ const balanceSheetClass = getClassList(classState, classListState).classes.find((accountingClass) => accountingClass.labels?.includes(BALANCE_SHEET_CLASS_LABEL) === true);
15
+ // reverse_next_month alone decides reversal_policy server-side, so reversal_policy is
16
+ // deliberately not sent — the API documents it only as an alternate way to say on_bill_match,
17
+ // and sending both would be two sources of truth for one toggle.
18
+ const reversalFields = localData.reverseNextMonth
19
+ ? {
20
+ reverse_next_month: true,
21
+ expected_reversal_date: getExpectedReversalDate(localData.serviceMonth).format(DEFAULT_DATE_FORMAT),
22
+ }
23
+ : { reverse_next_month: false };
24
+ return {
25
+ vendor_id: localData.vendorId,
26
+ vendor_name: localData.vendorName,
27
+ service_month: localData.serviceMonth.format(SERVICE_MONTH_FORMAT),
28
+ amount: localData.amount,
29
+ memo: localData.memo,
30
+ je_debit_account_id: localData.debitAccountId,
31
+ je_credit_account_id: localData.creditAccountId,
32
+ ...(localData.debitAccountName != null
33
+ ? { je_debit_account_name: localData.debitAccountName }
34
+ : {}),
35
+ ...(localData.creditAccountName != null
36
+ ? { je_credit_account_name: localData.creditAccountName }
37
+ : {}),
38
+ ...(localData.debitClassId != null
39
+ ? { je_debit_accounting_class_id: localData.debitClassId }
40
+ : {}),
41
+ ...(localData.debitClassName != null
42
+ ? { je_debit_accounting_class_name: localData.debitClassName }
43
+ : {}),
44
+ ...(balanceSheetClass != null
45
+ ? {
46
+ je_credit_accounting_class_id: balanceSheetClass.classId,
47
+ je_credit_accounting_class_name: balanceSheetClass.className,
48
+ }
49
+ : {}),
50
+ ...reversalFields,
51
+ };
52
+ };
53
+ /**
54
+ * The API defaults this to the 1st of the month after service_month. We send it explicitly so the
55
+ * date the form promised the user is the date that gets stored.
56
+ */
57
+ export const getExpectedReversalDate = (serviceMonth) => serviceMonth.add(1, 'month').startOf('month');
3
58
  export const prepareIgnoreSchedulePayload = (scheduleType, jeScheduleTransaction, state) => {
4
59
  const { vendorState } = state;
5
60
  const { vendor, currencyCode, currencySymbol, baseTransaction, status, balanceAsOfToday, period, startDate, endDate, jeCredit, jeDebit, } = jeScheduleTransaction;
@@ -2,9 +2,16 @@ import { createSlice } from '@reduxjs/toolkit';
2
2
  import { geNestedAccountIDHierarchyForReport } from '../../../commonStateTypes/accountView/getNestedAccountIDHierarchyForReport';
3
3
  import { toMonthYearPeriodId, } from '../../../commonStateTypes/timePeriod';
4
4
  import { mapAccountBasePayloadToAccountBase, mapAccountMetadataPayloadToAccountMetadata, } from '../../../entity/account/accountPayload';
5
- import { getJEScheduleTransactionDetailKeyPayload, } from '../../../entity/jeSchedules/jeSchedulesPayload';
5
+ import { generateJEOneTimeAccrualKey } from '../../../entity/jeSchedules/jeScheduleHelper';
6
+ import { getJEScheduleKey, getJEScheduleTransactionDetailKeyPayload, } from '../../../entity/jeSchedules/jeSchedulesPayload';
6
7
  import { clearAll } from '../../../rootActions';
7
8
  import { mapAccountTypeRecommendationPayloadToAccountRecommendationByType, } from '../../accountMappingView/accountTypeRecommendation/accountTypeRecommendationPayload';
9
+ import { MIN_NEW_SCHEDULE_SEARCH_LENGTH, getJESchedulePeriodTabKey, } from '../types/jeSchedulesViewState';
10
+ function removeKeyFromEveryTabSlot(keysByPeriodAndTab, keyToRemove) {
11
+ for (const periodTabKey of Object.keys(keysByPeriodAndTab)) {
12
+ keysByPeriodAndTab[periodTabKey] = keysByPeriodAndTab[periodTabKey].filter((jeScheduleKey) => jeScheduleKey !== keyToRemove);
13
+ }
14
+ }
8
15
  export const accountSettingsInitialState = {
9
16
  localData: {
10
17
  selectedPrepaidExpensesAccountIds: [],
@@ -36,16 +43,37 @@ export const accountSettingsInitialState = {
36
43
  accruedExpensesNestedAccountListHierarchy: [],
37
44
  accruedExpensesRecommendations: [],
38
45
  };
46
+ export const getBaseNewScheduleLocalData = (scheduleType) => ({
47
+ scheduleType,
48
+ jeScheduleDetails: [],
49
+ });
50
+ export const newScheduleInitialState = {
51
+ fixed_assets: getBaseNewScheduleLocalData('fixed_assets'),
52
+ prepaid_expenses: getBaseNewScheduleLocalData('prepaid_expenses'),
53
+ };
54
+ export const searchTransactionsInitialState = {
55
+ searchResults: [],
56
+ fetchState: 'Not-Started',
57
+ error: undefined,
58
+ };
39
59
  export const initialState = {
40
- jeScheduleTransactionKeysByPeriod: {},
41
- failedJeScheduleTransactionKeysByPeriod: {},
60
+ jeScheduleTransactionKeysByPeriodAndTab: {},
61
+ jeScheduleAccruedKeysByPeriodAndTab: {},
62
+ jeScheduleOneTimeAccrualKeysByPeriodAndTab: {},
63
+ failedJeScheduleTransactionKeysByPeriodAndTab: {},
42
64
  postStatusById: {},
43
65
  ignoreStatusById: {},
66
+ revertStatusById: {},
44
67
  jeScheduleLocalDataById: {},
68
+ oneTimeAccrualActionStatusById: {},
69
+ oneTimeAccrualFetchStatusById: {},
45
70
  uiState: {
46
- searchString: '',
71
+ createdGroupCollapsed: false,
72
+ pendingGroupCollapsed: false,
47
73
  scrollPosition: { scrollTop: 0, scrollLeft: undefined },
48
- selectedMainTab: 'pending_review',
74
+ searchString: '',
75
+ selectedJETypeFilter: null,
76
+ selectedPageTab: 'schedules',
49
77
  sortKey: 'transactionDate',
50
78
  sortOrder: 'descending',
51
79
  totalCount: 0,
@@ -56,6 +84,14 @@ export const initialState = {
56
84
  error: undefined,
57
85
  },
58
86
  accountSettings: accountSettingsInitialState,
87
+ newSchedule: {
88
+ createOneTimeAccrualStatus: { fetchState: 'Not-Started', error: undefined },
89
+ newScheduleState: newScheduleInitialState,
90
+ saveStatus: { fetchState: 'Not-Started', error: undefined },
91
+ searchTransactions: searchTransactionsInitialState,
92
+ fetchState: 'Not-Started',
93
+ error: undefined,
94
+ },
59
95
  fetchState: 'Not-Started',
60
96
  error: undefined,
61
97
  hasValidState() {
@@ -100,9 +136,12 @@ const expenseAutomationJESchedulesView = createSlice({
100
136
  },
101
137
  },
102
138
  fetchJeSchedulesSuccess(draft, action) {
103
- const { jeSchedules, selectedPeriod, failedJeSchedules, refreshViewInBackground, } = action.payload;
139
+ const { jeSchedules, selectedPeriod, selectedPageTab, failedJeSchedules, accruedJeSchedules, oneTimeAccruals, refreshViewInBackground, } = action.payload;
140
+ const periodTabKey = getJESchedulePeriodTabKey(selectedPageTab, toMonthYearPeriodId(selectedPeriod));
104
141
  const jeScheduleTransactionKeys = jeSchedules.map((schedules) => getJEScheduleTransactionDetailKeyPayload(schedules.base_transaction));
105
142
  const failedJeScheduleTransactionKeys = failedJeSchedules.map((schedules) => getJEScheduleTransactionDetailKeyPayload(schedules.base_transaction));
143
+ const jeScheduleAccruedKeys = accruedJeSchedules.map((schedule) => getJEScheduleKey(schedule));
144
+ const jeScheduleOneTimeAccrualKeys = oneTimeAccruals.map((accrual) => generateJEOneTimeAccrualKey(accrual._id));
106
145
  if (refreshViewInBackground === true &&
107
146
  draft.refreshStatus.fetchState === 'In-Progress') {
108
147
  draft.refreshStatus = { fetchState: 'Completed', error: undefined };
@@ -111,19 +150,28 @@ const expenseAutomationJESchedulesView = createSlice({
111
150
  draft.fetchState = 'Completed';
112
151
  draft.error = undefined;
113
152
  }
114
- draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = jeScheduleTransactionKeys;
115
- draft.failedJeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = failedJeScheduleTransactionKeys;
153
+ draft.jeScheduleTransactionKeysByPeriodAndTab[periodTabKey] =
154
+ jeScheduleTransactionKeys;
155
+ draft.jeScheduleAccruedKeysByPeriodAndTab[periodTabKey] =
156
+ jeScheduleAccruedKeys;
157
+ draft.jeScheduleOneTimeAccrualKeysByPeriodAndTab[periodTabKey] =
158
+ jeScheduleOneTimeAccrualKeys;
159
+ draft.failedJeScheduleTransactionKeysByPeriodAndTab[periodTabKey] =
160
+ failedJeScheduleTransactionKeys;
116
161
  },
117
162
  fetchJeSchedulesFailure(draft, action) {
118
- const { status, selectedPeriod } = action.payload;
163
+ const { status, selectedPeriod, selectedPageTab } = action.payload;
164
+ const periodTabKey = getJESchedulePeriodTabKey(selectedPageTab, toMonthYearPeriodId(selectedPeriod));
119
165
  if (draft.refreshStatus.fetchState === 'In-Progress') {
120
166
  draft.refreshStatus = { fetchState: 'Error', error: status };
121
167
  }
122
168
  else {
123
169
  draft.fetchState = 'Error';
124
170
  draft.error = status;
171
+ draft.jeScheduleTransactionKeysByPeriodAndTab[periodTabKey] = [];
172
+ draft.jeScheduleAccruedKeysByPeriodAndTab[periodTabKey] = [];
173
+ draft.jeScheduleOneTimeAccrualKeysByPeriodAndTab[periodTabKey] = [];
125
174
  }
126
- draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = [];
127
175
  },
128
176
  retryJeSchedule(draft, action) {
129
177
  const { scheduledJournalEntryID } = action.payload;
@@ -159,11 +207,13 @@ const expenseAutomationJESchedulesView = createSlice({
159
207
  };
160
208
  },
161
209
  ignoreRecommendedJeSchedule: {
162
- prepare(jeScheduleTransactionKey, scheduleType) {
210
+ prepare(jeScheduleTransactionKey, scheduleType, reason, note) {
163
211
  return {
164
212
  payload: {
165
213
  jeScheduleTransactionKey,
166
214
  scheduleType,
215
+ reason,
216
+ note,
167
217
  },
168
218
  };
169
219
  },
@@ -179,6 +229,41 @@ const expenseAutomationJESchedulesView = createSlice({
179
229
  };
180
230
  },
181
231
  },
232
+ revertJeSchedule: {
233
+ // jeScheduleTransactionKey is a JEScheduleKey for an accrued schedule, which has no base
234
+ // transaction to derive a transaction key from. It is only ever used as an opaque row
235
+ // identifier here -- for the row's spinner and for dropping the row from the list -- so one
236
+ // action serves both shapes rather than two near-identical ones.
237
+ prepare(jeScheduleId, jeScheduleTransactionKey, scheduleType, reason, note) {
238
+ return {
239
+ payload: {
240
+ jeScheduleId,
241
+ jeScheduleTransactionKey,
242
+ scheduleType,
243
+ reason,
244
+ note,
245
+ },
246
+ };
247
+ },
248
+ reducer(draft, action) {
249
+ draft.revertStatusById[action.payload.jeScheduleTransactionKey] = {
250
+ fetchState: 'In-Progress',
251
+ error: undefined,
252
+ };
253
+ },
254
+ },
255
+ revertJeScheduleSuccess(draft, action) {
256
+ draft.revertStatusById[action.payload.jeScheduleTransactionKey] = {
257
+ fetchState: 'Completed',
258
+ error: undefined,
259
+ };
260
+ },
261
+ revertJeScheduleFailure(draft, action) {
262
+ draft.revertStatusById[action.payload.jeScheduleTransactionKey] = {
263
+ fetchState: 'Error',
264
+ error: action.payload.status,
265
+ };
266
+ },
182
267
  ignoreRecommendedJeScheduleSuccess: {
183
268
  reducer(draft, action) {
184
269
  const { jeScheduleTransactionKey } = action.payload;
@@ -211,17 +296,18 @@ const expenseAutomationJESchedulesView = createSlice({
211
296
  };
212
297
  },
213
298
  updateJeScheduleTransactionKeys: {
214
- prepare(jeScheduleKeys, selectedPeriod) {
299
+ prepare(jeScheduleKeys, selectedPeriod, selectedPageTab) {
215
300
  return {
216
301
  payload: {
217
302
  jeScheduleKeys: jeScheduleKeys,
218
303
  selectedPeriod: selectedPeriod,
304
+ selectedPageTab: selectedPageTab,
219
305
  },
220
306
  };
221
307
  },
222
308
  reducer(draft, action) {
223
- const { selectedPeriod, jeScheduleKeys } = action.payload;
224
- draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = jeScheduleKeys;
309
+ const { selectedPeriod, selectedPageTab, jeScheduleKeys } = action.payload;
310
+ draft.jeScheduleTransactionKeysByPeriodAndTab[getJESchedulePeriodTabKey(selectedPageTab, toMonthYearPeriodId(selectedPeriod))] = jeScheduleKeys;
225
311
  },
226
312
  },
227
313
  removeJeScheduleTransactionKey: {
@@ -234,12 +320,20 @@ const expenseAutomationJESchedulesView = createSlice({
234
320
  };
235
321
  },
236
322
  reducer(draft, action) {
237
- const { selectedPeriod, jeScheduleKey } = action.payload;
238
- const prevData = [
239
- ...(draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] ?? []),
240
- ];
241
- const filteredKeys = prevData.filter((jeKey) => jeKey !== jeScheduleKey);
242
- draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = filteredKeys;
323
+ const { jeScheduleKey } = action.payload;
324
+ // Dropped from every tab's slot, not just the visible one: once a schedule is ignored or
325
+ // resolved it must not reappear when the user switches tabs and hits a cached list.
326
+ removeKeyFromEveryTabSlot(draft.jeScheduleTransactionKeysByPeriodAndTab, jeScheduleKey);
327
+ },
328
+ },
329
+ removeJeAccruedScheduleKey: {
330
+ prepare(jeAccruedScheduleKey) {
331
+ return { payload: { jeAccruedScheduleKey } };
332
+ },
333
+ reducer(draft, action) {
334
+ // Accrued keys live in their own per-tab map, so removeJeScheduleTransactionKey cannot drop
335
+ // them -- a reverted accrued schedule stayed on the list until the next fetch.
336
+ removeKeyFromEveryTabSlot(draft.jeScheduleAccruedKeysByPeriodAndTab, action.payload.jeAccruedScheduleKey);
243
337
  },
244
338
  },
245
339
  removeFailedJeScheduleTransactionKey: {
@@ -252,12 +346,8 @@ const expenseAutomationJESchedulesView = createSlice({
252
346
  };
253
347
  },
254
348
  reducer(draft, action) {
255
- const { selectedPeriod, failedJeScheduleKey } = action.payload;
256
- const prevData = [
257
- ...(draft.failedJeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] ?? []),
258
- ];
259
- const filteredKeys = prevData.filter((jeKey) => jeKey !== failedJeScheduleKey);
260
- draft.failedJeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = filteredKeys;
349
+ const { failedJeScheduleKey } = action.payload;
350
+ removeKeyFromEveryTabSlot(draft.failedJeScheduleTransactionKeysByPeriodAndTab, failedJeScheduleKey);
261
351
  },
262
352
  },
263
353
  initializeJeScheduleLocalData: {
@@ -369,6 +459,182 @@ const expenseAutomationJESchedulesView = createSlice({
369
459
  clearJeAccountSettingsLocalData(draft) {
370
460
  draft.accountSettings.localData = accountSettingsInitialState.localData;
371
461
  },
462
+ initializeNewSchedule: {
463
+ prepare({ scheduleType, shouldResetEnteredData = true, }) {
464
+ return { payload: { scheduleType, shouldResetEnteredData } };
465
+ },
466
+ reducer() {
467
+ // Purely an epic-trigger action — the epic fans out the account/class
468
+ // list fetches, and clears entered data only when asked to.
469
+ },
470
+ },
471
+ resetNewScheduleLocalData: {
472
+ prepare({ scheduleType, }) {
473
+ return { payload: { scheduleType } };
474
+ },
475
+ reducer(draft, action) {
476
+ const { scheduleType } = action.payload;
477
+ draft.newSchedule.newScheduleState[scheduleType] =
478
+ getBaseNewScheduleLocalData(scheduleType);
479
+ },
480
+ },
481
+ updateNewScheduleLocalData(draft, action) {
482
+ const { scheduleType, localData } = action.payload;
483
+ draft.newSchedule.newScheduleState[scheduleType] = {
484
+ ...draft.newSchedule.newScheduleState[scheduleType],
485
+ ...localData,
486
+ };
487
+ },
488
+ searchTransactionsForNewSchedule: {
489
+ prepare({ query, scheduleType, }) {
490
+ return { payload: { query, scheduleType } };
491
+ },
492
+ reducer(draft, action) {
493
+ const trimmed = action.payload.query.trim();
494
+ // Cleared or too-short query: no API (see epic) — reset immediately.
495
+ if (trimmed.length < MIN_NEW_SCHEDULE_SEARCH_LENGTH) {
496
+ draft.newSchedule.searchTransactions = searchTransactionsInitialState;
497
+ return;
498
+ }
499
+ draft.newSchedule.searchTransactions = {
500
+ ...draft.newSchedule.searchTransactions,
501
+ searchString: action.payload.query,
502
+ fetchState: 'In-Progress',
503
+ };
504
+ },
505
+ },
506
+ searchTransactionsForNewScheduleSuccess(draft, action) {
507
+ draft.newSchedule.searchTransactions = {
508
+ ...draft.newSchedule.searchTransactions,
509
+ searchResults: action.payload.searchResults,
510
+ fetchState: 'Completed',
511
+ error: undefined,
512
+ };
513
+ },
514
+ searchTransactionsForNewScheduleFailure(draft, action) {
515
+ draft.newSchedule.searchTransactions = {
516
+ ...draft.newSchedule.searchTransactions,
517
+ fetchState: 'Error',
518
+ error: action.payload.status,
519
+ };
520
+ },
521
+ clearSearchTransactionsForNewSchedule(draft) {
522
+ draft.newSchedule.searchTransactions = searchTransactionsInitialState;
523
+ },
524
+ saveNewSchedule: {
525
+ prepare({ scheduleType, }) {
526
+ return { payload: { scheduleType } };
527
+ },
528
+ reducer(draft) {
529
+ draft.newSchedule.saveStatus = {
530
+ fetchState: 'In-Progress',
531
+ error: undefined,
532
+ };
533
+ },
534
+ },
535
+ saveNewScheduleSuccess(draft) {
536
+ draft.newSchedule.saveStatus = {
537
+ fetchState: 'Completed',
538
+ error: undefined,
539
+ };
540
+ },
541
+ saveNewScheduleFailure(draft, action) {
542
+ draft.newSchedule.saveStatus = {
543
+ fetchState: 'Error',
544
+ error: action.payload.status,
545
+ };
546
+ },
547
+ createOneTimeAccrual: {
548
+ prepare(localData) {
549
+ return { payload: { localData } };
550
+ },
551
+ reducer(draft) {
552
+ draft.newSchedule.createOneTimeAccrualStatus = {
553
+ fetchState: 'In-Progress',
554
+ error: undefined,
555
+ };
556
+ },
557
+ },
558
+ createOneTimeAccrualSuccess(draft) {
559
+ draft.newSchedule.createOneTimeAccrualStatus = {
560
+ fetchState: 'Completed',
561
+ error: undefined,
562
+ };
563
+ },
564
+ createOneTimeAccrualFailure(draft, action) {
565
+ draft.newSchedule.createOneTimeAccrualStatus = {
566
+ fetchState: 'Error',
567
+ error: action.payload.status,
568
+ };
569
+ },
570
+ promoteOneTimeAccrual: {
571
+ prepare(accrualId, amount) {
572
+ return { payload: { accrualId, amount } };
573
+ },
574
+ reducer(draft, action) {
575
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
576
+ fetchState: 'In-Progress',
577
+ error: undefined,
578
+ };
579
+ },
580
+ },
581
+ revertOneTimeAccrual: {
582
+ prepare(accrualId, reason, note) {
583
+ return { payload: { accrualId, reason, note } };
584
+ },
585
+ reducer(draft, action) {
586
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
587
+ fetchState: 'In-Progress',
588
+ error: undefined,
589
+ };
590
+ },
591
+ },
592
+ ignoreOneTimeAccrual: {
593
+ prepare(accrualId, reason, note) {
594
+ return { payload: { accrualId, reason, note } };
595
+ },
596
+ reducer(draft, action) {
597
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
598
+ fetchState: 'In-Progress',
599
+ error: undefined,
600
+ };
601
+ },
602
+ },
603
+ fetchOneTimeAccrual: {
604
+ prepare(accrualId) {
605
+ return { payload: { accrualId } };
606
+ },
607
+ reducer(draft, action) {
608
+ draft.oneTimeAccrualFetchStatusById[action.payload.accrualId] = {
609
+ fetchState: 'In-Progress',
610
+ error: undefined,
611
+ };
612
+ },
613
+ },
614
+ fetchOneTimeAccrualSuccess(draft, action) {
615
+ draft.oneTimeAccrualFetchStatusById[action.payload.accrualId] = {
616
+ fetchState: 'Completed',
617
+ error: undefined,
618
+ };
619
+ },
620
+ fetchOneTimeAccrualFailure(draft, action) {
621
+ draft.oneTimeAccrualFetchStatusById[action.payload.accrualId] = {
622
+ fetchState: 'Error',
623
+ error: action.payload.status,
624
+ };
625
+ },
626
+ oneTimeAccrualActionSuccess(draft, action) {
627
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
628
+ fetchState: 'Completed',
629
+ error: undefined,
630
+ };
631
+ },
632
+ oneTimeAccrualActionFailure(draft, action) {
633
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
634
+ fetchState: 'Error',
635
+ error: action.payload.status,
636
+ };
637
+ },
372
638
  updateJESchedulesUIState(draft, action) {
373
639
  if (action.payload.sortKey != null) {
374
640
  draft.uiState.sortKey = action.payload.sortKey;
@@ -382,10 +648,21 @@ const expenseAutomationJESchedulesView = createSlice({
382
648
  if (action.payload.scrollPosition != null) {
383
649
  draft.uiState.scrollPosition = action.payload.scrollPosition;
384
650
  }
385
- if (action.payload.selectedMainTab != null) {
386
- draft.uiState.selectedMainTab = action.payload.selectedMainTab;
651
+ if (action.payload.selectedPageTab != null) {
652
+ draft.uiState.selectedPageTab = action.payload.selectedPageTab;
387
653
  }
388
654
  },
655
+ updateJEScheduleTypeFilter(draft, action) {
656
+ draft.uiState.selectedJETypeFilter = action.payload;
657
+ },
658
+ toggleJEPendingGroupCollapsed(draft) {
659
+ draft.uiState.pendingGroupCollapsed =
660
+ !draft.uiState.pendingGroupCollapsed;
661
+ },
662
+ toggleJECreatedGroupCollapsed(draft) {
663
+ draft.uiState.createdGroupCollapsed =
664
+ !draft.uiState.createdGroupCollapsed;
665
+ },
389
666
  clearExpenseAutomationJESchedulesView(draft) {
390
667
  Object.assign(draft, initialState);
391
668
  },
@@ -396,7 +673,7 @@ const expenseAutomationJESchedulesView = createSlice({
396
673
  });
397
674
  },
398
675
  });
399
- 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;
676
+ export const { clearExpenseAutomationJESchedulesView, clearJeAccountSettingsLocalData, clearJeScheduleLocalData, clearSearchTransactionsForNewSchedule, createOneTimeAccrual, createOneTimeAccrualFailure, createOneTimeAccrualSuccess, ignoreOneTimeAccrual, oneTimeAccrualActionFailure, oneTimeAccrualActionSuccess, promoteOneTimeAccrual, revertJeSchedule, revertJeScheduleFailure, revertJeScheduleSuccess, revertOneTimeAccrual, fetchAccountSettingsListForAccountTypes, fetchJeSchedules, fetchJeSchedulesFailure, fetchJeSchedulesPage, fetchJeSchedulesSuccess, fetchOneTimeAccrual, fetchOneTimeAccrualFailure, fetchOneTimeAccrualSuccess, fetchRecommendationForAccountSettings, ignoreRecommendedJeSchedule, ignoreRecommendedJeScheduleFailure, ignoreRecommendedJeScheduleSuccess, initializeAccountSettingsView, initializeJeScheduleLocalData, initializeNewSchedule, removeFailedJeScheduleTransactionKey, removeJeScheduleLocalDataById, removeJeAccruedScheduleKey, removeJeScheduleTransactionKey, resetNewScheduleLocalData, retryJeSchedule, retryJeScheduleFailure, retryJeScheduleSuccess, saveAccountSettings, saveAccountSettingsFailure, saveAccountSettingsLocalData, saveAccountSettingsSuccess, saveNewSchedule, saveNewScheduleFailure, saveNewScheduleSuccess, searchTransactionsForNewSchedule, searchTransactionsForNewScheduleFailure, searchTransactionsForNewScheduleSuccess, toggleJECreatedGroupCollapsed, toggleJEPendingGroupCollapsed, updateAccountSettingsListForAccountTypes, updateAccountSettingsListForAccountTypesFailure, updateJESchedulesUIState, updateJEScheduleTypeFilter, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys, updateNewScheduleLocalData, updateRecommendationForAccountSettings, updateRecommendationForAccountSettingsFailure, } = expenseAutomationJESchedulesView.actions;
400
677
  export default expenseAutomationJESchedulesView.reducer;
401
678
  const doUpdateRecommendationForAccountSettings = (draft, payload) => {
402
679
  const { prepaidExpensesRecommendations, fixedAssetsRecommendations, accruedExpensesRecommendations, } = mapAccountTypeRecommendationPayloadToAccountRecommendationByType(payload);
@@ -6,7 +6,18 @@ import { isVendorTransaction } from '../../../entity/transaction/stateTypes/vend
6
6
  import { clearAll } from '../../../rootActions';
7
7
  import { filterAutoTabLineItems, mergeTabSpecificLineItems, removeTransactionFromTabView, setEntityRecommendationForLineIdInLocalData, shouldAutoSelectAndAdd, toSetAllLineItemsToCategoryClass, toTransactionDetailLocalData, } from '../helpers/transactionCategorizationLocalDataHelper';
8
8
  import { DEFAULT_COMPLETED_SUB_TAB, } from '../types/completedSubTab';
9
+ import { DEFAULT_TRANSACTION_GROUP, } from '../types/transactionGroup';
9
10
  import { TRANSACTIONS_TABS, } from '../types/transactionsViewState';
11
+ export const initialUIState = {
12
+ sortKey: 'date',
13
+ sortOrder: 'descending',
14
+ searchString: '',
15
+ nodeCollapseState: {},
16
+ scrollPosition: { scrollTop: 0, scrollLeft: undefined },
17
+ pageToken: null,
18
+ totalCount: {},
19
+ limit: 10,
20
+ };
10
21
  export const initialTransactionTabViewState = {
11
22
  saveStatus: {
12
23
  fetchState: 'Not-Started',
@@ -20,16 +31,7 @@ export const initialTransactionTabViewState = {
20
31
  fetchState: 'Not-Started',
21
32
  error: undefined,
22
33
  },
23
- uiState: {
24
- sortKey: 'date',
25
- sortOrder: 'descending',
26
- searchString: '',
27
- nodeCollapseState: {},
28
- scrollPosition: { scrollTop: 0, scrollLeft: undefined },
29
- pageToken: null,
30
- totalCount: {},
31
- limit: 10,
32
- },
34
+ uiState: { ...initialUIState },
33
35
  filters: {
34
36
  categoryCombinationOperator: 'AND',
35
37
  categories: [],
@@ -55,6 +57,7 @@ export const initialState = {
55
57
  },
56
58
  selectedTransactionCategorizationTab: 'review',
57
59
  selectedTransactionCategorizationCompletedSubTab: DEFAULT_COMPLETED_SUB_TAB,
60
+ selectedTransactionGroup: DEFAULT_TRANSACTION_GROUP,
58
61
  transactionCategorizationView: {
59
62
  review: { ...initialTransactionTabViewState },
60
63
  autoCategorized: { ...initialTransactionTabViewState },
@@ -400,6 +403,48 @@ const expenseAutomationTransactionsView = createSlice({
400
403
  return { payload: { newSubTab } };
401
404
  },
402
405
  },
406
+ updateTransactionGroup: {
407
+ reducer(draft, action) {
408
+ const { newGroup } = action.payload;
409
+ if (draft.selectedTransactionGroup === newGroup) {
410
+ return;
411
+ }
412
+ draft.selectedTransactionGroup = newGroup;
413
+ // A group change re-scopes the entire dataset on the backend (by
414
+ // account_type), so every parent tab, sub-tab snapshot and count is now
415
+ // stale. Drop the sub-tab cache and parent counts, and reset each tab's
416
+ // paginated data slots so the view epic's cache check falls through to a
417
+ // fresh page-1 fetch. User preferences (search, sort, limit, collapse
418
+ // state) are intentionally preserved, mirroring the sub-tab switch.
419
+ draft.autoCategorizedSubTabCache = {};
420
+ draft.parentTotalCountByTab = { review: {}, autoCategorized: {} };
421
+ TRANSACTIONS_TABS.forEach((tab) => {
422
+ const view = draft.transactionCategorizationView[tab];
423
+ // Reset uiState to its initial values but keep the user prefs (search,
424
+ // sort, limit, collapse) in place -- mirroring the sub-tab switch. Then
425
+ // drop the loaded rows and any stale selection pointing at a now-absent
426
+ // row to avoid transient invalid state.
427
+ const { searchString, sortKey, sortOrder, nodeCollapseState, limit } = view.uiState;
428
+ view.uiState = {
429
+ ...initialUIState,
430
+ searchString,
431
+ sortKey,
432
+ sortOrder,
433
+ nodeCollapseState,
434
+ limit,
435
+ };
436
+ view.transactionIdsBySelectedPeriod = {};
437
+ view.fetchState = 'Not-Started';
438
+ view.error = undefined;
439
+ view.selectedTransactionId = undefined;
440
+ view.selectedTransactionLineId = undefined;
441
+ view.selectedCheckBoxTransactionIds = [];
442
+ });
443
+ },
444
+ prepare(newGroup) {
445
+ return { payload: { newGroup } };
446
+ },
447
+ },
403
448
  updateTransactionCategorization: {
404
449
  reducer(draft, action) {
405
450
  const selectedTab = action.payload.selectedTab;
@@ -1075,5 +1120,5 @@ const expenseAutomationTransactionsView = createSlice({
1075
1120
  });
1076
1121
  },
1077
1122
  });
1078
- export const { fetchTransactionCategorization, updateTransactionCategorizationUIState, updateTransactionFilters, initializeTransactionCategorizationViewLocalData, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateCurrentSelectedTransactionCategorizationTab, updateTransactionCategorizationCompletedSubTab, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateStatusForTransactionNotMiscategorizedUpdateForCategorization, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, setAllItemsToCategoryClassInLocalDataForCategorization, updateTotalCountForTransactionCategorization, updateParentTotalCountForTab, fetchTransactionCategorizationSuccess, resetOtherTabsFetchState, fetchTransactionCategorizationView, updateSelectedCheckboxTransactionIds, clearExpenseAutomationTransactionsViewPerTabView, clearExpenseAutomationTransactionsView, setEntityRecommendationForLineIdsForCategorization, markCategoryClassRecommendationsInProgressForCategorization, markCategoryClassRecommendationsCompletedForCategorization, markCategoryClassRecommendationsFailureForCategorization, updateSelectedTransactionId, syncTransactionCategorizationFromDetailSave, backgroundRefetchReviewTab, removeTransactionFromAllTabs, updateTransactionCategorizationUploadReceiptState, uploadTransactionCategorizationReceiptSuccess, } = expenseAutomationTransactionsView.actions;
1123
+ export const { fetchTransactionCategorization, updateTransactionCategorizationUIState, updateTransactionFilters, initializeTransactionCategorizationViewLocalData, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateCurrentSelectedTransactionCategorizationTab, updateTransactionCategorizationCompletedSubTab, updateTransactionGroup, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateStatusForTransactionNotMiscategorizedUpdateForCategorization, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, setAllItemsToCategoryClassInLocalDataForCategorization, updateTotalCountForTransactionCategorization, updateParentTotalCountForTab, fetchTransactionCategorizationSuccess, resetOtherTabsFetchState, fetchTransactionCategorizationView, updateSelectedCheckboxTransactionIds, clearExpenseAutomationTransactionsViewPerTabView, clearExpenseAutomationTransactionsView, setEntityRecommendationForLineIdsForCategorization, markCategoryClassRecommendationsInProgressForCategorization, markCategoryClassRecommendationsCompletedForCategorization, markCategoryClassRecommendationsFailureForCategorization, updateSelectedTransactionId, syncTransactionCategorizationFromDetailSave, backgroundRefetchReviewTab, removeTransactionFromAllTabs, updateTransactionCategorizationUploadReceiptState, uploadTransactionCategorizationReceiptSuccess, } = expenseAutomationTransactionsView.actions;
1079
1124
  export default expenseAutomationTransactionsView.reducer;