@zeniai/client-epic-state 5.2.10 → 5.2.11-betaAM1

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 (155) hide show
  1. package/lib/entity/jeSchedules/jeScheduleHelper.d.ts +1 -0
  2. package/lib/entity/jeSchedules/jeScheduleHelper.js +7 -0
  3. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +86 -1
  4. package/lib/entity/jeSchedules/jeSchedulesPayload.js +172 -0
  5. package/lib/entity/jeSchedules/jeSchedulesReducer.d.ts +4 -2
  6. package/lib/entity/jeSchedules/jeSchedulesReducer.js +30 -2
  7. package/lib/entity/jeSchedules/jeSchedulesSelector.d.ts +11 -2
  8. package/lib/entity/jeSchedules/jeSchedulesSelector.js +38 -3
  9. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +101 -1
  10. package/lib/entity/jeSchedules/jeSchedulesTypes.d.ts +24 -1
  11. package/lib/entity/jeSchedules/jeSchedulesTypes.js +88 -1
  12. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  13. package/lib/entity/snackbar/snackbarTypes.js +3 -0
  14. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.d.ts +2 -0
  15. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.js +2 -0
  16. package/lib/entity/transaction/stateTypes/scheduleTransaction.d.ts +2 -0
  17. package/lib/epic.d.ts +14 -1
  18. package/lib/epic.js +26 -0
  19. package/lib/esm/entity/jeSchedules/jeScheduleHelper.js +6 -0
  20. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +172 -1
  21. package/lib/esm/entity/jeSchedules/jeSchedulesReducer.js +30 -2
  22. package/lib/esm/entity/jeSchedules/jeSchedulesSelector.js +36 -2
  23. package/lib/esm/entity/jeSchedules/jeSchedulesTypes.js +78 -0
  24. package/lib/esm/entity/snackbar/snackbarTypes.js +3 -0
  25. package/lib/esm/entity/transaction/payloadTypes/scheduleTransactionPayload.js +2 -0
  26. package/lib/esm/epic.js +26 -0
  27. package/lib/esm/index.js +19 -9
  28. package/lib/esm/reducer.js +3 -0
  29. package/lib/esm/view/companyMonthEndReportView/companyMonthEndReportViewReducer.js +6 -2
  30. package/lib/esm/view/companyMonthEndReportView/companyMonthEndReportViewState.js +4 -0
  31. package/lib/esm/view/companyMonthEndReportView/epics/saveCompanyMonthEndReportEpic.js +10 -6
  32. package/lib/esm/view/companyMonthEndReportView/epics/sendCompanyMonthEndReportEpic.js +9 -5
  33. package/lib/esm/view/companyMonthEndReportView/monthEndTemplateData.js +32 -0
  34. package/lib/esm/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingEpic.js +46 -0
  35. package/lib/esm/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingPageEpic.js +7 -0
  36. package/lib/esm/view/expenseAutomationView/epics/actualMatching/matchAndReverseAccrualsEpic.js +50 -0
  37. package/lib/esm/view/expenseAutomationView/epics/actualMatching/searchMatchAccrualsEpic.js +44 -0
  38. package/lib/esm/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.js +44 -0
  39. package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +30 -10
  40. package/lib/esm/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.js +9 -1
  41. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +9 -1
  42. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +41 -5
  43. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchOneTimeAccrualEpic.js +45 -0
  44. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/ignoreRecommendedJeScheduleEpic.js +14 -2
  45. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.js +104 -0
  46. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +25 -0
  47. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +136 -0
  48. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +79 -0
  49. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.js +157 -0
  50. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.js +111 -0
  51. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +33 -0
  52. package/lib/esm/view/expenseAutomationView/expenseAutomationViewSelector.js +22 -7
  53. package/lib/esm/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +140 -0
  54. package/lib/esm/view/expenseAutomationView/payload/actualMatchingPayload.js +35 -0
  55. package/lib/esm/view/expenseAutomationView/payload/jeSchedulesPayload.js +55 -0
  56. package/lib/esm/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +260 -0
  57. package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +314 -29
  58. package/lib/esm/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.js +1 -0
  59. package/lib/esm/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +1 -0
  60. package/lib/esm/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +162 -0
  61. package/lib/esm/view/expenseAutomationView/selectors/jeAccountSettingsViewSelector.js +1 -0
  62. package/lib/esm/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +106 -0
  63. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +297 -22
  64. package/lib/esm/view/expenseAutomationView/types/actualMatchingViewState.js +22 -0
  65. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +8 -5
  66. package/lib/esm/view/scheduleView/scheduleListView/epics/fetchAccruedScheduleListEpic.js +1 -1
  67. package/lib/esm/view/scheduleView/scheduleListView/epics/fetchDownloadSchedulesEpic.js +7 -2
  68. package/lib/esm/view/scheduleView/scheduleListView/scheduleListReducer.js +5 -3
  69. package/lib/index.d.ts +25 -14
  70. package/lib/index.js +119 -51
  71. package/lib/reducer.d.ts +1 -0
  72. package/lib/reducer.js +3 -0
  73. package/lib/rootStateTypes.d.ts +2 -0
  74. package/lib/view/companyMonthEndReportView/companyMonthEndReportViewPayload.d.ts +8 -0
  75. package/lib/view/companyMonthEndReportView/companyMonthEndReportViewReducer.d.ts +6 -2
  76. package/lib/view/companyMonthEndReportView/companyMonthEndReportViewReducer.js +6 -2
  77. package/lib/view/companyMonthEndReportView/companyMonthEndReportViewState.d.ts +2 -0
  78. package/lib/view/companyMonthEndReportView/companyMonthEndReportViewState.js +4 -0
  79. package/lib/view/companyMonthEndReportView/epics/saveCompanyMonthEndReportEpic.js +10 -6
  80. package/lib/view/companyMonthEndReportView/epics/sendCompanyMonthEndReportEpic.js +9 -5
  81. package/lib/view/companyMonthEndReportView/monthEndTemplateData.d.ts +16 -0
  82. package/lib/view/companyMonthEndReportView/monthEndTemplateData.js +36 -0
  83. package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingEpic.d.ts +9 -0
  84. package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingEpic.js +50 -0
  85. package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingPageEpic.d.ts +5 -0
  86. package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingPageEpic.js +11 -0
  87. package/lib/view/expenseAutomationView/epics/actualMatching/matchAndReverseAccrualsEpic.d.ts +8 -0
  88. package/lib/view/expenseAutomationView/epics/actualMatching/matchAndReverseAccrualsEpic.js +54 -0
  89. package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchAccrualsEpic.d.ts +8 -0
  90. package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchAccrualsEpic.js +48 -0
  91. package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.d.ts +8 -0
  92. package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.js +48 -0
  93. package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.d.ts +2 -1
  94. package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +30 -10
  95. package/lib/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.d.ts +2 -1
  96. package/lib/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.js +9 -1
  97. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +9 -1
  98. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.d.ts +3 -2
  99. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +39 -3
  100. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchOneTimeAccrualEpic.d.ts +21 -0
  101. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchOneTimeAccrualEpic.js +49 -0
  102. package/lib/view/expenseAutomationView/epics/jeSchedule/ignoreRecommendedJeScheduleEpic.js +14 -2
  103. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.d.ts +9 -0
  104. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.js +108 -0
  105. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.d.ts +8 -0
  106. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +29 -0
  107. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.d.ts +9 -0
  108. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +140 -0
  109. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.d.ts +8 -0
  110. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +83 -0
  111. package/lib/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.d.ts +13 -0
  112. package/lib/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.js +164 -0
  113. package/lib/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.d.ts +65 -0
  114. package/lib/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.js +115 -0
  115. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.d.ts +7 -0
  116. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +37 -0
  117. package/lib/view/expenseAutomationView/expenseAutomationViewSelector.js +22 -7
  118. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.d.ts +36 -0
  119. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +145 -0
  120. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  121. package/lib/view/expenseAutomationView/payload/actualMatchingPayload.d.ts +66 -0
  122. package/lib/view/expenseAutomationView/payload/actualMatchingPayload.js +40 -0
  123. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.d.ts +72 -3
  124. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.js +58 -1
  125. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.d.ts +53 -0
  126. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +264 -0
  127. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +91 -12
  128. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +316 -29
  129. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +1 -1
  130. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +2 -2
  131. package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.d.ts +58 -0
  132. package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.js +2 -0
  133. package/lib/view/expenseAutomationView/selectorTypes/expenseAutomationViewSelectorTypes.d.ts +2 -0
  134. package/lib/view/expenseAutomationView/selectorTypes/jeAccountSettingsViewSelectorTypes.d.ts +1 -0
  135. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.d.ts +42 -0
  136. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +2 -0
  137. package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +36 -7
  138. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.d.ts +9 -0
  139. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +172 -0
  140. package/lib/view/expenseAutomationView/selectors/jeAccountSettingsViewSelector.js +1 -0
  141. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.d.ts +21 -0
  142. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +112 -0
  143. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.d.ts +34 -0
  144. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +305 -21
  145. package/lib/view/expenseAutomationView/types/actualMatchingViewState.d.ts +76 -0
  146. package/lib/view/expenseAutomationView/types/actualMatchingViewState.js +27 -0
  147. package/lib/view/expenseAutomationView/types/completedSubTab.d.ts +1 -1
  148. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +83 -8
  149. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +11 -7
  150. package/lib/view/expenseAutomationView/types/reconciliationViewState.d.ts +1 -1
  151. package/lib/view/scheduleView/scheduleListView/epics/fetchAccruedScheduleListEpic.js +1 -1
  152. package/lib/view/scheduleView/scheduleListView/epics/fetchDownloadSchedulesEpic.js +7 -2
  153. package/lib/view/scheduleView/scheduleListView/scheduleListReducer.d.ts +4 -2
  154. package/lib/view/scheduleView/scheduleListView/scheduleListReducer.js +5 -3
  155. 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: [],
@@ -18,6 +25,7 @@ export const accountSettingsInitialState = {
18
25
  error: undefined,
19
26
  fetchState: 'Not-Started',
20
27
  },
28
+ hasLoadedAccountSettings: false,
21
29
  recommendationFetchState: {
22
30
  error: undefined,
23
31
  fetchState: 'Not-Started',
@@ -36,16 +44,37 @@ export const accountSettingsInitialState = {
36
44
  accruedExpensesNestedAccountListHierarchy: [],
37
45
  accruedExpensesRecommendations: [],
38
46
  };
47
+ export const getBaseNewScheduleLocalData = (scheduleType) => ({
48
+ scheduleType,
49
+ jeScheduleDetails: [],
50
+ });
51
+ export const newScheduleInitialState = {
52
+ fixed_assets: getBaseNewScheduleLocalData('fixed_assets'),
53
+ prepaid_expenses: getBaseNewScheduleLocalData('prepaid_expenses'),
54
+ };
55
+ export const searchTransactionsInitialState = {
56
+ searchResults: [],
57
+ fetchState: 'Not-Started',
58
+ error: undefined,
59
+ };
39
60
  export const initialState = {
40
- jeScheduleTransactionKeysByPeriod: {},
41
- failedJeScheduleTransactionKeysByPeriod: {},
61
+ jeScheduleTransactionKeysByPeriodAndTab: {},
62
+ jeScheduleAccruedKeysByPeriodAndTab: {},
63
+ jeScheduleOneTimeAccrualKeysByPeriodAndTab: {},
64
+ failedJeScheduleTransactionKeysByPeriodAndTab: {},
42
65
  postStatusById: {},
43
66
  ignoreStatusById: {},
67
+ revertStatusById: {},
44
68
  jeScheduleLocalDataById: {},
69
+ oneTimeAccrualActionStatusById: {},
70
+ oneTimeAccrualFetchStatusById: {},
45
71
  uiState: {
46
- searchString: '',
72
+ createdGroupCollapsed: false,
73
+ pendingGroupCollapsed: false,
47
74
  scrollPosition: { scrollTop: 0, scrollLeft: undefined },
48
- selectedMainTab: 'pending_review',
75
+ searchString: '',
76
+ selectedJETypeFilter: null,
77
+ selectedPageTab: 'schedules',
49
78
  sortKey: 'transactionDate',
50
79
  sortOrder: 'descending',
51
80
  totalCount: 0,
@@ -56,6 +85,14 @@ export const initialState = {
56
85
  error: undefined,
57
86
  },
58
87
  accountSettings: accountSettingsInitialState,
88
+ newSchedule: {
89
+ createOneTimeAccrualStatus: { fetchState: 'Not-Started', error: undefined },
90
+ newScheduleState: newScheduleInitialState,
91
+ saveStatus: { fetchState: 'Not-Started', error: undefined },
92
+ searchTransactions: searchTransactionsInitialState,
93
+ fetchState: 'Not-Started',
94
+ error: undefined,
95
+ },
59
96
  fetchState: 'Not-Started',
60
97
  error: undefined,
61
98
  hasValidState() {
@@ -100,9 +137,12 @@ const expenseAutomationJESchedulesView = createSlice({
100
137
  },
101
138
  },
102
139
  fetchJeSchedulesSuccess(draft, action) {
103
- const { jeSchedules, selectedPeriod, failedJeSchedules, refreshViewInBackground, } = action.payload;
140
+ const { jeSchedules, selectedPeriod, selectedPageTab, failedJeSchedules, accruedJeSchedules, oneTimeAccruals, refreshViewInBackground, } = action.payload;
141
+ const periodTabKey = getJESchedulePeriodTabKey(selectedPageTab, toMonthYearPeriodId(selectedPeriod));
104
142
  const jeScheduleTransactionKeys = jeSchedules.map((schedules) => getJEScheduleTransactionDetailKeyPayload(schedules.base_transaction));
105
143
  const failedJeScheduleTransactionKeys = failedJeSchedules.map((schedules) => getJEScheduleTransactionDetailKeyPayload(schedules.base_transaction));
144
+ const jeScheduleAccruedKeys = accruedJeSchedules.map((schedule) => getJEScheduleKey(schedule));
145
+ const jeScheduleOneTimeAccrualKeys = oneTimeAccruals.map((accrual) => generateJEOneTimeAccrualKey(accrual._id));
106
146
  if (refreshViewInBackground === true &&
107
147
  draft.refreshStatus.fetchState === 'In-Progress') {
108
148
  draft.refreshStatus = { fetchState: 'Completed', error: undefined };
@@ -111,19 +151,31 @@ const expenseAutomationJESchedulesView = createSlice({
111
151
  draft.fetchState = 'Completed';
112
152
  draft.error = undefined;
113
153
  }
114
- draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = jeScheduleTransactionKeys;
115
- draft.failedJeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = failedJeScheduleTransactionKeys;
154
+ draft.jeScheduleTransactionKeysByPeriodAndTab[periodTabKey] =
155
+ jeScheduleTransactionKeys;
156
+ draft.jeScheduleAccruedKeysByPeriodAndTab[periodTabKey] =
157
+ jeScheduleAccruedKeys;
158
+ draft.jeScheduleOneTimeAccrualKeysByPeriodAndTab[periodTabKey] =
159
+ jeScheduleOneTimeAccrualKeys;
160
+ draft.failedJeScheduleTransactionKeysByPeriodAndTab[periodTabKey] =
161
+ failedJeScheduleTransactionKeys;
116
162
  },
117
163
  fetchJeSchedulesFailure(draft, action) {
118
- const { status, selectedPeriod } = action.payload;
164
+ const { status, selectedPeriod, selectedPageTab } = action.payload;
165
+ const periodTabKey = getJESchedulePeriodTabKey(selectedPageTab, toMonthYearPeriodId(selectedPeriod));
119
166
  if (draft.refreshStatus.fetchState === 'In-Progress') {
120
167
  draft.refreshStatus = { fetchState: 'Error', error: status };
121
168
  }
122
169
  else {
123
170
  draft.fetchState = 'Error';
124
171
  draft.error = status;
172
+ draft.jeScheduleTransactionKeysByPeriodAndTab[periodTabKey] = [];
173
+ draft.jeScheduleAccruedKeysByPeriodAndTab[periodTabKey] = [];
174
+ draft.jeScheduleOneTimeAccrualKeysByPeriodAndTab[periodTabKey] = [];
175
+ // Cleared with the rest: leaving it behind kept the previous fetch's resolve rows on an
176
+ // otherwise empty errored tab, which reads as "these are all the schedules there are".
177
+ draft.failedJeScheduleTransactionKeysByPeriodAndTab[periodTabKey] = [];
125
178
  }
126
- draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = [];
127
179
  },
128
180
  retryJeSchedule(draft, action) {
129
181
  const { scheduledJournalEntryID } = action.payload;
@@ -159,11 +211,13 @@ const expenseAutomationJESchedulesView = createSlice({
159
211
  };
160
212
  },
161
213
  ignoreRecommendedJeSchedule: {
162
- prepare(jeScheduleTransactionKey, scheduleType) {
214
+ prepare(jeScheduleTransactionKey, scheduleType, reason, note) {
163
215
  return {
164
216
  payload: {
165
217
  jeScheduleTransactionKey,
166
218
  scheduleType,
219
+ reason,
220
+ note,
167
221
  },
168
222
  };
169
223
  },
@@ -179,6 +233,41 @@ const expenseAutomationJESchedulesView = createSlice({
179
233
  };
180
234
  },
181
235
  },
236
+ revertJeSchedule: {
237
+ // jeScheduleTransactionKey is a JEScheduleKey for an accrued schedule, which has no base
238
+ // transaction to derive a transaction key from. It is only ever used as an opaque row
239
+ // identifier here -- for the row's spinner and for dropping the row from the list -- so one
240
+ // action serves both shapes rather than two near-identical ones.
241
+ prepare(jeScheduleId, jeScheduleTransactionKey, scheduleType, reason, note) {
242
+ return {
243
+ payload: {
244
+ jeScheduleId,
245
+ jeScheduleTransactionKey,
246
+ scheduleType,
247
+ reason,
248
+ note,
249
+ },
250
+ };
251
+ },
252
+ reducer(draft, action) {
253
+ draft.revertStatusById[action.payload.jeScheduleTransactionKey] = {
254
+ fetchState: 'In-Progress',
255
+ error: undefined,
256
+ };
257
+ },
258
+ },
259
+ revertJeScheduleSuccess(draft, action) {
260
+ draft.revertStatusById[action.payload.jeScheduleTransactionKey] = {
261
+ fetchState: 'Completed',
262
+ error: undefined,
263
+ };
264
+ },
265
+ revertJeScheduleFailure(draft, action) {
266
+ draft.revertStatusById[action.payload.jeScheduleTransactionKey] = {
267
+ fetchState: 'Error',
268
+ error: action.payload.status,
269
+ };
270
+ },
182
271
  ignoreRecommendedJeScheduleSuccess: {
183
272
  reducer(draft, action) {
184
273
  const { jeScheduleTransactionKey } = action.payload;
@@ -211,17 +300,18 @@ const expenseAutomationJESchedulesView = createSlice({
211
300
  };
212
301
  },
213
302
  updateJeScheduleTransactionKeys: {
214
- prepare(jeScheduleKeys, selectedPeriod) {
303
+ prepare(jeScheduleKeys, selectedPeriod, selectedPageTab) {
215
304
  return {
216
305
  payload: {
217
306
  jeScheduleKeys: jeScheduleKeys,
218
307
  selectedPeriod: selectedPeriod,
308
+ selectedPageTab: selectedPageTab,
219
309
  },
220
310
  };
221
311
  },
222
312
  reducer(draft, action) {
223
- const { selectedPeriod, jeScheduleKeys } = action.payload;
224
- draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = jeScheduleKeys;
313
+ const { selectedPeriod, selectedPageTab, jeScheduleKeys } = action.payload;
314
+ draft.jeScheduleTransactionKeysByPeriodAndTab[getJESchedulePeriodTabKey(selectedPageTab, toMonthYearPeriodId(selectedPeriod))] = jeScheduleKeys;
225
315
  },
226
316
  },
227
317
  removeJeScheduleTransactionKey: {
@@ -234,12 +324,20 @@ const expenseAutomationJESchedulesView = createSlice({
234
324
  };
235
325
  },
236
326
  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;
327
+ const { jeScheduleKey } = action.payload;
328
+ // Dropped from every tab's slot, not just the visible one: once a schedule is ignored or
329
+ // resolved it must not reappear when the user switches tabs and hits a cached list.
330
+ removeKeyFromEveryTabSlot(draft.jeScheduleTransactionKeysByPeriodAndTab, jeScheduleKey);
331
+ },
332
+ },
333
+ removeJeAccruedScheduleKey: {
334
+ prepare(jeAccruedScheduleKey) {
335
+ return { payload: { jeAccruedScheduleKey } };
336
+ },
337
+ reducer(draft, action) {
338
+ // Accrued keys live in their own per-tab map, so removeJeScheduleTransactionKey cannot drop
339
+ // them -- a reverted accrued schedule stayed on the list until the next fetch.
340
+ removeKeyFromEveryTabSlot(draft.jeScheduleAccruedKeysByPeriodAndTab, action.payload.jeAccruedScheduleKey);
243
341
  },
244
342
  },
245
343
  removeFailedJeScheduleTransactionKey: {
@@ -252,12 +350,8 @@ const expenseAutomationJESchedulesView = createSlice({
252
350
  };
253
351
  },
254
352
  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;
353
+ const { failedJeScheduleKey } = action.payload;
354
+ removeKeyFromEveryTabSlot(draft.failedJeScheduleTransactionKeysByPeriodAndTab, failedJeScheduleKey);
261
355
  },
262
356
  },
263
357
  initializeJeScheduleLocalData: {
@@ -336,6 +430,9 @@ const expenseAutomationJESchedulesView = createSlice({
336
430
  error: status,
337
431
  fetchState: 'Error',
338
432
  };
433
+ // Set on failure too: a tenant whose account list errors must still reach the page rather
434
+ // than sit under a skeleton forever.
435
+ draft.accountSettings.hasLoadedAccountSettings = true;
339
436
  },
340
437
  updateAccountSettingsListForAccountTypes(draft, action) {
341
438
  doUpdateAccountSettingsListForAccountTypes(draft.accountSettings, action.payload.accountPayload);
@@ -369,6 +466,182 @@ const expenseAutomationJESchedulesView = createSlice({
369
466
  clearJeAccountSettingsLocalData(draft) {
370
467
  draft.accountSettings.localData = accountSettingsInitialState.localData;
371
468
  },
469
+ initializeNewSchedule: {
470
+ prepare({ scheduleType, shouldResetEnteredData = true, }) {
471
+ return { payload: { scheduleType, shouldResetEnteredData } };
472
+ },
473
+ reducer() {
474
+ // Purely an epic-trigger action — the epic fans out the account/class
475
+ // list fetches, and clears entered data only when asked to.
476
+ },
477
+ },
478
+ resetNewScheduleLocalData: {
479
+ prepare({ scheduleType, }) {
480
+ return { payload: { scheduleType } };
481
+ },
482
+ reducer(draft, action) {
483
+ const { scheduleType } = action.payload;
484
+ draft.newSchedule.newScheduleState[scheduleType] =
485
+ getBaseNewScheduleLocalData(scheduleType);
486
+ },
487
+ },
488
+ updateNewScheduleLocalData(draft, action) {
489
+ const { scheduleType, localData } = action.payload;
490
+ draft.newSchedule.newScheduleState[scheduleType] = {
491
+ ...draft.newSchedule.newScheduleState[scheduleType],
492
+ ...localData,
493
+ };
494
+ },
495
+ searchTransactionsForNewSchedule: {
496
+ prepare({ query, scheduleType, }) {
497
+ return { payload: { query, scheduleType } };
498
+ },
499
+ reducer(draft, action) {
500
+ const trimmed = action.payload.query.trim();
501
+ // Cleared or too-short query: no API (see epic) — reset immediately.
502
+ if (trimmed.length < MIN_NEW_SCHEDULE_SEARCH_LENGTH) {
503
+ draft.newSchedule.searchTransactions = searchTransactionsInitialState;
504
+ return;
505
+ }
506
+ draft.newSchedule.searchTransactions = {
507
+ ...draft.newSchedule.searchTransactions,
508
+ searchString: action.payload.query,
509
+ fetchState: 'In-Progress',
510
+ };
511
+ },
512
+ },
513
+ searchTransactionsForNewScheduleSuccess(draft, action) {
514
+ draft.newSchedule.searchTransactions = {
515
+ ...draft.newSchedule.searchTransactions,
516
+ searchResults: action.payload.searchResults,
517
+ fetchState: 'Completed',
518
+ error: undefined,
519
+ };
520
+ },
521
+ searchTransactionsForNewScheduleFailure(draft, action) {
522
+ draft.newSchedule.searchTransactions = {
523
+ ...draft.newSchedule.searchTransactions,
524
+ fetchState: 'Error',
525
+ error: action.payload.status,
526
+ };
527
+ },
528
+ clearSearchTransactionsForNewSchedule(draft) {
529
+ draft.newSchedule.searchTransactions = searchTransactionsInitialState;
530
+ },
531
+ saveNewSchedule: {
532
+ prepare({ scheduleType, }) {
533
+ return { payload: { scheduleType } };
534
+ },
535
+ reducer(draft) {
536
+ draft.newSchedule.saveStatus = {
537
+ fetchState: 'In-Progress',
538
+ error: undefined,
539
+ };
540
+ },
541
+ },
542
+ saveNewScheduleSuccess(draft) {
543
+ draft.newSchedule.saveStatus = {
544
+ fetchState: 'Completed',
545
+ error: undefined,
546
+ };
547
+ },
548
+ saveNewScheduleFailure(draft, action) {
549
+ draft.newSchedule.saveStatus = {
550
+ fetchState: 'Error',
551
+ error: action.payload.status,
552
+ };
553
+ },
554
+ createOneTimeAccrual: {
555
+ prepare(localData) {
556
+ return { payload: { localData } };
557
+ },
558
+ reducer(draft) {
559
+ draft.newSchedule.createOneTimeAccrualStatus = {
560
+ fetchState: 'In-Progress',
561
+ error: undefined,
562
+ };
563
+ },
564
+ },
565
+ createOneTimeAccrualSuccess(draft) {
566
+ draft.newSchedule.createOneTimeAccrualStatus = {
567
+ fetchState: 'Completed',
568
+ error: undefined,
569
+ };
570
+ },
571
+ createOneTimeAccrualFailure(draft, action) {
572
+ draft.newSchedule.createOneTimeAccrualStatus = {
573
+ fetchState: 'Error',
574
+ error: action.payload.status,
575
+ };
576
+ },
577
+ promoteOneTimeAccrual: {
578
+ prepare(accrualId, amount) {
579
+ return { payload: { accrualId, amount } };
580
+ },
581
+ reducer(draft, action) {
582
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
583
+ fetchState: 'In-Progress',
584
+ error: undefined,
585
+ };
586
+ },
587
+ },
588
+ revertOneTimeAccrual: {
589
+ prepare(accrualId, reason, note) {
590
+ return { payload: { accrualId, reason, note } };
591
+ },
592
+ reducer(draft, action) {
593
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
594
+ fetchState: 'In-Progress',
595
+ error: undefined,
596
+ };
597
+ },
598
+ },
599
+ ignoreOneTimeAccrual: {
600
+ prepare(accrualId, reason, note) {
601
+ return { payload: { accrualId, reason, note } };
602
+ },
603
+ reducer(draft, action) {
604
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
605
+ fetchState: 'In-Progress',
606
+ error: undefined,
607
+ };
608
+ },
609
+ },
610
+ fetchOneTimeAccrual: {
611
+ prepare(accrualId) {
612
+ return { payload: { accrualId } };
613
+ },
614
+ reducer(draft, action) {
615
+ draft.oneTimeAccrualFetchStatusById[action.payload.accrualId] = {
616
+ fetchState: 'In-Progress',
617
+ error: undefined,
618
+ };
619
+ },
620
+ },
621
+ fetchOneTimeAccrualSuccess(draft, action) {
622
+ draft.oneTimeAccrualFetchStatusById[action.payload.accrualId] = {
623
+ fetchState: 'Completed',
624
+ error: undefined,
625
+ };
626
+ },
627
+ fetchOneTimeAccrualFailure(draft, action) {
628
+ draft.oneTimeAccrualFetchStatusById[action.payload.accrualId] = {
629
+ fetchState: 'Error',
630
+ error: action.payload.status,
631
+ };
632
+ },
633
+ oneTimeAccrualActionSuccess(draft, action) {
634
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
635
+ fetchState: 'Completed',
636
+ error: undefined,
637
+ };
638
+ },
639
+ oneTimeAccrualActionFailure(draft, action) {
640
+ draft.oneTimeAccrualActionStatusById[action.payload.accrualId] = {
641
+ fetchState: 'Error',
642
+ error: action.payload.status,
643
+ };
644
+ },
372
645
  updateJESchedulesUIState(draft, action) {
373
646
  if (action.payload.sortKey != null) {
374
647
  draft.uiState.sortKey = action.payload.sortKey;
@@ -382,10 +655,21 @@ const expenseAutomationJESchedulesView = createSlice({
382
655
  if (action.payload.scrollPosition != null) {
383
656
  draft.uiState.scrollPosition = action.payload.scrollPosition;
384
657
  }
385
- if (action.payload.selectedMainTab != null) {
386
- draft.uiState.selectedMainTab = action.payload.selectedMainTab;
658
+ if (action.payload.selectedPageTab != null) {
659
+ draft.uiState.selectedPageTab = action.payload.selectedPageTab;
387
660
  }
388
661
  },
662
+ updateJEScheduleTypeFilter(draft, action) {
663
+ draft.uiState.selectedJETypeFilter = action.payload;
664
+ },
665
+ toggleJEPendingGroupCollapsed(draft) {
666
+ draft.uiState.pendingGroupCollapsed =
667
+ !draft.uiState.pendingGroupCollapsed;
668
+ },
669
+ toggleJECreatedGroupCollapsed(draft) {
670
+ draft.uiState.createdGroupCollapsed =
671
+ !draft.uiState.createdGroupCollapsed;
672
+ },
389
673
  clearExpenseAutomationJESchedulesView(draft) {
390
674
  Object.assign(draft, initialState);
391
675
  },
@@ -396,7 +680,7 @@ const expenseAutomationJESchedulesView = createSlice({
396
680
  });
397
681
  },
398
682
  });
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;
683
+ 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
684
  export default expenseAutomationJESchedulesView.reducer;
401
685
  const doUpdateRecommendationForAccountSettings = (draft, payload) => {
402
686
  const { prepaidExpensesRecommendations, fixedAssetsRecommendations, accruedExpensesRecommendations, } = mapAccountTypeRecommendationPayloadToAccountRecommendationByType(payload);
@@ -464,4 +748,5 @@ const doUpdateAccountSettingsListForAccountTypes = (draft, accountPayloadList) =
464
748
  error: undefined,
465
749
  fetchState: 'Completed',
466
750
  };
751
+ draft.hasLoadedAccountSettings = true;
467
752
  };
@@ -0,0 +1,162 @@
1
+ import orderBy from 'lodash/orderBy';
2
+ import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
3
+ import { getJEOneTimeAccrualByKey, } from '../../../entity/jeSchedules/jeSchedulesSelector';
4
+ import { getCurrentTenant } from '../../../entity/tenant/tenantSelector';
5
+ export function isAutoReversedAccrual(accrual) {
6
+ return (accrual.accrualStatus === 'reversed' &&
7
+ accrual.reversalTrigger === 'bill_match');
8
+ }
9
+ export function isPendingReviewAccrual(accrual) {
10
+ if (accrual.accrualStatus !== 'posted' || accrual.matchSuggestion == null) {
11
+ return false;
12
+ }
13
+ const resolution = accrual.matchSuggestion.resolution;
14
+ return resolution == null || resolution.length === 0;
15
+ }
16
+ export function getActualMatchingAmount(accrual) {
17
+ return (accrual.cleared?.matchedAmount?.amount ?? accrual.estimatedAmount.amount);
18
+ }
19
+ export function getActualMatchingReversalDate(accrual) {
20
+ if (!isAutoReversedAccrual(accrual)) {
21
+ return undefined;
22
+ }
23
+ return accrual.actualReversalPostDate ?? accrual.cleared?.reversedAt;
24
+ }
25
+ function toActualMatchingRow(accrual, kind) {
26
+ return {
27
+ ...accrual,
28
+ kind,
29
+ reversalDate: kind === 'auto_reversed'
30
+ ? getActualMatchingReversalDate(accrual)
31
+ : undefined,
32
+ };
33
+ }
34
+ function matchesSearch(accrual, searchString) {
35
+ const trimmed = searchString.trim().toLowerCase();
36
+ if (trimmed.length === 0) {
37
+ return true;
38
+ }
39
+ return (accrual.vendorName.toLowerCase().includes(trimmed) ||
40
+ accrual.memo.toLowerCase().includes(trimmed));
41
+ }
42
+ function getActualMatchingSortValue(row, sortKey) {
43
+ switch (sortKey) {
44
+ case 'vendor':
45
+ return row.vendorName.toLowerCase();
46
+ case 'date':
47
+ return row.reversalDate?.valueOf();
48
+ case 'amount':
49
+ return getActualMatchingAmount(row);
50
+ case 'category':
51
+ return row.jeDebitAccountName?.toLowerCase();
52
+ case 'class':
53
+ return row.jeDebitAccountingClassName?.toLowerCase();
54
+ case 'type':
55
+ return (row.cleared?.matchedTransactionType ??
56
+ row.matchSuggestion?.matchedTransactionType)?.toLowerCase();
57
+ case 'lifecycle':
58
+ return row.kind;
59
+ default:
60
+ return undefined;
61
+ }
62
+ }
63
+ function sortActualMatchingRows(rows, uiState) {
64
+ const lodashOrder = uiState.sortOrder === 'ascending' ? 'asc' : 'desc';
65
+ return orderBy(rows, [(row) => getActualMatchingSortValue(row, uiState.sortKey)], [lodashOrder]);
66
+ }
67
+ function emptyKpiSummary() {
68
+ return {
69
+ autoReversed: { count: 0, amount: 0 },
70
+ pendingReview: { count: 0, amount: 0 },
71
+ totalThisClose: { count: 0, amount: 0 },
72
+ ai: { count: 0 },
73
+ manual: { count: 0 },
74
+ };
75
+ }
76
+ export function getExpenseAutomationActualMatchingView(state) {
77
+ const { expenseAutomationActualMatchingViewState, expenseAutomationViewState } = state;
78
+ const { accrualKeysByPeriod, fetchState, error, refreshStatus, uiState, matchModal, } = expenseAutomationActualMatchingViewState;
79
+ const currentTenant = getCurrentTenant(state);
80
+ const selectedPeriod = expenseAutomationViewState.selectedPeriodByTenantId[currentTenant.tenantId];
81
+ const monthYearPeriodId = selectedPeriod != null ? toMonthYearPeriodId(selectedPeriod) : undefined;
82
+ const accrualKeys = monthYearPeriodId != null
83
+ ? accrualKeysByPeriod[monthYearPeriodId]
84
+ : undefined;
85
+ const accruals = (accrualKeys ?? [])
86
+ .map((key) => getJEOneTimeAccrualByKey(key, state.jeSchedulesState))
87
+ .filter((accrual) => accrual != null);
88
+ const filtered = accruals.filter((accrual) => matchesSearch(accrual, uiState.searchString));
89
+ const autoReversed = sortActualMatchingRows(filtered
90
+ .filter(isAutoReversedAccrual)
91
+ .map((accrual) => toActualMatchingRow(accrual, 'auto_reversed')), uiState);
92
+ const pendingReview = sortActualMatchingRows(filtered
93
+ .filter(isPendingReviewAccrual)
94
+ .map((accrual) => toActualMatchingRow(accrual, 'pending_review')), uiState);
95
+ const kpiSource = accruals;
96
+ const kpiSummary = kpiSource.length === 0
97
+ ? emptyKpiSummary()
98
+ : {
99
+ autoReversed: {
100
+ count: kpiSource.filter(isAutoReversedAccrual).length,
101
+ amount: kpiSource
102
+ .filter(isAutoReversedAccrual)
103
+ .reduce((sum, accrual) => sum + getActualMatchingAmount(accrual), 0),
104
+ },
105
+ pendingReview: {
106
+ count: kpiSource.filter(isPendingReviewAccrual).length,
107
+ amount: kpiSource
108
+ .filter(isPendingReviewAccrual)
109
+ .reduce((sum, accrual) => sum + getActualMatchingAmount(accrual), 0),
110
+ },
111
+ totalThisClose: {
112
+ count: kpiSource.length,
113
+ amount: kpiSource.reduce((sum, accrual) => sum + getActualMatchingAmount(accrual), 0),
114
+ },
115
+ ai: {
116
+ count: kpiSource.filter((accrual) => accrual.origin === 'agent')
117
+ .length,
118
+ },
119
+ manual: {
120
+ count: kpiSource.filter((accrual) => accrual.origin === 'human')
121
+ .length,
122
+ },
123
+ };
124
+ const accrualSearchResults = matchModal.accrualSearch.results
125
+ .map((key) => getJEOneTimeAccrualByKey(key, state.jeSchedulesState))
126
+ .filter((accrual) => accrual != null);
127
+ return {
128
+ fetchState,
129
+ error,
130
+ autoReversed,
131
+ pendingReview,
132
+ kpiSummary,
133
+ uiState,
134
+ refreshStatus,
135
+ hasLoadedForSelectedPeriod: accrualKeys != null,
136
+ matchModal: {
137
+ isOpen: matchModal.isOpen,
138
+ confirmStatus: matchModal.confirmStatus,
139
+ lastBatchResults: matchModal.lastBatchResults,
140
+ transactionSearch: {
141
+ query: matchModal.transactionSearch.query,
142
+ results: matchModal.transactionSearch.results,
143
+ fetchState: {
144
+ fetchState: matchModal.transactionSearch.fetchState,
145
+ error: matchModal.transactionSearch.error,
146
+ },
147
+ nextPageToken: matchModal.transactionSearch.nextPageToken,
148
+ isLoadingMore: matchModal.transactionSearch.isLoadingMore,
149
+ },
150
+ accrualSearch: {
151
+ query: matchModal.accrualSearch.query,
152
+ results: accrualSearchResults,
153
+ fetchState: {
154
+ fetchState: matchModal.accrualSearch.fetchState,
155
+ error: matchModal.accrualSearch.error,
156
+ },
157
+ nextPageToken: matchModal.accrualSearch.nextPageToken,
158
+ isLoadingMore: matchModal.accrualSearch.isLoadingMore,
159
+ },
160
+ },
161
+ };
162
+ }
@@ -22,6 +22,7 @@ export const getJEAccountSettingsView = createSelector((state) => state.expenseA
22
22
  fixedAssetsAccountHierarchy: jeAccountMappingState.fixedAssetsNestedAccountListHierarchy,
23
23
  accruedExpensesAccountHierarchy: jeAccountMappingState.accruedExpensesNestedAccountListHierarchy,
24
24
  fetchState: fetchState.fetchState,
25
+ hasLoaded: jeAccountMappingState.hasLoadedAccountSettings,
25
26
  saveState,
26
27
  };
27
28
  });