@zeniai/client-epic-state 5.1.91 → 5.1.92-betaRD0

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 (126) hide show
  1. package/lib/entity/aiCfo/aiCfoState.d.ts +2 -2
  2. package/lib/entity/jeSchedules/jeScheduleHelper.d.ts +2 -0
  3. package/lib/entity/jeSchedules/jeScheduleHelper.js +7 -0
  4. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +66 -1
  5. package/lib/entity/jeSchedules/jeSchedulesPayload.js +135 -0
  6. package/lib/entity/jeSchedules/jeSchedulesReducer.d.ts +4 -2
  7. package/lib/entity/jeSchedules/jeSchedulesReducer.js +24 -2
  8. package/lib/entity/jeSchedules/jeSchedulesSelector.d.ts +11 -2
  9. package/lib/entity/jeSchedules/jeSchedulesSelector.js +34 -3
  10. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +79 -1
  11. package/lib/entity/jeSchedules/jeSchedulesTypes.d.ts +24 -1
  12. package/lib/entity/jeSchedules/jeSchedulesTypes.js +88 -1
  13. package/lib/entity/snackbar/snackbarApiError.d.ts +8 -0
  14. package/lib/entity/snackbar/snackbarApiError.js +15 -0
  15. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  16. package/lib/entity/snackbar/snackbarTypes.js +1 -0
  17. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.d.ts +2 -0
  18. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.js +2 -0
  19. package/lib/entity/transaction/stateTypes/scheduleTransaction.d.ts +2 -0
  20. package/lib/epic.d.ts +8 -1
  21. package/lib/epic.js +8 -1
  22. package/lib/esm/entity/jeSchedules/jeScheduleHelper.js +6 -0
  23. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +135 -1
  24. package/lib/esm/entity/jeSchedules/jeSchedulesReducer.js +24 -2
  25. package/lib/esm/entity/jeSchedules/jeSchedulesSelector.js +32 -2
  26. package/lib/esm/entity/jeSchedules/jeSchedulesTypes.js +78 -0
  27. package/lib/esm/entity/snackbar/snackbarApiError.js +11 -0
  28. package/lib/esm/entity/snackbar/snackbarTypes.js +1 -0
  29. package/lib/esm/entity/transaction/payloadTypes/scheduleTransactionPayload.js +2 -0
  30. package/lib/esm/epic.js +8 -1
  31. package/lib/esm/index.js +13 -7
  32. package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +6 -3
  33. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +41 -5
  34. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/ignoreRecommendedJeScheduleEpic.js +14 -2
  35. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.js +81 -0
  36. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +21 -0
  37. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +110 -0
  38. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +73 -0
  39. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.js +129 -0
  40. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.js +92 -0
  41. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +22 -0
  42. package/lib/esm/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +140 -0
  43. package/lib/esm/view/expenseAutomationView/payload/jeSchedulesPayload.js +55 -0
  44. package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +268 -29
  45. package/lib/esm/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +1 -0
  46. package/lib/esm/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +106 -0
  47. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +286 -22
  48. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +5 -6
  49. package/lib/esm/view/invoicing/createCreditNote/createCreditNoteEpic.js +2 -0
  50. package/lib/esm/view/invoicing/createInvoice/createInvoiceEpic.js +2 -0
  51. package/lib/esm/view/invoicing/discountAction/discountActionEpic.js +6 -3
  52. package/lib/esm/view/invoicing/dunningAction/dunningActionEpic.js +6 -3
  53. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +5 -4
  54. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +3 -0
  55. package/lib/esm/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +2 -0
  56. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +2 -0
  57. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +2 -0
  58. package/lib/esm/view/invoicing/invoiceAction/invoiceActionEpic.js +7 -3
  59. package/lib/esm/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +2 -0
  60. package/lib/esm/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +2 -0
  61. package/lib/esm/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +2 -0
  62. package/lib/esm/view/invoicing/recordPayment/recordPaymentEpic.js +3 -0
  63. package/lib/esm/view/invoicing/settingsView/settingsViewEpics.js +6 -3
  64. package/lib/esm/view/invoicing/settingsView/settingsViewSelector.js +52 -0
  65. package/lib/esm/view/invoicing/subscriptionAction/subscriptionActionEpic.js +6 -3
  66. package/lib/esm/view/vendorTabView/vendorTabViewReducer.js +1 -1
  67. package/lib/index.d.ts +18 -14
  68. package/lib/index.js +92 -49
  69. package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +6 -3
  70. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.d.ts +3 -2
  71. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +38 -2
  72. package/lib/view/expenseAutomationView/epics/jeSchedule/ignoreRecommendedJeScheduleEpic.js +14 -2
  73. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.d.ts +8 -0
  74. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.js +85 -0
  75. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.d.ts +8 -0
  76. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +25 -0
  77. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.d.ts +45 -0
  78. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +114 -0
  79. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.d.ts +8 -0
  80. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +77 -0
  81. package/lib/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.d.ts +12 -0
  82. package/lib/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.js +136 -0
  83. package/lib/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.d.ts +65 -0
  84. package/lib/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.js +96 -0
  85. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.d.ts +6 -0
  86. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +26 -0
  87. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.d.ts +36 -0
  88. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +145 -0
  89. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  90. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.d.ts +72 -3
  91. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.js +58 -1
  92. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +79 -11
  93. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +270 -29
  94. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +1 -1
  95. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +2 -2
  96. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.d.ts +42 -0
  97. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +2 -0
  98. package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +34 -8
  99. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.d.ts +21 -0
  100. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +112 -0
  101. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.d.ts +31 -1
  102. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +294 -21
  103. package/lib/view/expenseAutomationView/types/completedSubTab.d.ts +1 -1
  104. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +81 -8
  105. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +8 -8
  106. package/lib/view/invoicing/createCreditNote/createCreditNoteEpic.js +2 -0
  107. package/lib/view/invoicing/createInvoice/createInvoiceEpic.js +2 -0
  108. package/lib/view/invoicing/discountAction/discountActionEpic.js +5 -2
  109. package/lib/view/invoicing/dunningAction/dunningActionEpic.js +5 -2
  110. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +5 -4
  111. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +3 -0
  112. package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +2 -0
  113. package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +2 -0
  114. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +2 -0
  115. package/lib/view/invoicing/invoiceAction/invoiceActionEpic.js +6 -2
  116. package/lib/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +2 -0
  117. package/lib/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +2 -0
  118. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewReducer.d.ts +1 -1
  119. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewState.d.ts +1 -1
  120. package/lib/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +2 -0
  121. package/lib/view/invoicing/recordPayment/recordPaymentEpic.js +3 -0
  122. package/lib/view/invoicing/settingsView/settingsViewEpics.js +5 -2
  123. package/lib/view/invoicing/settingsView/settingsViewSelector.d.ts +41 -1
  124. package/lib/view/invoicing/settingsView/settingsViewSelector.js +55 -1
  125. package/lib/view/invoicing/subscriptionAction/subscriptionActionEpic.js +5 -2
  126. package/package.json +1 -1
@@ -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,36 @@ 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: {},
45
69
  uiState: {
46
- searchString: '',
70
+ createdGroupCollapsed: false,
71
+ pendingGroupCollapsed: false,
47
72
  scrollPosition: { scrollTop: 0, scrollLeft: undefined },
48
- selectedMainTab: 'pending_review',
73
+ searchString: '',
74
+ selectedJETypeFilter: null,
75
+ selectedPageTab: 'schedules',
49
76
  sortKey: 'transactionDate',
50
77
  sortOrder: 'descending',
51
78
  totalCount: 0,
@@ -56,6 +83,14 @@ export const initialState = {
56
83
  error: undefined,
57
84
  },
58
85
  accountSettings: accountSettingsInitialState,
86
+ newSchedule: {
87
+ createOneTimeAccrualStatus: { fetchState: 'Not-Started', error: undefined },
88
+ newScheduleState: newScheduleInitialState,
89
+ saveStatus: { fetchState: 'Not-Started', error: undefined },
90
+ searchTransactions: searchTransactionsInitialState,
91
+ fetchState: 'Not-Started',
92
+ error: undefined,
93
+ },
59
94
  fetchState: 'Not-Started',
60
95
  error: undefined,
61
96
  hasValidState() {
@@ -100,9 +135,12 @@ const expenseAutomationJESchedulesView = createSlice({
100
135
  },
101
136
  },
102
137
  fetchJeSchedulesSuccess(draft, action) {
103
- const { jeSchedules, selectedPeriod, failedJeSchedules, refreshViewInBackground, } = action.payload;
138
+ const { jeSchedules, selectedPeriod, selectedPageTab, failedJeSchedules, accruedJeSchedules, oneTimeAccruals, refreshViewInBackground, } = action.payload;
139
+ const periodTabKey = getJESchedulePeriodTabKey(selectedPageTab, toMonthYearPeriodId(selectedPeriod));
104
140
  const jeScheduleTransactionKeys = jeSchedules.map((schedules) => getJEScheduleTransactionDetailKeyPayload(schedules.base_transaction));
105
141
  const failedJeScheduleTransactionKeys = failedJeSchedules.map((schedules) => getJEScheduleTransactionDetailKeyPayload(schedules.base_transaction));
142
+ const jeScheduleAccruedKeys = accruedJeSchedules.map((schedule) => getJEScheduleKey(schedule));
143
+ const jeScheduleOneTimeAccrualKeys = oneTimeAccruals.map((accrual) => generateJEOneTimeAccrualKey(accrual._id));
106
144
  if (refreshViewInBackground === true &&
107
145
  draft.refreshStatus.fetchState === 'In-Progress') {
108
146
  draft.refreshStatus = { fetchState: 'Completed', error: undefined };
@@ -111,19 +149,28 @@ const expenseAutomationJESchedulesView = createSlice({
111
149
  draft.fetchState = 'Completed';
112
150
  draft.error = undefined;
113
151
  }
114
- draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = jeScheduleTransactionKeys;
115
- draft.failedJeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = failedJeScheduleTransactionKeys;
152
+ draft.jeScheduleTransactionKeysByPeriodAndTab[periodTabKey] =
153
+ jeScheduleTransactionKeys;
154
+ draft.jeScheduleAccruedKeysByPeriodAndTab[periodTabKey] =
155
+ jeScheduleAccruedKeys;
156
+ draft.jeScheduleOneTimeAccrualKeysByPeriodAndTab[periodTabKey] =
157
+ jeScheduleOneTimeAccrualKeys;
158
+ draft.failedJeScheduleTransactionKeysByPeriodAndTab[periodTabKey] =
159
+ failedJeScheduleTransactionKeys;
116
160
  },
117
161
  fetchJeSchedulesFailure(draft, action) {
118
- const { status, selectedPeriod } = action.payload;
162
+ const { status, selectedPeriod, selectedPageTab } = action.payload;
163
+ const periodTabKey = getJESchedulePeriodTabKey(selectedPageTab, toMonthYearPeriodId(selectedPeriod));
119
164
  if (draft.refreshStatus.fetchState === 'In-Progress') {
120
165
  draft.refreshStatus = { fetchState: 'Error', error: status };
121
166
  }
122
167
  else {
123
168
  draft.fetchState = 'Error';
124
169
  draft.error = status;
170
+ draft.jeScheduleTransactionKeysByPeriodAndTab[periodTabKey] = [];
171
+ draft.jeScheduleAccruedKeysByPeriodAndTab[periodTabKey] = [];
172
+ draft.jeScheduleOneTimeAccrualKeysByPeriodAndTab[periodTabKey] = [];
125
173
  }
126
- draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = [];
127
174
  },
128
175
  retryJeSchedule(draft, action) {
129
176
  const { scheduledJournalEntryID } = action.payload;
@@ -159,11 +206,13 @@ const expenseAutomationJESchedulesView = createSlice({
159
206
  };
160
207
  },
161
208
  ignoreRecommendedJeSchedule: {
162
- prepare(jeScheduleTransactionKey, scheduleType) {
209
+ prepare(jeScheduleTransactionKey, scheduleType, reason, note) {
163
210
  return {
164
211
  payload: {
165
212
  jeScheduleTransactionKey,
166
213
  scheduleType,
214
+ reason,
215
+ note,
167
216
  },
168
217
  };
169
218
  },
@@ -179,6 +228,37 @@ const expenseAutomationJESchedulesView = createSlice({
179
228
  };
180
229
  },
181
230
  },
231
+ revertJeSchedule: {
232
+ prepare(jeScheduleId, jeScheduleTransactionKey, scheduleType, reason, note) {
233
+ return {
234
+ payload: {
235
+ jeScheduleId,
236
+ jeScheduleTransactionKey,
237
+ scheduleType,
238
+ reason,
239
+ note,
240
+ },
241
+ };
242
+ },
243
+ reducer(draft, action) {
244
+ draft.revertStatusById[action.payload.jeScheduleTransactionKey] = {
245
+ fetchState: 'In-Progress',
246
+ error: undefined,
247
+ };
248
+ },
249
+ },
250
+ revertJeScheduleSuccess(draft, action) {
251
+ draft.revertStatusById[action.payload.jeScheduleTransactionKey] = {
252
+ fetchState: 'Completed',
253
+ error: undefined,
254
+ };
255
+ },
256
+ revertJeScheduleFailure(draft, action) {
257
+ draft.revertStatusById[action.payload.jeScheduleTransactionKey] = {
258
+ fetchState: 'Error',
259
+ error: action.payload.status,
260
+ };
261
+ },
182
262
  ignoreRecommendedJeScheduleSuccess: {
183
263
  reducer(draft, action) {
184
264
  const { jeScheduleTransactionKey } = action.payload;
@@ -211,17 +291,18 @@ const expenseAutomationJESchedulesView = createSlice({
211
291
  };
212
292
  },
213
293
  updateJeScheduleTransactionKeys: {
214
- prepare(jeScheduleKeys, selectedPeriod) {
294
+ prepare(jeScheduleKeys, selectedPeriod, selectedPageTab) {
215
295
  return {
216
296
  payload: {
217
297
  jeScheduleKeys: jeScheduleKeys,
218
298
  selectedPeriod: selectedPeriod,
299
+ selectedPageTab: selectedPageTab,
219
300
  },
220
301
  };
221
302
  },
222
303
  reducer(draft, action) {
223
- const { selectedPeriod, jeScheduleKeys } = action.payload;
224
- draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = jeScheduleKeys;
304
+ const { selectedPeriod, selectedPageTab, jeScheduleKeys } = action.payload;
305
+ draft.jeScheduleTransactionKeysByPeriodAndTab[getJESchedulePeriodTabKey(selectedPageTab, toMonthYearPeriodId(selectedPeriod))] = jeScheduleKeys;
225
306
  },
226
307
  },
227
308
  removeJeScheduleTransactionKey: {
@@ -234,12 +315,10 @@ const expenseAutomationJESchedulesView = createSlice({
234
315
  };
235
316
  },
236
317
  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;
318
+ const { jeScheduleKey } = action.payload;
319
+ // Dropped from every tab's slot, not just the visible one: once a schedule is ignored or
320
+ // resolved it must not reappear when the user switches tabs and hits a cached list.
321
+ removeKeyFromEveryTabSlot(draft.jeScheduleTransactionKeysByPeriodAndTab, jeScheduleKey);
243
322
  },
244
323
  },
245
324
  removeFailedJeScheduleTransactionKey: {
@@ -252,12 +331,8 @@ const expenseAutomationJESchedulesView = createSlice({
252
331
  };
253
332
  },
254
333
  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;
334
+ const { failedJeScheduleKey } = action.payload;
335
+ removeKeyFromEveryTabSlot(draft.failedJeScheduleTransactionKeysByPeriodAndTab, failedJeScheduleKey);
261
336
  },
262
337
  },
263
338
  initializeJeScheduleLocalData: {
@@ -369,6 +444,159 @@ const expenseAutomationJESchedulesView = createSlice({
369
444
  clearJeAccountSettingsLocalData(draft) {
370
445
  draft.accountSettings.localData = accountSettingsInitialState.localData;
371
446
  },
447
+ initializeNewSchedule: {
448
+ prepare({ scheduleType, }) {
449
+ return { payload: { scheduleType } };
450
+ },
451
+ reducer() {
452
+ // Purely an epic-trigger action — the epic fans out the account/class
453
+ // list fetches plus resetNewScheduleLocalData.
454
+ },
455
+ },
456
+ resetNewScheduleLocalData: {
457
+ prepare({ scheduleType, }) {
458
+ return { payload: { scheduleType } };
459
+ },
460
+ reducer(draft, action) {
461
+ const { scheduleType } = action.payload;
462
+ draft.newSchedule.newScheduleState[scheduleType] =
463
+ getBaseNewScheduleLocalData(scheduleType);
464
+ },
465
+ },
466
+ updateNewScheduleLocalData(draft, action) {
467
+ const { scheduleType, localData } = action.payload;
468
+ draft.newSchedule.newScheduleState[scheduleType] = {
469
+ ...draft.newSchedule.newScheduleState[scheduleType],
470
+ ...localData,
471
+ };
472
+ },
473
+ searchTransactionsForNewSchedule: {
474
+ prepare({ query, scheduleType, }) {
475
+ return { payload: { query, scheduleType } };
476
+ },
477
+ reducer(draft, action) {
478
+ const trimmed = action.payload.query.trim();
479
+ // Cleared or too-short query: no API (see epic) — reset immediately.
480
+ if (trimmed.length < MIN_NEW_SCHEDULE_SEARCH_LENGTH) {
481
+ draft.newSchedule.searchTransactions = searchTransactionsInitialState;
482
+ return;
483
+ }
484
+ draft.newSchedule.searchTransactions = {
485
+ ...draft.newSchedule.searchTransactions,
486
+ searchString: action.payload.query,
487
+ fetchState: 'In-Progress',
488
+ };
489
+ },
490
+ },
491
+ searchTransactionsForNewScheduleSuccess(draft, action) {
492
+ draft.newSchedule.searchTransactions = {
493
+ ...draft.newSchedule.searchTransactions,
494
+ searchResults: action.payload.searchResults,
495
+ fetchState: 'Completed',
496
+ error: undefined,
497
+ };
498
+ },
499
+ searchTransactionsForNewScheduleFailure(draft, action) {
500
+ draft.newSchedule.searchTransactions = {
501
+ ...draft.newSchedule.searchTransactions,
502
+ fetchState: 'Error',
503
+ error: action.payload.status,
504
+ };
505
+ },
506
+ clearSearchTransactionsForNewSchedule(draft) {
507
+ draft.newSchedule.searchTransactions = searchTransactionsInitialState;
508
+ },
509
+ saveNewSchedule: {
510
+ prepare({ scheduleType, }) {
511
+ return { payload: { scheduleType } };
512
+ },
513
+ reducer(draft) {
514
+ draft.newSchedule.saveStatus = {
515
+ fetchState: 'In-Progress',
516
+ error: undefined,
517
+ };
518
+ },
519
+ },
520
+ saveNewScheduleSuccess(draft) {
521
+ draft.newSchedule.saveStatus = {
522
+ fetchState: 'Completed',
523
+ error: undefined,
524
+ };
525
+ },
526
+ saveNewScheduleFailure(draft, action) {
527
+ draft.newSchedule.saveStatus = {
528
+ fetchState: 'Error',
529
+ error: action.payload.status,
530
+ };
531
+ },
532
+ createOneTimeAccrual: {
533
+ prepare(localData) {
534
+ return { payload: { localData } };
535
+ },
536
+ reducer(draft) {
537
+ draft.newSchedule.createOneTimeAccrualStatus = {
538
+ fetchState: 'In-Progress',
539
+ error: undefined,
540
+ };
541
+ },
542
+ },
543
+ createOneTimeAccrualSuccess(draft) {
544
+ draft.newSchedule.createOneTimeAccrualStatus = {
545
+ fetchState: 'Completed',
546
+ error: undefined,
547
+ };
548
+ },
549
+ createOneTimeAccrualFailure(draft, action) {
550
+ draft.newSchedule.createOneTimeAccrualStatus = {
551
+ fetchState: 'Error',
552
+ error: action.payload.status,
553
+ };
554
+ },
555
+ promoteOneTimeAccrual: {
556
+ prepare(accrualId, amount) {
557
+ return { payload: { accrualId, amount } };
558
+ },
559
+ reducer(draft, action) {
560
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
561
+ fetchState: 'In-Progress',
562
+ error: undefined,
563
+ };
564
+ },
565
+ },
566
+ revertOneTimeAccrual: {
567
+ prepare(accrualId, reason, note) {
568
+ return { payload: { accrualId, reason, note } };
569
+ },
570
+ reducer(draft, action) {
571
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
572
+ fetchState: 'In-Progress',
573
+ error: undefined,
574
+ };
575
+ },
576
+ },
577
+ ignoreOneTimeAccrual: {
578
+ prepare(accrualId, reason, note) {
579
+ return { payload: { accrualId, reason, note } };
580
+ },
581
+ reducer(draft, action) {
582
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
583
+ fetchState: 'In-Progress',
584
+ error: undefined,
585
+ };
586
+ },
587
+ },
588
+ oneTimeAccrualActionSuccess(draft, action) {
589
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
590
+ fetchState: 'Completed',
591
+ error: undefined,
592
+ };
593
+ },
594
+ oneTimeAccrualActionFailure(draft, action) {
595
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
596
+ fetchState: 'Error',
597
+ error: action.payload.status,
598
+ };
599
+ },
372
600
  updateJESchedulesUIState(draft, action) {
373
601
  if (action.payload.sortKey != null) {
374
602
  draft.uiState.sortKey = action.payload.sortKey;
@@ -382,10 +610,21 @@ const expenseAutomationJESchedulesView = createSlice({
382
610
  if (action.payload.scrollPosition != null) {
383
611
  draft.uiState.scrollPosition = action.payload.scrollPosition;
384
612
  }
385
- if (action.payload.selectedMainTab != null) {
386
- draft.uiState.selectedMainTab = action.payload.selectedMainTab;
613
+ if (action.payload.selectedPageTab != null) {
614
+ draft.uiState.selectedPageTab = action.payload.selectedPageTab;
387
615
  }
388
616
  },
617
+ updateJEScheduleTypeFilter(draft, action) {
618
+ draft.uiState.selectedJETypeFilter = action.payload;
619
+ },
620
+ toggleJEPendingGroupCollapsed(draft) {
621
+ draft.uiState.pendingGroupCollapsed =
622
+ !draft.uiState.pendingGroupCollapsed;
623
+ },
624
+ toggleJECreatedGroupCollapsed(draft) {
625
+ draft.uiState.createdGroupCollapsed =
626
+ !draft.uiState.createdGroupCollapsed;
627
+ },
389
628
  clearExpenseAutomationJESchedulesView(draft) {
390
629
  Object.assign(draft, initialState);
391
630
  },
@@ -396,7 +635,7 @@ const expenseAutomationJESchedulesView = createSlice({
396
635
  });
397
636
  },
398
637
  });
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;
638
+ export const { clearExpenseAutomationJESchedulesView, clearJeAccountSettingsLocalData, clearJeScheduleLocalData, clearSearchTransactionsForNewSchedule, createOneTimeAccrual, createOneTimeAccrualFailure, createOneTimeAccrualSuccess, ignoreOneTimeAccrual, oneTimeAccrualActionFailure, oneTimeAccrualActionSuccess, promoteOneTimeAccrual, revertJeSchedule, revertJeScheduleFailure, revertJeScheduleSuccess, revertOneTimeAccrual, fetchAccountSettingsListForAccountTypes, fetchJeSchedules, fetchJeSchedulesFailure, fetchJeSchedulesPage, fetchJeSchedulesSuccess, fetchRecommendationForAccountSettings, ignoreRecommendedJeSchedule, ignoreRecommendedJeScheduleFailure, ignoreRecommendedJeScheduleSuccess, initializeAccountSettingsView, initializeJeScheduleLocalData, initializeNewSchedule, removeFailedJeScheduleTransactionKey, removeJeScheduleLocalDataById, 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
639
  export default expenseAutomationJESchedulesView.reducer;
401
640
  const doUpdateRecommendationForAccountSettings = (draft, payload) => {
402
641
  const { prepaidExpensesRecommendations, fixedAssetsRecommendations, accruedExpensesRecommendations, } = mapAccountTypeRecommendationPayloadToAccountRecommendationByType(payload);
@@ -0,0 +1,106 @@
1
+ import { getAccountIdsForLabels, getAccountIdsForTypes, } from '../../../entity/account/accountSelector';
2
+ import { getScheduleTransactionById } from '../../../entity/transaction/transactionSelector';
3
+ import { getAccountIdsForLabel, getAccountList, getNestedAccountListHierarchy, } from '../../accountList/accountListSelector';
4
+ import { getClassList, getNestedClassListHierarchy, } from '../../classList/classListSelector';
5
+ import { getAccountsTypesForScheduleDetails } from '../../scheduleView/scheduleDetailView/scheduleDetailLocalDataHelper';
6
+ import { filterNestedAccountHierarchyById } from '../../scheduleView/scheduleDetailView/scheduleDetailSelector';
7
+ import { getAccountLabelForScheduleType, getAccountsTypesForScheduleEpics, } from '../../scheduleView/scheduleListView/scheduleListHelper';
8
+ /**
9
+ * The Base Transaction search is shared across schedule types (one search
10
+ * box, not one per prepaid_expenses/fixed_assets) — split out from
11
+ * getNewScheduleView so a consumer can read it without supplying an
12
+ * otherwise-irrelevant scheduleType.
13
+ */
14
+ export const getNewScheduleSearchTransactionsView = (state) => {
15
+ const { searchTransactions } = state.expenseAutomationJESchedulesViewState.newSchedule;
16
+ const searchTransactionsResults = searchTransactions.searchResults
17
+ .map((key) => getScheduleTransactionById(state.transactionState, key))
18
+ .filter((transaction) => transaction != null);
19
+ return {
20
+ searchTransactionsResults,
21
+ searchTransactionsFetchState: {
22
+ fetchState: searchTransactions.fetchState,
23
+ error: searchTransactions.error,
24
+ },
25
+ searchTransactionsString: searchTransactions.searchString,
26
+ };
27
+ };
28
+ const ACCRUED_EXPENSE_ACCOUNT_LABELS = ['accrued_expenses'];
29
+ /**
30
+ * Account + class options and request status shared by both accrual creation forms — the one-time
31
+ * accrual and the recurring accrued schedule.
32
+ *
33
+ * getAccountsTypesForScheduleDetails('accrued_expenses') deliberately includes
34
+ * other_current_liabilities, because the accrued liability accounts live there —
35
+ * so the debit list has to subtract them back out, and the credit list keeps only
36
+ * them. Mirrors getScheduleAccruedDetailView, which is the form this one is
37
+ * modelled on.
38
+ */
39
+ export const getNewAccrualAccountsView = (state) => {
40
+ const { accountState, accountListState, classState, classListState } = state;
41
+ const { newSchedule } = state.expenseAutomationJESchedulesViewState;
42
+ const accountType = getAccountsTypesForScheduleEpics();
43
+ const accrualAccountIds = getAccountIdsForTypes(accountState, getAccountsTypesForScheduleDetails('accrued_expenses'));
44
+ const accruedCategoryIds = getAccountIdsForLabels(accountState, ACCRUED_EXPENSE_ACCOUNT_LABELS);
45
+ const allAccountList = getAccountList(accountState, accountListState, accountType.accountListKey);
46
+ const nestedAccountHierarchy = getNestedAccountListHierarchy(accountListState, accountType.accountListKey);
47
+ const debitAccounts = allAccountList.accounts.filter((account) => accrualAccountIds.includes(account.accountId) &&
48
+ !accruedCategoryIds.includes(account.accountId));
49
+ const creditAccounts = allAccountList.accounts.filter((account) => accruedCategoryIds.includes(account.accountId));
50
+ const allClassList = getClassList(classState, classListState);
51
+ return {
52
+ accountListNestedAccountHierarchy: filterNestedAccountHierarchyById(nestedAccountHierarchy, debitAccounts.map((account) => account.accountId)),
53
+ accruedAccountListNestedAccountHierarchy: filterNestedAccountHierarchyById(nestedAccountHierarchy, creditAccounts.map((account) => account.accountId)),
54
+ allAccountList: debitAccounts,
55
+ allAccruedExpenseList: creditAccounts,
56
+ allClassList: allClassList.classes,
57
+ classListNestedAccountHierarchy: getNestedClassListHierarchy(classListState),
58
+ createStatus: newSchedule.createOneTimeAccrualStatus,
59
+ // The recurring accrued schedule saves through the accrued detail epics that the Vendor tab
60
+ // already uses, so its status is that slice's updateStatus rather than anything new here.
61
+ accruedScheduleSaveStatus: state.scheduleAccruedDetailState.updateStatus,
62
+ };
63
+ };
64
+ export const getNewScheduleView = (state, scheduleType) => {
65
+ const { accountState, accountListState, classState, classListState } = state;
66
+ const { newSchedule } = state.expenseAutomationJESchedulesViewState;
67
+ const searchTransactionsView = getNewScheduleSearchTransactionsView(state);
68
+ const accountType = getAccountsTypesForScheduleEpics();
69
+ const newScheduleAccountTypes = getAccountsTypesForScheduleDetails(scheduleType);
70
+ const newScheduleAccountIds = getAccountIdsForTypes(accountState, newScheduleAccountTypes);
71
+ const allAccountList = getAccountList(accountState, accountListState, accountType.accountListKey);
72
+ const filteredAccounts = allAccountList.accounts.filter((account) => newScheduleAccountIds.includes(account.accountId));
73
+ const accountListNestedAccountHierarchy = filterNestedAccountHierarchyById(getNestedAccountListHierarchy(accountListState, accountType.accountListKey), filteredAccounts.map((account) => account.accountId));
74
+ const allClassList = getClassList(classState, classListState);
75
+ const classListNestedAccountHierarchy = getNestedClassListHierarchy(classListState);
76
+ let allDepreciationAccountList;
77
+ let allDepreciationAccountListNestedAccountHierarchy;
78
+ if (scheduleType === 'fixed_assets') {
79
+ const depreciationCategoryIds = getAccountIdsForTypes(accountState, [
80
+ 'fixed_assets',
81
+ 'other_assets',
82
+ ]);
83
+ const accountLabel = getAccountLabelForScheduleType('fixed_assets');
84
+ const fixedAssetLabelAccountIds = accountLabel != null
85
+ ? getAccountIdsForLabel(accountListState, accountType.accountListKey, accountLabel)
86
+ : [];
87
+ allDepreciationAccountList = allAccountList.accounts.filter((account) => depreciationCategoryIds.includes(account.accountId) &&
88
+ !fixedAssetLabelAccountIds.includes(account.accountId));
89
+ allDepreciationAccountListNestedAccountHierarchy =
90
+ filterNestedAccountHierarchyById(getNestedAccountListHierarchy(accountListState, accountType.accountListKey), allDepreciationAccountList.map((account) => account.accountId));
91
+ }
92
+ return {
93
+ scheduleType,
94
+ accountListNestedAccountHierarchy,
95
+ allAccountList: filteredAccounts,
96
+ allClassList: allClassList.classes,
97
+ allDepreciationAccountList,
98
+ allDepreciationAccountListNestedAccountHierarchy,
99
+ classListNestedAccountHierarchy,
100
+ newScheduleLocalData: newSchedule.newScheduleState[scheduleType],
101
+ saveStatus: newSchedule.saveStatus,
102
+ ...searchTransactionsView,
103
+ fetchState: newSchedule.fetchState,
104
+ error: newSchedule.error,
105
+ };
106
+ };