@zeniai/client-epic-state 5.0.79 → 5.0.80

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 (183) hide show
  1. package/lib/coreEpics.js +1 -1
  2. package/lib/entity/account/accountSelector.d.ts +1 -27
  3. package/lib/entity/account/accountSelector.js +1 -47
  4. package/lib/entity/account/accountState.d.ts +1 -6
  5. package/lib/entity/account/accountState.js +4 -11
  6. package/lib/entity/account/subAccountSelector.d.ts +1 -1
  7. package/lib/entity/aiAccountantCustomer/aiAccountantCustomerPayload.js +3 -1
  8. package/lib/entity/aiAccountantCustomer/aiAccountantCustomerReducer.js +2 -1
  9. package/lib/entity/aiAccountantCustomer/aiAccountantCustomerSelector.d.ts +1 -1
  10. package/lib/entity/chargeCard/chargeCardReducer.d.ts +2 -19
  11. package/lib/entity/chargeCard/chargeCardReducer.js +2 -35
  12. package/lib/entity/chargeCardTransaction/chargeCardTransactionReducer.d.ts +1 -14
  13. package/lib/entity/chargeCardTransaction/chargeCardTransactionReducer.js +2 -36
  14. package/lib/entity/class/classSelector.d.ts +0 -35
  15. package/lib/entity/class/classSelector.js +0 -50
  16. package/lib/entity/sectionProjectView/sectionProjectViewReducer.d.ts +1 -1
  17. package/lib/entity/sectionProjectView/sectionProjectViewSelector.js +1 -1
  18. package/lib/entity/tenant/SessionManager.js +3 -6
  19. package/lib/entity/tenant/clearAllEpic.d.ts +2 -2
  20. package/lib/entity/tenant/clearAllEpic.js +2 -2
  21. package/lib/entity/tenant/epic/saveAPIKeyConnectionEpic.js +2 -6
  22. package/lib/entity/tenant/epic/saveOAuthConnectionEpic.js +2 -6
  23. package/lib/entity/tenant/tenantReducer.js +1 -6
  24. package/lib/entity/transaction/payloadTypes/transactionLinePayload.js +1 -3
  25. package/lib/epic.d.ts +11 -11
  26. package/lib/epic.js +12 -12
  27. package/lib/esm/coreEpics.js +1 -1
  28. package/lib/esm/entity/account/accountSelector.js +1 -46
  29. package/lib/esm/entity/account/accountState.js +1 -7
  30. package/lib/esm/entity/aiAccountantCustomer/aiAccountantCustomerPayload.js +3 -1
  31. package/lib/esm/entity/aiAccountantCustomer/aiAccountantCustomerReducer.js +2 -1
  32. package/lib/esm/entity/chargeCard/chargeCardReducer.js +1 -34
  33. package/lib/esm/entity/chargeCardTransaction/chargeCardTransactionReducer.js +1 -35
  34. package/lib/esm/entity/class/classSelector.js +0 -48
  35. package/lib/esm/entity/sectionProjectView/sectionProjectViewSelector.js +1 -1
  36. package/lib/esm/entity/tenant/SessionManager.js +1 -4
  37. package/lib/esm/entity/tenant/clearAllEpic.js +2 -2
  38. package/lib/esm/entity/tenant/epic/saveAPIKeyConnectionEpic.js +2 -6
  39. package/lib/esm/entity/tenant/epic/saveOAuthConnectionEpic.js +2 -6
  40. package/lib/esm/entity/tenant/tenantReducer.js +1 -6
  41. package/lib/esm/entity/transaction/payloadTypes/transactionLinePayload.js +1 -3
  42. package/lib/esm/epic.js +12 -12
  43. package/lib/esm/index.js +21 -31
  44. package/lib/esm/reducer.js +2 -2
  45. package/lib/esm/view/aiAccountantView/epics/fetchAiAccountantCustomersEpic.js +5 -2
  46. package/lib/esm/view/aiAccountantView/epics/fetchAiAccountantJobsEpic.js +5 -2
  47. package/lib/esm/view/aiAccountantView/epics/triggerAiAccountantJobEpic.js +1 -4
  48. package/lib/esm/view/companyHealthMetricView/companyHealthMetricViewSelector.js +1 -1
  49. package/lib/esm/view/companyTaskManagerView/companyTaskManagerViewSelector.js +1 -1
  50. package/lib/esm/view/companyTaskManagerView/epics/fetchTaskManagerMetricsEpic.js +1 -1
  51. package/lib/esm/view/companyView/helpers/cockpitHelpers.js +1 -1
  52. package/lib/esm/view/companyView/selector/companyManagementViewSelector.js +1 -1
  53. package/lib/esm/view/companyView/selector/companyPortfolioViewSelector.js +1 -1
  54. package/lib/esm/view/creditAgentView/creditAgentViewReducer.js +16 -1
  55. package/lib/esm/view/creditAgentView/epics/fetchCreditAgentAccessEpic.js +13 -0
  56. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js +2 -2
  57. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +1 -2
  58. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/restoreBulkUploadAutomatchingOnMountEpic.js +6 -8
  59. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +1 -7
  60. package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +1 -11
  61. package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +1 -21
  62. package/lib/esm/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +1 -2
  63. package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +14 -253
  64. package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +13 -147
  65. package/lib/esm/view/expenseAutomationView/types/missingReceiptsViewState.js +2 -0
  66. package/lib/esm/view/financeStatement/financeStatementSelector.js +1 -1
  67. package/lib/esm/view/recommendation/recommendationHelper.js +0 -29
  68. package/lib/esm/view/recommendation/recommendationReducer.js +1 -26
  69. package/lib/esm/view/spendManagement/chargeCards/cashbackDetail/cashbackDetailReducer.js +2 -3
  70. package/lib/esm/view/spendManagement/chargeCards/chargeCardConfig/chargeCardConfigReducer.js +2 -3
  71. package/lib/esm/view/spendManagement/chargeCards/chargeCardDetail/chargeCardDetailReducer.js +18 -55
  72. package/lib/esm/view/spendManagement/chargeCards/chargeCardDetail/fetchChargeCardDetailEpic.js +2 -16
  73. package/lib/esm/view/spendManagement/chargeCards/chargeCardDetail/fetchChargeCardDetailPageEpic.js +4 -5
  74. package/lib/esm/view/spendManagement/chargeCards/chargeCardList/chargeCardListReducer.js +9 -26
  75. package/lib/esm/view/spendManagement/chargeCards/chargeCardList/fetchChargeCardListPageEpic.js +6 -9
  76. package/lib/esm/view/spendManagement/chargeCards/chargeCardPaymentHistory/chargeCardPaymentHistoryReducer.js +2 -3
  77. package/lib/esm/view/spendManagement/chargeCards/chargeCardPaymentHistory/fetchChargeCardPaymentPageEpic.js +1 -1
  78. package/lib/esm/view/spendManagement/chargeCards/chargeCardRepaymentDetail/chargeCardRepaymentDetailReducer.js +3 -7
  79. package/lib/esm/view/spendManagement/spendManagementFilterHelpers.js +2 -4
  80. package/lib/esm/view/subscriptionView/subscriptionViewSelector.js +1 -1
  81. package/lib/esm/view/taskManager/cannedResponsesView/epics/fetchCannedResponsesEpic.js +1 -1
  82. package/lib/esm/view/taskManager/cannedResponsesView/epics/saveCannedResponseEpic.js +1 -1
  83. package/lib/esm/view/taskManager/taskDetailView/epics/unsnoozeTaskEpic.js +1 -1
  84. package/lib/esm/view/taskManager/taskListView/taskListReducer.js +1 -1
  85. package/lib/esm/view/transactionDetail/transactionDetailReducer.js +6 -121
  86. package/lib/esm/view/transactionDetail/transactionDetailSelector.js +1 -29
  87. package/lib/index.d.ts +24 -31
  88. package/lib/index.js +60 -84
  89. package/lib/reducer.d.ts +2 -2
  90. package/lib/reducer.js +2 -2
  91. package/lib/tsconfig.typecheck.tsbuildinfo +1 -0
  92. package/lib/view/aiAccountantView/aiAccountantViewPayload.d.ts +2 -2
  93. package/lib/view/aiAccountantView/aiAccountantViewReducer.d.ts +1 -1
  94. package/lib/view/aiAccountantView/epics/fetchAiAccountantCustomersEpic.js +5 -2
  95. package/lib/view/aiAccountantView/epics/fetchAiAccountantJobsEpic.js +5 -2
  96. package/lib/view/aiAccountantView/epics/triggerAiAccountantJobEpic.js +1 -4
  97. package/lib/view/companyHealthMetricView/companyHealthMetricViewSelector.js +1 -1
  98. package/lib/view/companyTaskManagerView/companyTaskManagerViewSelector.d.ts +1 -1
  99. package/lib/view/companyTaskManagerView/companyTaskManagerViewSelector.js +1 -1
  100. package/lib/view/companyView/helpers/cockpitHelpers.js +1 -1
  101. package/lib/view/companyView/selector/companyManagementViewSelector.js +1 -1
  102. package/lib/view/companyView/selector/companyPortfolioViewSelector.js +1 -1
  103. package/lib/view/companyView/types/cockpitTypes.d.ts +1 -1
  104. package/lib/view/creditAgentView/creditAgentViewPayload.d.ts +3 -0
  105. package/lib/view/creditAgentView/creditAgentViewReducer.d.ts +1 -1
  106. package/lib/view/creditAgentView/creditAgentViewReducer.js +17 -2
  107. package/lib/view/creditAgentView/creditAgentViewState.d.ts +5 -0
  108. package/lib/view/creditAgentView/epics/fetchCreditAgentAccessEpic.d.ts +11 -0
  109. package/lib/view/creditAgentView/epics/fetchCreditAgentAccessEpic.js +17 -0
  110. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js +2 -2
  111. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +1 -2
  112. package/lib/view/expenseAutomationView/epics/missingReceipts/restoreBulkUploadAutomatchingOnMountEpic.js +6 -8
  113. package/lib/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +1 -7
  114. package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.d.ts +2 -2
  115. package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +0 -10
  116. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -2
  117. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +2 -23
  118. package/lib/view/expenseAutomationView/payload/transactionCategorizationPayload.d.ts +0 -21
  119. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +1 -2
  120. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +1 -2
  121. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +5 -28
  122. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +14 -253
  123. package/lib/view/expenseAutomationView/selectorTypes/missingReceiptsSelectorTypes.d.ts +1 -2
  124. package/lib/view/expenseAutomationView/selectorTypes/transactionsViewSelectorTypes.d.ts +0 -16
  125. package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.d.ts +1 -7
  126. package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +13 -150
  127. package/lib/view/expenseAutomationView/types/missingReceiptsViewState.d.ts +2 -1
  128. package/lib/view/expenseAutomationView/types/missingReceiptsViewState.js +4 -1
  129. package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +2 -44
  130. package/lib/view/financeStatement/financeStatementSelector.js +1 -1
  131. package/lib/view/profitAndLossProjectView/profitAndLossProjectViewSelectorTypes.d.ts +1 -1
  132. package/lib/view/recommendation/recommendationHelper.d.ts +0 -9
  133. package/lib/view/recommendation/recommendationHelper.js +1 -31
  134. package/lib/view/recommendation/recommendationReducer.d.ts +1 -20
  135. package/lib/view/recommendation/recommendationReducer.js +2 -27
  136. package/lib/view/spendManagement/billPay/billList/billListState.d.ts +1 -1
  137. package/lib/view/spendManagement/chargeCards/cashbackDetail/cashbackDetailReducer.d.ts +1 -3
  138. package/lib/view/spendManagement/chargeCards/cashbackDetail/cashbackDetailReducer.js +2 -3
  139. package/lib/view/spendManagement/chargeCards/chargeCardConfig/chargeCardConfigReducer.d.ts +1 -3
  140. package/lib/view/spendManagement/chargeCards/chargeCardConfig/chargeCardConfigReducer.js +2 -3
  141. package/lib/view/spendManagement/chargeCards/chargeCardDetail/chargeCardDetailReducer.js +18 -55
  142. package/lib/view/spendManagement/chargeCards/chargeCardDetail/fetchChargeCardDetailEpic.js +2 -16
  143. package/lib/view/spendManagement/chargeCards/chargeCardDetail/fetchChargeCardDetailPageEpic.js +4 -5
  144. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListReducer.d.ts +3 -18
  145. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListReducer.js +10 -27
  146. package/lib/view/spendManagement/chargeCards/chargeCardList/fetchChargeCardListPageEpic.js +6 -9
  147. package/lib/view/spendManagement/chargeCards/chargeCardPaymentHistory/chargeCardPaymentHistory.d.ts +1 -1
  148. package/lib/view/spendManagement/chargeCards/chargeCardPaymentHistory/chargeCardPaymentHistoryReducer.d.ts +1 -3
  149. package/lib/view/spendManagement/chargeCards/chargeCardPaymentHistory/chargeCardPaymentHistoryReducer.js +2 -3
  150. package/lib/view/spendManagement/chargeCards/chargeCardPaymentHistory/fetchChargeCardPaymentPageEpic.js +1 -1
  151. package/lib/view/spendManagement/chargeCards/chargeCardRepaymentDetail/chargeCardRepaymentDetailReducer.d.ts +1 -3
  152. package/lib/view/spendManagement/chargeCards/chargeCardRepaymentDetail/chargeCardRepaymentDetailReducer.js +3 -7
  153. package/lib/view/spendManagement/reimbursement/remiListView/remiListState.d.ts +1 -1
  154. package/lib/view/spendManagement/spendManagementFilterHelpers.d.ts +3 -12
  155. package/lib/view/spendManagement/spendManagementFilterHelpers.js +2 -4
  156. package/lib/view/subscriptionView/subscriptionViewSelector.js +1 -1
  157. package/lib/view/taskManager/taskListView/taskList.d.ts +1 -1
  158. package/lib/view/taskManager/taskListView/taskListReducer.js +1 -1
  159. package/lib/view/transactionDetail/transactionDetailReducer.d.ts +1 -11
  160. package/lib/view/transactionDetail/transactionDetailReducer.js +7 -122
  161. package/lib/view/transactionDetail/transactionDetailSelector.d.ts +0 -2
  162. package/lib/view/transactionDetail/transactionDetailSelector.js +2 -31
  163. package/lib/view/transactionDetail/transactionDetailTypes.d.ts +0 -1
  164. package/lib/view/zeniOAuthView/zeniOAuthSelector.d.ts +1 -1
  165. package/package.json +4 -9
  166. package/lib/commonStateTypes/cacheOverrideFetchReducer.d.ts +0 -17
  167. package/lib/commonStateTypes/cacheOverrideFetchReducer.js +0 -20
  168. package/lib/commonStateTypes/filterPrimitives.d.ts +0 -23
  169. package/lib/commonStateTypes/filterPrimitives.js +0 -21
  170. package/lib/commonStateTypes/pusherActions.d.ts +0 -11
  171. package/lib/commonStateTypes/pusherActions.js +0 -6
  172. package/lib/esm/commonStateTypes/cacheOverrideFetchReducer.js +0 -16
  173. package/lib/esm/commonStateTypes/filterPrimitives.js +0 -20
  174. package/lib/esm/commonStateTypes/pusherActions.js +0 -3
  175. package/lib/esm/view/expenseAutomationView/transactionFilterHelpers.js +0 -258
  176. package/lib/esm/view/expenseAutomationView/types/completedSubTab.js +0 -17
  177. package/lib/esm/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.js +0 -87
  178. package/lib/view/expenseAutomationView/transactionFilterHelpers.d.ts +0 -66
  179. package/lib/view/expenseAutomationView/transactionFilterHelpers.js +0 -262
  180. package/lib/view/expenseAutomationView/types/completedSubTab.d.ts +0 -10
  181. package/lib/view/expenseAutomationView/types/completedSubTab.js +0 -21
  182. package/lib/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.d.ts +0 -9
  183. package/lib/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.js +0 -91
@@ -5,8 +5,7 @@ import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
5
5
  import { updateTransactions } from '../../../../entity/transaction/transactionReducer';
6
6
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
7
7
  import { getLineItemsByTransactionsIdsFromResponse } from '../../helpers/transactionCategorizationLocalDataHelper';
8
- import { fetchTransactionCategorization, fetchTransactionCategorizationFailure, fetchTransactionCategorizationSuccess, initializeTransactionCategorizationViewLocalData, resetOtherTabsFetchState, updateParentTotalCountForTab, updateTotalCountForTransactionCategorization, updateTransactionCategorizationUIState, } from '../../reducers/transactionsViewReducer';
9
- import { DEFAULT_COMPLETED_SUB_TAB } from '../../types/completedSubTab';
8
+ import { fetchTransactionCategorization, fetchTransactionCategorizationFailure, fetchTransactionCategorizationSuccess, initializeTransactionCategorizationViewLocalData, resetOtherTabsFetchState, updateTotalCountForTransactionCategorization, updateTransactionCategorizationUIState, } from '../../reducers/transactionsViewReducer';
10
9
  import { TRANSACTIONS_TABS, toTransactionsSortKey, } from '../../types/transactionsViewState';
11
10
  export const fetchTransactionCategorizationEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchTransactionCategorization.match), switchMap((action) => {
12
11
  const { expenseAutomationViewState: { selectedPeriodByTenantId }, expenseAutomationTransactionsViewState, } = state$.value;
@@ -24,9 +23,6 @@ export const fetchTransactionCategorizationEpic = (actions$, state$, zeniAPI) =>
24
23
  page_token: pageToken,
25
24
  page_size: 25,
26
25
  search_text: uiState.searchString,
27
- sub_tab: selectedTab === 'autoCategorized'
28
- ? expenseAutomationTransactionsViewState.selectedTransactionCategorizationCompletedSubTab
29
- : DEFAULT_COMPLETED_SUB_TAB,
30
26
  };
31
27
  return zeniAPI
32
28
  .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/expense-automation/transactions?query=${encodeURIComponent(JSON.stringify(queryParam))}`)
@@ -49,12 +45,6 @@ export const fetchTransactionCategorizationEpic = (actions$, state$, zeniAPI) =>
49
45
  selectedTab,
50
46
  totalCount: response.data.total_count,
51
47
  }));
52
- updateActions.push(updateParentTotalCountForTab({
53
- selectedPeriod,
54
- selectedTab,
55
- parentTotalCount: response.data.parent_tab_total_count ??
56
- response.data.total_count,
57
- }));
58
48
  updateActions.push(resetOtherTabsFetchState({
59
49
  refreshViewInBackground,
60
50
  tabs: TRANSACTIONS_TABS.filter((tab) => selectedTab !== tab),
@@ -59,22 +59,6 @@ export const filterAutoTabLineItems = (tabView, transactionId, updatedTransactio
59
59
  }
60
60
  };
61
61
  export const MAX_SELECTION_LIMIT = 5;
62
- // Returns true when the transaction should be auto-added to the
63
- // selectedCheckBoxTransactionIds list after a categorization-related
64
- // state mutation: all line items are filled, the selection limit has
65
- // not been hit, and the id isn't already in the list. Consolidates the
66
- // triplet that was inlined at four sites (updateSelectedCustomer/Vendor,
67
- // setAllItemsToCategoryClassInLocalDataForCategorization, and
68
- // setEntityRecommendationForLineIdInLocalData below).
69
- export const shouldAutoSelectAndAdd = (transaction, localData, selectedCheckBoxTransactionIds, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled) => {
70
- if (selectedCheckBoxTransactionIds.includes(transaction.id)) {
71
- return false;
72
- }
73
- if (selectedCheckBoxTransactionIds.length >= MAX_SELECTION_LIMIT) {
74
- return false;
75
- }
76
- return checkIfAllLineItemsAreCategoryClassFilled(transaction, localData, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled);
77
- };
78
62
  export const toTransactionDetailLocalData = (transaction, selectedTab, lineItemsByTransactionIds, uncategorizedIncomeExpense, isUncategorizedExpenseCategoryEnabled) => {
79
63
  const transactionLocal = {
80
64
  ...initialSupportedTransactionCategorization.transactionReviewLocalData,
@@ -560,14 +544,10 @@ export const setEntityRecommendationForLineIdInLocalData = (draft, transaction,
560
544
  selectedEntity: transactionDetailLocalData.selectedEntity,
561
545
  tabSpecificLineItems: transactionDetailLocalData.tabSpecificLineItems,
562
546
  };
563
- // Auto-uncheck if not all line items are filled (the row's
564
- // category/class became stale after the entity update). Otherwise
565
- // route through shouldAutoSelectAndAdd so the MAX_SELECTION_LIMIT
566
- // gate is consistently applied across all auto-add sites.
567
547
  if (!checkIfAllLineItemsAreCategoryClassFilled(transaction, newLocalData, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled)) {
568
548
  selectedCheckBoxTransactionIds = selectedCheckBoxTransactionIds.filter((id) => id !== transaction.id);
569
549
  }
570
- else if (shouldAutoSelectAndAdd(transaction, newLocalData, selectedCheckBoxTransactionIds, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled)) {
550
+ else if (selectedCheckBoxTransactionIds.includes(transaction.id) === false) {
571
551
  selectedCheckBoxTransactionIds.push(transaction.id);
572
552
  }
573
553
  draft.selectedCheckBoxTransactionIds = selectedCheckBoxTransactionIds;
@@ -1,6 +1,5 @@
1
1
  import { createAction, createSlice } from '@reduxjs/toolkit';
2
2
  import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
3
- import { DEFAULT_COMPLETED_SUB_TAB, } from '../types/completedSubTab';
4
3
  import { MIN_MANUAL_TRANSACTION_SEARCH_LENGTH, } from '../types/missingReceiptsViewState';
5
4
  export const getCompletedTransactionsCacheKey = (periodId, sortKey, sortOrder, subTab) => {
6
5
  const sortKeyPart = sortKey ?? 'none';
@@ -14,7 +13,7 @@ export const initialBulkUploadState = {
14
13
  batchListByPeriod: {},
15
14
  batchListFetchState: { fetchState: 'Not-Started', error: undefined },
16
15
  batchStatusById: {},
17
- completedSubTab: DEFAULT_COMPLETED_SUB_TAB,
16
+ completedSubTab: 'all',
18
17
  completedTransactionsByPeriod: {},
19
18
  confirmMatchStatus: { fetchState: 'Not-Started', error: undefined },
20
19
  currentBatchId: undefined,
@@ -3,8 +3,7 @@ import recordGet from 'lodash/get';
3
3
  import uniq from 'lodash/uniq';
4
4
  import { toMonthYearPeriodId, } from '../../../commonStateTypes/timePeriod';
5
5
  import { isVendorTransaction } from '../../../entity/transaction/stateTypes/vendorTransaction';
6
- import { filterAutoTabLineItems, mergeTabSpecificLineItems, removeTransactionFromTabView, setEntityRecommendationForLineIdInLocalData, shouldAutoSelectAndAdd, toSetAllLineItemsToCategoryClass, toTransactionDetailLocalData, } from '../helpers/transactionCategorizationLocalDataHelper';
7
- import { DEFAULT_COMPLETED_SUB_TAB, } from '../types/completedSubTab';
6
+ import { MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, filterAutoTabLineItems, mergeTabSpecificLineItems, removeTransactionFromTabView, setEntityRecommendationForLineIdInLocalData, toSetAllLineItemsToCategoryClass, toTransactionDetailLocalData, } from '../helpers/transactionCategorizationLocalDataHelper';
8
7
  export const initialTransactionTabViewState = {
9
8
  saveStatus: {
10
9
  fetchState: 'Not-Started',
@@ -28,10 +27,6 @@ export const initialTransactionTabViewState = {
28
27
  totalCount: {},
29
28
  limit: 10,
30
29
  },
31
- filters: {
32
- categoryCombinationOperator: 'AND',
33
- categories: [],
34
- },
35
30
  fetchState: 'Not-Started',
36
31
  error: undefined,
37
32
  hasValidState() {
@@ -46,74 +41,12 @@ export const initialTransactionTabViewState = {
46
41
  selectedTransactionLineId: undefined,
47
42
  };
48
43
  export const initialState = {
49
- autoCategorizedSubTabCache: {},
50
- parentTotalCountByTab: {
51
- review: {},
52
- autoCategorized: {},
53
- },
54
44
  selectedTransactionCategorizationTab: 'review',
55
- selectedTransactionCategorizationCompletedSubTab: DEFAULT_COMPLETED_SUB_TAB,
56
45
  transactionCategorizationView: {
57
46
  review: { ...initialTransactionTabViewState },
58
47
  autoCategorized: { ...initialTransactionTabViewState },
59
48
  },
60
49
  };
61
- /**
62
- * Capture the autoCategorized tab's current paginated dataset for a sub-tab.
63
- * The mid-flight `'In-Progress'` state is normalised to `'Completed'` because
64
- * the in-flight request is cancelled by `switchMap` in the fetch epic when the
65
- * sub-tab changes — restoring `'In-Progress'` later would leave the UI stuck
66
- * showing a phantom loading state with no fetch actually running. Length-zero
67
- * datasets degrade to `'Not-Started'` so the next visit triggers a fresh
68
- * fetch from page 1 instead of short-circuiting on stale empty caches.
69
- *
70
- * Snapshot scope (deliberately narrow):
71
- * - Captured: `pageToken`, `totalCount`, `transactionIdsBySelectedPeriod`,
72
- * `fetchState`, `error`, `scrollPosition`. The first five are the keys the
73
- * fetch epic's cache check reads to decide whether to short-circuit a
74
- * sub-tab revisit; `scrollPosition` is captured per sub-tab so revisiting
75
- * restores the user's last offset and switching to a never-visited sub-tab
76
- * starts at the top instead of inheriting the outgoing sub-tab's offset
77
- * (which would land the user at a meaningless row index against a
78
- * completely different list).
79
- * - Intentionally NOT captured (left in place on `autoCat` and inherited by
80
- * the incoming sub-tab):
81
- * - `uiState.searchString`, `uiState.sortKey`, `uiState.sortOrder`,
82
- * `uiState.nodeCollapseState`, `uiState.limit` — search and sort are
83
- * user-applied preferences that persist across sub-tabs by design (a
84
- * search query stays active when the user toggles between Manual / AI
85
- * Accountant).
86
- * - `selectedCheckBoxTransactionIds` — selection state is intentionally
87
- * cleared at the action source (the fetch epic / save flow), not
88
- * by the snapshot path. Carrying selection across sub-tabs is safe
89
- * because every sub-tab change goes through a fetch round-trip that
90
- * reconciles selection against the new row IDs.
91
- * - `transactionReviewLocalDataById`, `transactionIdsWithUnsavedData`,
92
- * `uploadReceiptStatusById`, `saveStatus`, `refreshStatus`,
93
- * `markAsNotMiscategorizedStatus` — these are per-row / per-flight
94
- * caches that are write-through global state, not sub-tab-scoped.
95
- *
96
- * If the contract changes (e.g. selection should reset on every sub-tab
97
- * switch), update both this comment and the snapshot return shape together.
98
- */
99
- function snapshotAutoCategorizedTab(autoCat) {
100
- const transactionIdsBySelectedPeriod = {
101
- ...autoCat.transactionIdsBySelectedPeriod,
102
- };
103
- const hasAnyLoadedRows = Object.values(transactionIdsBySelectedPeriod).some((ids) => ids.length > 0);
104
- let normalisedFetchState = autoCat.fetchState;
105
- if (normalisedFetchState === 'In-Progress') {
106
- normalisedFetchState = hasAnyLoadedRows ? 'Completed' : 'Not-Started';
107
- }
108
- return {
109
- error: autoCat.error,
110
- fetchState: normalisedFetchState,
111
- pageToken: autoCat.uiState.pageToken,
112
- scrollPosition: autoCat.uiState.scrollPosition,
113
- totalCount: { ...autoCat.uiState.totalCount },
114
- transactionIdsBySelectedPeriod,
115
- };
116
- }
117
50
  const expenseAutomationTransactionsView = createSlice({
118
51
  name: 'expenseAutomationTransactionsView',
119
52
  initialState,
@@ -303,12 +236,6 @@ const expenseAutomationTransactionsView = createSlice({
303
236
  uiState.totalCount;
304
237
  }
305
238
  },
306
- updateTransactionFilters(draft, action) {
307
- const { selectedTab, filters } = action.payload;
308
- // `filters` is non-nullable per the payload type, so no runtime
309
- // null-check is needed — dropping it removes a dead defensive branch.
310
- draft.transactionCategorizationView[selectedTab].filters = filters;
311
- },
312
239
  saveTransactionCategorization: {
313
240
  prepare(selectedTab, transactionIds, cotTrackingByTransactionId, isUncategorizedExpenseCategoryEnabled) {
314
241
  return {
@@ -333,55 +260,6 @@ const expenseAutomationTransactionsView = createSlice({
333
260
  return { payload: { newSelectedTab } };
334
261
  },
335
262
  },
336
- updateTransactionCategorizationCompletedSubTab: {
337
- reducer(draft, action) {
338
- const { newSubTab } = action.payload;
339
- const previousSubTab = draft.selectedTransactionCategorizationCompletedSubTab;
340
- if (previousSubTab === newSubTab) {
341
- return;
342
- }
343
- const autoCat = draft.transactionCategorizationView.autoCategorized;
344
- // Snapshot the outgoing sub-tab so a future revisit can short-circuit
345
- // the fetch epic (mirrors the parent-tab "don't refetch what's
346
- // already cached" behaviour). Period-scoped data is preserved as-is
347
- // because the snapshot itself is keyed only by sub-tab; the active
348
- // tab's per-period maps remain the source of truth while live.
349
- draft.autoCategorizedSubTabCache[previousSubTab] =
350
- snapshotAutoCategorizedTab(autoCat);
351
- const cached = draft.autoCategorizedSubTabCache[newSubTab];
352
- if (cached != null) {
353
- autoCat.uiState.pageToken = cached.pageToken;
354
- autoCat.uiState.totalCount = { ...cached.totalCount };
355
- autoCat.uiState.scrollPosition = cached.scrollPosition;
356
- autoCat.transactionIdsBySelectedPeriod = {
357
- ...cached.transactionIdsBySelectedPeriod,
358
- };
359
- autoCat.fetchState = cached.fetchState;
360
- autoCat.error = cached.error;
361
- }
362
- else {
363
- // Sub-tab has never been visited — clear the active slot so the
364
- // view-epic's `fetchState === 'Not-Started' || transactionIds.length
365
- // === 0` cache check falls through and triggers a fresh page-1
366
- // fetch for the new dataset. `scrollPosition` is reset to the top
367
- // so the incoming list isn't anchored to the outgoing sub-tab's
368
- // offset (different rows → previous offset is meaningless).
369
- autoCat.uiState.pageToken = null;
370
- autoCat.uiState.totalCount = {};
371
- autoCat.uiState.scrollPosition = {
372
- scrollTop: 0,
373
- scrollLeft: undefined,
374
- };
375
- autoCat.transactionIdsBySelectedPeriod = {};
376
- autoCat.fetchState = 'Not-Started';
377
- autoCat.error = undefined;
378
- }
379
- draft.selectedTransactionCategorizationCompletedSubTab = newSubTab;
380
- },
381
- prepare(newSubTab) {
382
- return { payload: { newSubTab } };
383
- },
384
- },
385
263
  updateTransactionCategorization: {
386
264
  reducer(draft, action) {
387
265
  const selectedTab = action.payload.selectedTab;
@@ -430,9 +308,12 @@ const expenseAutomationTransactionsView = createSlice({
430
308
  const selectedCheckBoxTransactionIds = draft.transactionCategorizationView[selectedTab]
431
309
  .selectedCheckBoxTransactionIds;
432
310
  if (selectedTransaction != null &&
433
- shouldAutoSelectAndAdd(selectedTransaction, newTransactionLocalData, selectedCheckBoxTransactionIds, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled)) {
311
+ checkIfAllLineItemsAreCategoryClassFilled(selectedTransaction, newTransactionLocalData, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled) === true && // check if all line items are filled
312
+ selectedCheckBoxTransactionIds.length < MAX_SELECTION_LIMIT &&
313
+ selectedCheckBoxTransactionIds.includes(transactionId) === false) {
434
314
  draft.transactionCategorizationView[selectedTab].selectedCheckBoxTransactionIds = [
435
- ...selectedCheckBoxTransactionIds,
315
+ ...draft.transactionCategorizationView[selectedTab]
316
+ .selectedCheckBoxTransactionIds,
436
317
  transactionId,
437
318
  ];
438
319
  }
@@ -515,26 +396,9 @@ const expenseAutomationTransactionsView = createSlice({
515
396
  const transactionLocalData = recordGet(draft.transactionCategorizationView[selectedTab]
516
397
  .transactionReviewLocalDataById, transactionId.id, undefined);
517
398
  if (transactionLocalData != null) {
518
- const newLocalData = setEntityRecommendationForLineIdInLocalData(draft.transactionCategorizationView[selectedTab], transaction, transactionLocalData.transactionReviewLocalData, entity, lineIds, uncategorizedAccounts, action.payload.recommendationWithCOTByLineId, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled);
519
- // Release the per-line fetch flag for every line this fetch
520
- // covered. Done in-place on the freshly returned local data
521
- // (the helper produces a new mutable object), before we write
522
- // it back to the draft.
523
- lineIds.forEach((lineId) => {
524
- const lineItem = newLocalData.lineItemById[lineId];
525
- if (lineItem != null) {
526
- newLocalData.lineItemById[lineId] = {
527
- ...lineItem,
528
- categoryClassRecommendationsFetchState: {
529
- fetchState: 'Completed',
530
- error: undefined,
531
- },
532
- };
533
- }
534
- });
535
399
  draft.transactionCategorizationView[selectedTab].transactionReviewLocalDataById[transaction.id] = {
536
400
  transactionId: transaction.id,
537
- transactionReviewLocalData: newLocalData,
401
+ transactionReviewLocalData: setEntityRecommendationForLineIdInLocalData(draft.transactionCategorizationView[selectedTab], transaction, transactionLocalData.transactionReviewLocalData, entity, lineIds, uncategorizedAccounts, action.payload.recommendationWithCOTByLineId, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled),
538
402
  };
539
403
  // Mark transaction as dirty (autofill happened)
540
404
  if (!draft.transactionCategorizationView[selectedTab].transactionIdsWithUnsavedData.includes(transaction.id)) {
@@ -547,99 +411,6 @@ const expenseAutomationTransactionsView = createSlice({
547
411
  }
548
412
  },
549
413
  },
550
- // Start arm of the line-update recommendations fetch. Flips covered
551
- // lines to In-Progress AND removes the transaction from
552
- // selectedCheckBoxTransactionIds — the row is unchecked + disabled
553
- // until either the success arm (recheck if limit allows) or the
554
- // failure arm releases the per-line flag.
555
- markCategoryClassRecommendationsInProgressForCategorization: {
556
- reducer(draft, action) {
557
- const { selectedTab, transactionId, lineIds } = action.payload;
558
- const tab = draft.transactionCategorizationView[selectedTab];
559
- const transactionLocalData = recordGet(tab.transactionReviewLocalDataById, transactionId.id, undefined);
560
- if (transactionLocalData != null) {
561
- lineIds.forEach((lineId) => {
562
- const lineItem = transactionLocalData.transactionReviewLocalData.lineItemById[lineId];
563
- if (lineItem != null) {
564
- transactionLocalData.transactionReviewLocalData.lineItemById[lineId] = {
565
- ...lineItem,
566
- categoryClassRecommendationsFetchState: {
567
- fetchState: 'In-Progress',
568
- error: undefined,
569
- },
570
- };
571
- }
572
- });
573
- }
574
- // Uncheck on fetch start: the row's existing category/class are
575
- // stale after a payee change, so we drop the auto-selection until
576
- // fresh recommendations land.
577
- if (tab.selectedCheckBoxTransactionIds.includes(transactionId.id)) {
578
- tab.selectedCheckBoxTransactionIds =
579
- tab.selectedCheckBoxTransactionIds.filter((id) => id !== transactionId.id);
580
- }
581
- },
582
- prepare(selectedTab, transactionId, lineIds) {
583
- return { payload: { selectedTab, transactionId, lineIds } };
584
- },
585
- },
586
- // Completed arm. Used by the epic when the HTTP call succeeds but the
587
- // server returned no per-line recommendations — we still need to
588
- // release the In-Progress flag so the skeleton resolves. Successful
589
- // responses with recommendations go through
590
- // setEntityRecommendationForLineIdsForCategorization instead (which
591
- // also flips the lines to Completed).
592
- markCategoryClassRecommendationsCompletedForCategorization: {
593
- reducer(draft, action) {
594
- const { selectedTab, transactionId, lineIds } = action.payload;
595
- const transactionLocalData = recordGet(draft.transactionCategorizationView[selectedTab]
596
- .transactionReviewLocalDataById, transactionId.id, undefined);
597
- if (transactionLocalData != null) {
598
- lineIds.forEach((lineId) => {
599
- const lineItem = transactionLocalData.transactionReviewLocalData.lineItemById[lineId];
600
- if (lineItem != null) {
601
- transactionLocalData.transactionReviewLocalData.lineItemById[lineId] = {
602
- ...lineItem,
603
- categoryClassRecommendationsFetchState: {
604
- fetchState: 'Completed',
605
- error: undefined,
606
- },
607
- };
608
- }
609
- });
610
- }
611
- },
612
- prepare(selectedTab, transactionId, lineIds) {
613
- return { payload: { selectedTab, transactionId, lineIds } };
614
- },
615
- },
616
- // Failure arm. Flips covered lines to Error so the skeleton resolves
617
- // and downstream UI can react to the failure. The transaction stays
618
- // unchecked from the start-arm action.
619
- markCategoryClassRecommendationsFailureForCategorization: {
620
- reducer(draft, action) {
621
- const { selectedTab, transactionId, lineIds, error } = action.payload;
622
- const transactionLocalData = recordGet(draft.transactionCategorizationView[selectedTab]
623
- .transactionReviewLocalDataById, transactionId.id, undefined);
624
- if (transactionLocalData != null) {
625
- lineIds.forEach((lineId) => {
626
- const lineItem = transactionLocalData.transactionReviewLocalData.lineItemById[lineId];
627
- if (lineItem != null) {
628
- transactionLocalData.transactionReviewLocalData.lineItemById[lineId] = {
629
- ...lineItem,
630
- categoryClassRecommendationsFetchState: {
631
- fetchState: 'Error',
632
- error,
633
- },
634
- };
635
- }
636
- });
637
- }
638
- },
639
- prepare(selectedTab, transactionId, lineIds, error) {
640
- return { payload: { selectedTab, transactionId, lineIds, error } };
641
- },
642
- },
643
414
  fetchTransactionCategorizationSuccess(draft, action) {
644
415
  const { selectedTab, refreshViewInBackground } = action.payload;
645
416
  if (draft.transactionCategorizationView[selectedTab].fetchState ===
@@ -735,7 +506,9 @@ const expenseAutomationTransactionsView = createSlice({
735
506
  .selectedCheckBoxTransactionIds;
736
507
  if (newTransactionLocalData.customer != null &&
737
508
  newTransactionLocalData.customer.id != null &&
738
- shouldAutoSelectAndAdd(selectedTransaction, newTransactionLocalData, selectedCheckBoxTransactionIds, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled)) {
509
+ checkIfAllLineItemsAreCategoryClassFilled(selectedTransaction, newTransactionLocalData, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled) === true && // check if all line items are filled
510
+ selectedCheckBoxTransactionIds.length < MAX_SELECTION_LIMIT &&
511
+ selectedCheckBoxTransactionIds.includes(transactionId) === false) {
739
512
  draft.transactionCategorizationView[selectedTab].selectedCheckBoxTransactionIds = [
740
513
  ...selectedCheckBoxTransactionIds,
741
514
  transactionId,
@@ -809,7 +582,9 @@ const expenseAutomationTransactionsView = createSlice({
809
582
  .selectedCheckBoxTransactionIds;
810
583
  if (newTransactionLocalData.vendor != null &&
811
584
  newTransactionLocalData.vendor.id != null &&
812
- shouldAutoSelectAndAdd(selectedTransaction, newTransactionLocalData, selectedCheckBoxTransactionIds, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled)) {
585
+ checkIfAllLineItemsAreCategoryClassFilled(selectedTransaction, newTransactionLocalData, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled) === true && // check if all line items are filled
586
+ selectedCheckBoxTransactionIds.length < MAX_SELECTION_LIMIT &&
587
+ selectedCheckBoxTransactionIds.includes(transactionId) === false) {
813
588
  draft.transactionCategorizationView[selectedTab].selectedCheckBoxTransactionIds = [
814
589
  ...selectedCheckBoxTransactionIds,
815
590
  transactionId,
@@ -922,10 +697,6 @@ const expenseAutomationTransactionsView = createSlice({
922
697
  const { selectedTab, selectedPeriod, totalCount } = action.payload;
923
698
  draft.transactionCategorizationView[selectedTab].uiState.totalCount[toMonthYearPeriodId(selectedPeriod)] = totalCount;
924
699
  },
925
- updateParentTotalCountForTab(draft, action) {
926
- const { selectedTab, selectedPeriod, parentTotalCount } = action.payload;
927
- draft.parentTotalCountByTab[selectedTab][toMonthYearPeriodId(selectedPeriod)] = parentTotalCount;
928
- },
929
700
  updateSelectedCheckboxTransactionIds(draft, action) {
930
701
  const selectedTab = action.payload.selectedTab;
931
702
  const transactionIds = action.payload.transactionIds;
@@ -936,16 +707,6 @@ const expenseAutomationTransactionsView = createSlice({
936
707
  draft.transactionCategorizationView[selectedTab] = {
937
708
  ...initialTransactionTabViewState,
938
709
  };
939
- draft.parentTotalCountByTab[selectedTab] = {};
940
- // The per-sub-tab snapshot cache lives at the slice root and is
941
- // exclusively populated by the autoCategorized tab's sub-tab switching
942
- // (see updateTransactionCategorizationCompletedSubTab). When that tab
943
- // is reset, leaving stale snapshots behind would short-circuit the
944
- // next sub-tab visit with phantom row IDs / page tokens that no longer
945
- // correspond to anything in state — drop them in lockstep.
946
- if (selectedTab === 'autoCategorized') {
947
- draft.autoCategorizedSubTabCache = {};
948
- }
949
710
  },
950
711
  clearExpenseAutomationTransactionsView(draft) {
951
712
  Object.assign(draft, initialState);
@@ -1042,5 +803,5 @@ const expenseAutomationTransactionsView = createSlice({
1042
803
  },
1043
804
  },
1044
805
  });
1045
- 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, updateTransactionCategorizationUploadReceiptState, uploadTransactionCategorizationReceiptSuccess, } = expenseAutomationTransactionsView.actions;
806
+ export const { fetchTransactionCategorization, updateTransactionCategorizationUIState, initializeTransactionCategorizationViewLocalData, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateCurrentSelectedTransactionCategorizationTab, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateStatusForTransactionNotMiscategorizedUpdateForCategorization, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, setAllItemsToCategoryClassInLocalDataForCategorization, updateTotalCountForTransactionCategorization, fetchTransactionCategorizationSuccess, resetOtherTabsFetchState, fetchTransactionCategorizationView, updateSelectedCheckboxTransactionIds, clearExpenseAutomationTransactionsViewPerTabView, clearExpenseAutomationTransactionsView, setEntityRecommendationForLineIdsForCategorization, updateSelectedTransactionId, syncTransactionCategorizationFromDetailSave, backgroundRefetchReviewTab, updateTransactionCategorizationUploadReceiptState, uploadTransactionCategorizationReceiptSuccess, } = expenseAutomationTransactionsView.actions;
1046
807
  export default expenseAutomationTransactionsView.reducer;