@zeniai/client-epic-state 4.19.39 → 4.19.40-betaML1

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 (27) hide show
  1. package/lib/esm/index.js +2 -2
  2. package/lib/esm/view/commonVendorView/transactionVendorView/epics/saveTransactionVendorEpic.js +1 -0
  3. package/lib/esm/view/commonVendorView/transactionVendorView/transactionVendorViewReducer.js +2 -1
  4. package/lib/esm/view/expenseAutomationView/epics/accountRecon/uploadAccountStatementDocumentAIHelper.js +5 -3
  5. package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +27 -0
  6. package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +65 -2
  7. package/lib/esm/view/transactionDetail/epics/saveTransactionDetailEpic.js +2 -2
  8. package/lib/esm/view/transactionDetail/epics/updateTransactionDetailEpic.js +11 -2
  9. package/lib/esm/view/transactionDetail/transactionDetailReducer.js +2 -1
  10. package/lib/index.d.ts +2 -2
  11. package/lib/index.js +30 -29
  12. package/lib/tsconfig.typecheck.tsbuildinfo +1 -1
  13. package/lib/view/commonVendorView/transactionVendorView/epics/saveTransactionVendorEpic.js +1 -0
  14. package/lib/view/commonVendorView/transactionVendorView/transactionVendorViewReducer.d.ts +2 -1
  15. package/lib/view/commonVendorView/transactionVendorView/transactionVendorViewReducer.js +2 -1
  16. package/lib/view/expenseAutomationView/epics/accountRecon/uploadAccountStatementDocumentAIHelper.d.ts +2 -1
  17. package/lib/view/expenseAutomationView/epics/accountRecon/uploadAccountStatementDocumentAIHelper.js +5 -3
  18. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +10 -0
  19. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +30 -1
  20. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +7 -1
  21. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +65 -2
  22. package/lib/view/transactionDetail/epics/saveTransactionDetailEpic.js +2 -2
  23. package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.d.ts +3 -2
  24. package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.js +10 -1
  25. package/lib/view/transactionDetail/transactionDetailReducer.d.ts +3 -1
  26. package/lib/view/transactionDetail/transactionDetailReducer.js +2 -1
  27. package/package.json +1 -1
package/lib/esm/index.js CHANGED
@@ -163,7 +163,7 @@ import { clearExpenseAutomationFluxAnalysisView, fetchFluxAnalysisView, reviewFl
163
163
  import { clearJeScheduleLocalData as clearExpenseAutomationJEScheduleLocalData, clearExpenseAutomationJESchedulesView, fetchJeSchedulesPage as fetchExpenseAutomationJESchedulesPage, ignoreRecommendedJeSchedule as ignoreExpenseAutomationJESchedule, initializeAccountSettingsView as initializeJeAccountSettingsView, initializeJeScheduleLocalData, removeJeScheduleTransactionKey, retryJeSchedule as retryExpenseAutomationJESchedule, saveAccountSettings as saveJeAccountSettings, saveAccountSettingsLocalData as saveJeAccountSettingsLocalData, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys, } from './view/expenseAutomationView/reducers/jeSchedulesViewReducer';
164
164
  import { fetchMissingReceipts as fetchExpenseAutomationMissingReceipts, markMissingReceiptAsDone as markExpenseAutomationMissingReceiptAsDone, updateMissingReceiptUploadState as updateExpenseAutomationMissingReceiptUploadState, updateMissingReceiptsUIState as updateExpenseAutomationMissingReceiptsUIState, uploadMissingReceiptSuccess as uploadExpenseAutomationMissingReceiptSuccess, } from './view/expenseAutomationView/reducers/missingReceiptsViewReducer';
165
165
  import { deleteAccountStatement, fetchReconciliation as fetchReconciliationView, saveReconciliationDetail as saveExpenseAutomationReconciliationDetail, saveReconciliationReview as saveExpenseAutomationReconciliationReview, setConnectionInProgressForAccount as setConnectionInProgressForAccountReconciliation, setStatementParseInProgress, updateAccountReconciliationLocalData as updateExpenseAutomationAccountReconciliationLocalData, updateSelectedAccountId as updateExpenseAutomationAccountReconciliationSelectedAccountId, updateSelectedTab as updateExpenseAutomationAccountReconciliationSelectedTab, updateReconListScrollPosition as updateExpenseAutomationReconListScrollPosition, updateReviewTabSortState as updateExpenseAutomationReconReviewTabListSortState, updateReviewTabLocalData as updateExpenseAutomationReconReviewTabLocalData, updateReconcileTabListScrollState as updateExpenseAutomationReconcileTabListScrollState, updateReconcileTabListSortState as updateExpenseAutomationReconcileTabListSortState, updateReconcileTabLocalData as updateExpenseAutomationReconcileTabLocalData, updateSelectedDrawerAccountId as updateExpenseAutomationSelectedDrawerAccountId, updateStatementUploadChosen, uploadAccountStatement, } from './view/expenseAutomationView/reducers/reconciliationViewReducer';
166
- import { clearExpenseAutomationTransactionsView, fetchTransactionCategorization, fetchTransactionCategorizationFailure, fetchTransactionCategorizationView, initializeTransactionCategorizationViewLocalData, markTransactionAsNotMiscategorized, saveTransactionCategorization, saveTransactionCategorizationLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, setEntityRecommendationForLineIdsForCategorization, updateCurrentSelectedTransactionCategorizationTab, updateSelectedCheckboxTransactionIds, updateSelectedCustomerForTransaction, updateSelectedTransactionId, updateSelectedVendorForTransaction, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, updateTransactionCategorizationUIState, } from './view/expenseAutomationView/reducers/transactionsViewReducer';
166
+ import { clearExpenseAutomationTransactionsView, fetchTransactionCategorization, fetchTransactionCategorizationFailure, fetchTransactionCategorizationView, initializeTransactionCategorizationViewLocalData, markTransactionAsNotMiscategorized, saveTransactionCategorization, saveTransactionCategorizationLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, setEntityRecommendationForLineIdsForCategorization, syncTransactionCategorizationFromDetailSave, updateCurrentSelectedTransactionCategorizationTab, updateSelectedCheckboxTransactionIds, updateSelectedCustomerForTransaction, updateSelectedTransactionId, updateSelectedVendorForTransaction, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, updateTransactionCategorizationUIState, } from './view/expenseAutomationView/reducers/transactionsViewReducer';
167
167
  import { getExpenseAutomationFluxAnalysisView } from './view/expenseAutomationView/selectors/fluxAnalysisViewSelector';
168
168
  import { getExpenseAutomationReconciliationView, isAccountReconReport, } from './view/expenseAutomationView/selectors/reconciliationViewSelector';
169
169
  import { getExpenseAutomationTransactionView } from './view/expenseAutomationView/selectors/transactionCategorizationSelector';
@@ -408,7 +408,7 @@ export { toCOABalanceTypeStrict, toCOABalanceType as toCOABlanaceType, isCalcula
408
408
  export { stringToUnion, stringToUnionStrict };
409
409
  export { fetchMonthEndCloseChecks, fetchMonthClosePerformanceTrend, getMonthEndCloseChecksViewByTenantId, ALL_MONTH_END_CLOSE_CHECKS_FREQUENCY, };
410
410
  export { getExpenseAutomationView, toExpenseAutomationMissingReceiptsSortKey, toExpenseAutomationTransactionsTabKey, toExpenseAutomationViewType, uploadExpenseAutomationMissingReceiptSuccess, markExpenseAutomationMissingReceiptAsDone, fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedTransactionCategorizationTab, fetchExpenseAutomationMissingReceipts, fetchFluxAnalysisView, clearExpenseAutomationFluxAnalysisView, updateOperatingExpensesIdsForReview as updateFluxOperatingExpensesIdsForReview, updateSelectedSectionIdsForReview as updateFluxAnalysisSelectedSectionIdsForReview, reviewFluxAnalysisView, updateExpenseAutomationMissingReceiptUploadState, updateExpenseAutomationMissingReceiptsUIState, getExpenseAutomationFluxAnalysisView, updateCurrentSelectedView, updateCurrentSelectedPeriod, getExpenseAutomationTransactionView, updateFluxAnalysisViewUIState, updateFluxAnalysisViewPageMetaData, MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, getLineItemsByTransactionIdsFromLocalData, isAnyItemWithUncategorizedExpenseAccount, saveExpenseAutomationReconciliationDetail, updateExpenseAutomationReconcileTabListScrollState, updateExpenseAutomationReconReviewTabListSortState, updateExpenseAutomationReconcileTabListSortState, updateExpenseAutomationReconcileTabLocalData, updateExpenseAutomationAccountReconciliationSelectedTab, updateExpenseAutomationAccountReconciliationSelectedAccountId, getExpenseAutomationReconciliationView, fetchReconciliationView, uploadAccountStatementIntoDocumentAI, updateExpenseAutomationReconListScrollPosition, setConnectionInProgressForAccountReconciliation, getAccountReconByAccountIdAndSelectedPeriod, toReconciliationTabsType, isAccountReconReport, updateExpenseAutomationReconReviewTabLocalData, updateExpenseAutomationSelectedDrawerAccountId, saveExpenseAutomationReconciliationReview, updateExpenseAutomationAccountReconciliationLocalData, toReconciliationAccountSource, deleteAccountStatement, uploadAccountStatement, updateStatementUploadChosen, isReviewTransactionBankTransferType, isReviewTransactionBillPaymentType, isReviewTransactionCreditCardPaymentType, isReviewTransactionDepositType, isReviewTransactionExpenseType, isReviewTransactionCreditCardCreditType, setStatementParseInProgress, };
411
- export { fetchTransactionCategorization, fetchTransactionCategorizationView, updateTransactionCategorizationUIState, updateSelectedCheckboxTransactionIds, setEntityRecommendationForLineIdsForCategorization, initializeTransactionCategorizationViewLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, updateSelectedTransactionId, clearExpenseAutomationTransactionsView, toTransactionsSortKey, };
411
+ export { fetchTransactionCategorization, fetchTransactionCategorizationView, updateTransactionCategorizationUIState, updateSelectedCheckboxTransactionIds, setEntityRecommendationForLineIdsForCategorization, initializeTransactionCategorizationViewLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, updateSelectedTransactionId, syncTransactionCategorizationFromDetailSave, clearExpenseAutomationTransactionsView, toTransactionsSortKey, };
412
412
  export { TOP_EX_TIME_PERIODS };
413
413
  export { toTimeframeTick, mapTimePeriodtoTimeframeTick, toTimePeriod, toAbsoluteDay, toMonthYearPeriodId, convertToPeriod, };
414
414
  export { toVendorSpendTrendFilterTabsTypeStrict, } from './entity/vendorExpense/vendorExpenseSelector';
@@ -105,6 +105,7 @@ export const saveTransactionVendorEpic = (actions$, state$, zeniAPI) => actions$
105
105
  transactionId: action.payload.transactionId,
106
106
  isExpenseAutomationEnabled: action.payload.isExpenseAutomationEnabled,
107
107
  cotTransactionTracking: [], // We don't need to pass COT tracking for vendor save
108
+ isUncategorizedExpenseCategoryEnabled: action.payload.isUncategorizedExpenseCategoryEnabled,
108
109
  }));
109
110
  }
110
111
  return from(actions);
@@ -44,13 +44,14 @@ const transactionVendorView = createSlice({
44
44
  draft.newVendorState.saveStatus.error = undefined;
45
45
  }
46
46
  },
47
- prepare(transactionId, vendorId, saveTransaction, isExpenseAutomationEnabled = false) {
47
+ prepare(transactionId, vendorId, saveTransaction, isExpenseAutomationEnabled = false, isUncategorizedExpenseCategoryEnabled) {
48
48
  return {
49
49
  payload: {
50
50
  vendorId,
51
51
  transactionId,
52
52
  saveTransaction,
53
53
  isExpenseAutomationEnabled,
54
+ isUncategorizedExpenseCategoryEnabled,
54
55
  },
55
56
  };
56
57
  },
@@ -1,12 +1,14 @@
1
1
  import fetch from 'cross-fetch';
2
2
  import { zeniAPI } from '../../../../init';
3
- export default async function uploadAccountStatementIntoDocumentAI(fileBlob, authParams) {
3
+ export default async function uploadAccountStatementIntoDocumentAI(accountType, fileBlob, authParams) {
4
4
  let statementUpload;
5
- const urlEndPoint = `${zeniAPI.apiEndPoints.documentAIMicroServiceBaseUrl}/1.0/processors/bank-statement`;
5
+ const urlEndPoint = `${zeniAPI.apiEndPoints.documentAIMicroServiceBaseUrl}/1.0/processors/statement`;
6
6
  const data = new FormData();
7
7
  data.append('attachment_file_0', fileBlob);
8
8
  const attachment_json = JSON.stringify({
9
- document_type: 'reconciliation_bank_statement_upload',
9
+ document_type: accountType === 'credit_card'
10
+ ? 'reconciliation_card_statement_upload'
11
+ : 'reconciliation_bank_statement_upload',
10
12
  purpose_id: 'reconciliation',
11
13
  });
12
14
  data.append('attachment_json_0', attachment_json);
@@ -3,6 +3,33 @@ import { isEntityMatching, mergeTransactionAndEntityRecommendationsWithCOT, toLi
3
3
  import { isAccountUncategorized } from '../../transactionDetail/transactionDetailLocalDataHelper';
4
4
  import { initialSupportedTransactionCategorization, } from '../types/transactionsViewState';
5
5
  import { TRANSACTION_CATEGORIZED_COUNT_VARIABLE_NAME, TRANSACTION_COUNT_VARIABLE_NAME, TRANSACTION_FAILED_COUNT_VARIABLE_NAME, TRANSACTION_UPDATED_COUNT_VARIABLE_NAME, } from './helpers';
6
+ /**
7
+ * Extracts line IDs with `pending_review` categorization status from a transaction,
8
+ * preserving the transaction's original line order.
9
+ */
10
+ export const getPendingReviewLineIdsFromTransaction = (transaction) => {
11
+ if (transaction.lines == null) {
12
+ return [];
13
+ }
14
+ return transaction.lines
15
+ .filter((line) => line.categorizationStatus === 'pending_review')
16
+ .map((line) => line.id);
17
+ };
18
+ /**
19
+ * Removes a transaction from a tab view's local data and membership lists.
20
+ * Intended for use within Immer reducer drafts (mutates in place).
21
+ */
22
+ export const removeTransactionFromTabView = (tabView, transactionId) => {
23
+ delete tabView.transactionReviewLocalDataById[transactionId];
24
+ for (const periodId of Object.keys(tabView.transactionIdsBySelectedPeriod)) {
25
+ tabView.transactionIdsBySelectedPeriod[periodId] =
26
+ tabView.transactionIdsBySelectedPeriod[periodId].filter((id) => id !== transactionId);
27
+ }
28
+ tabView.selectedCheckBoxTransactionIds =
29
+ tabView.selectedCheckBoxTransactionIds.filter((id) => id !== transactionId);
30
+ tabView.transactionIdsWithUnsavedData =
31
+ tabView.transactionIdsWithUnsavedData.filter((id) => id !== transactionId);
32
+ };
6
33
  export const MAX_SELECTION_LIMIT = 5;
7
34
  export const toTransactionDetailLocalData = (transaction, selectedTab, lineItemsByTransactionIds, uncategorizedIncomeExpense, isUncategorizedExpenseCategoryEnabled) => {
8
35
  const transactionLocal = {
@@ -3,7 +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 { MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, mergeTabSpecificLineItems, setEntityRecommendationForLineIdInLocalData, toSetAllLineItemsToCategoryClass, } from '../helpers/transactionCategorizationLocalDataHelper';
6
+ import { MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, mergeTabSpecificLineItems, removeTransactionFromTabView, setEntityRecommendationForLineIdInLocalData, toSetAllLineItemsToCategoryClass, toTransactionDetailLocalData, } from '../helpers/transactionCategorizationLocalDataHelper';
7
7
  export const initialTransactionTabViewState = {
8
8
  saveStatus: {
9
9
  fetchState: 'Not-Started',
@@ -699,7 +699,70 @@ const expenseAutomationTransactionsView = createSlice({
699
699
  clearExpenseAutomationTransactionsView(draft) {
700
700
  Object.assign(draft, initialState);
701
701
  },
702
+ syncTransactionCategorizationFromDetailSave: {
703
+ prepare(transactionId, updatedTransaction, pendingReviewLineIds, uncategorizedIncomeExpense, isUncategorizedExpenseCategoryEnabled) {
704
+ return {
705
+ payload: {
706
+ transactionId,
707
+ updatedTransaction,
708
+ pendingReviewLineIds,
709
+ uncategorizedIncomeExpense,
710
+ isUncategorizedExpenseCategoryEnabled,
711
+ },
712
+ };
713
+ },
714
+ reducer(draft, action) {
715
+ const { transactionId, updatedTransaction, pendingReviewLineIds, uncategorizedIncomeExpense, isUncategorizedExpenseCategoryEnabled, } = action.payload;
716
+ const txnId = transactionId.id;
717
+ const reviewTabView = draft.transactionCategorizationView.review;
718
+ const autoTabView = draft.transactionCategorizationView.autoCategorized;
719
+ const existsInReview = reviewTabView.transactionReviewLocalDataById[txnId] != null;
720
+ const existsInAuto = autoTabView.transactionReviewLocalDataById[txnId] != null;
721
+ if (!existsInReview && !existsInAuto) {
722
+ return;
723
+ }
724
+ const allReviewed = pendingReviewLineIds.length === 0;
725
+ if (allReviewed) {
726
+ if (existsInReview) {
727
+ removeTransactionFromTabView(reviewTabView, txnId);
728
+ }
729
+ if (existsInAuto) {
730
+ removeTransactionFromTabView(autoTabView, txnId);
731
+ }
732
+ return;
733
+ }
734
+ // Partially reviewed — auto-only: remove transaction from auto tab entirely
735
+ // since pending_review lines don't belong in auto tab and review_complete lines are done
736
+ const isAutoOnly = existsInAuto && !existsInReview;
737
+ if (isAutoOnly) {
738
+ removeTransactionFromTabView(autoTabView, txnId);
739
+ return;
740
+ }
741
+ // Review-only or both-tabs: rebuild review tab local data with pending review lines
742
+ if (existsInReview) {
743
+ const newLocalData = toTransactionDetailLocalData(updatedTransaction, 'review', pendingReviewLineIds, uncategorizedIncomeExpense, isUncategorizedExpenseCategoryEnabled);
744
+ reviewTabView.transactionReviewLocalDataById[txnId] = {
745
+ transactionId: txnId,
746
+ transactionReviewLocalData: {
747
+ ...newLocalData,
748
+ sortedLineItems: updatedTransaction.lines?.map((l) => l.id) ?? [],
749
+ tabSpecificLineItems: {
750
+ review: pendingReviewLineIds,
751
+ },
752
+ },
753
+ };
754
+ reviewTabView.selectedCheckBoxTransactionIds =
755
+ reviewTabView.selectedCheckBoxTransactionIds.filter((id) => id !== txnId);
756
+ reviewTabView.transactionIdsWithUnsavedData =
757
+ reviewTabView.transactionIdsWithUnsavedData.filter((id) => id !== txnId);
758
+ }
759
+ // If both tabs, remove from auto tab entirely
760
+ if (existsInAuto) {
761
+ removeTransactionFromTabView(autoTabView, txnId);
762
+ }
763
+ },
764
+ },
702
765
  },
703
766
  });
704
- 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, } = expenseAutomationTransactionsView.actions;
767
+ 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, } = expenseAutomationTransactionsView.actions;
705
768
  export default expenseAutomationTransactionsView.reducer;
@@ -6,7 +6,7 @@ import { saveTransactionDetail, updateTransactionDetail, } from '../transactionD
6
6
  import { getTransactionDetailKey } from '../transactionDetailState';
7
7
  import { toTransactionUpdatesFromTransactionDetailLocalData } from './saveTransactionHelper';
8
8
  export const saveTransactionDetailEpic = (actions$, state$) => actions$.pipe(filter(saveTransactionDetail.match), mergeMap((action) => {
9
- const { transactionId, cotTransactionTracking, isExpenseAutomationEnabled, } = action.payload;
9
+ const { transactionId, cotTransactionTracking, isExpenseAutomationEnabled, isUncategorizedExpenseCategoryEnabled, } = action.payload;
10
10
  const fetchActions = [];
11
11
  const transactionDetailState = state$.value.transactionDetailState;
12
12
  const transactionState = state$.value.transactionState;
@@ -16,7 +16,7 @@ export const saveTransactionDetailEpic = (actions$, state$) => actions$.pipe(fil
16
16
  if (detail != null && transaction != null) {
17
17
  const localData = detail.transactionDetailLocalData;
18
18
  const transactionSaveUpdates = toTransactionUpdatesFromTransactionDetailLocalData(localData, transaction, isExpenseAutomationEnabled);
19
- fetchActions.push(updateTransactionDetail(transactionId, transactionSaveUpdates, isExpenseAutomationEnabled, cotTransactionTracking));
19
+ fetchActions.push(updateTransactionDetail(transactionId, transactionSaveUpdates, isExpenseAutomationEnabled, cotTransactionTracking, isUncategorizedExpenseCategoryEnabled));
20
20
  return from(fetchActions);
21
21
  }
22
22
  return from(fetchActions);
@@ -13,18 +13,21 @@ import { isTransferTransaction, } from '../../../entity/transaction/stateTypes/o
13
13
  import { toJEAndDepositTransactionTypeStrict, toVendorTransactionTypeStrict, } from '../../../entity/transaction/stateTypes/transactionType';
14
14
  import { isVendorTransaction, } from '../../../entity/transaction/stateTypes/vendorTransaction';
15
15
  import toSupportedTransaction from '../../../entity/transaction/toSupportedTransaction';
16
- import { updateTransaction } from '../../../entity/transaction/transactionReducer';
16
+ import { getTransactionWithCOT } from '../../../entity/transaction/transactionHelper';
17
+ import { updateTransaction, updateTransactions, } from '../../../entity/transaction/transactionReducer';
17
18
  import { getSupportedTransactionById } from '../../../entity/transaction/transactionSelector';
18
19
  import { updateVendors } from '../../../entity/vendor/vendorReducer';
19
20
  import { getVendorByVendorId } from '../../../entity/vendor/vendorSelector';
20
21
  import { createZeniAPIStatus, isActionNotAllowed, isSuccessResponse, } from '../../../responsePayload';
21
22
  import { getUncategorizedAccounts } from '../../accountList/accountListSelector';
23
+ import { getPendingReviewLineIdsFromTransaction } from '../../expenseAutomationView/helpers/transactionCategorizationLocalDataHelper';
24
+ import { syncTransactionCategorizationFromDetailSave } from '../../expenseAutomationView/reducers/transactionsViewReducer';
22
25
  import { initializeTransactionDetailLocalData, markTransactionAsNotMiscategorized, updateStatusConsolidatedSaveTransactionDetail, updateTransactionDetail, updateTransactionDetailSaveStatus, updateTransactionStateIfUpdateActionNotAllowed, } from '../transactionDetailReducer';
23
26
  import { getTransactionDetailKey, } from '../transactionDetailState';
24
27
  import { isTransactionUncategorized } from './saveTransactionHelper';
25
28
  export const updateTransactionDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(updateTransactionDetail.match), mergeMap((action) => {
26
29
  const { transactionState, vendorState, transactionDetailState } = state$.value;
27
- const { cotTransactionTracking, transactionId, transactionSaveUpdates } = action.payload;
30
+ const { cotTransactionTracking, transactionId, transactionSaveUpdates, isUncategorizedExpenseCategoryEnabled, } = action.payload;
28
31
  return zeniAPI
29
32
  .putAndGetJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/transactions/${action.payload.transactionId.id}/categorize`, preparePayload(transactionState, vendorState, transactionDetailState, transactionId, transactionSaveUpdates, cotTransactionTracking))
30
33
  .pipe(mergeMap((response) => {
@@ -102,6 +105,12 @@ export const updateTransactionDetailEpic = (actions$, state$, zeniAPI) => action
102
105
  }));
103
106
  }
104
107
  }
108
+ // Sync transaction categorization list state from detail save
109
+ // Updates list-keyed canonical entity so the list selector reads fresh data
110
+ actions.push(updateTransactions([response.data.transaction], (value) => value.transaction_id, 'merge'));
111
+ const transactionWithCOT = getTransactionWithCOT(transaction);
112
+ const pendingReviewLineIds = getPendingReviewLineIdsFromTransaction(transactionWithCOT);
113
+ actions.push(syncTransactionCategorizationFromDetailSave(transactionIdResp, transactionWithCOT, pendingReviewLineIds, uncategorizedIncomeExpense, isUncategorizedExpenseCategoryEnabled));
105
114
  return from(actions);
106
115
  }
107
116
  else if (isActionNotAllowed(response)) {
@@ -105,13 +105,14 @@ const transactionDetail = createSlice({
105
105
  };
106
106
  }
107
107
  },
108
- prepare(transactionId, transactionSaveUpdates, isExpenseAutomationEnabled, cotTransactionTracking) {
108
+ prepare(transactionId, transactionSaveUpdates, isExpenseAutomationEnabled, cotTransactionTracking, isUncategorizedExpenseCategoryEnabled) {
109
109
  return {
110
110
  payload: {
111
111
  transactionId,
112
112
  transactionSaveUpdates,
113
113
  isExpenseAutomationEnabled,
114
114
  cotTransactionTracking,
115
+ isUncategorizedExpenseCategoryEnabled,
115
116
  },
116
117
  };
117
118
  },
package/lib/index.d.ts CHANGED
@@ -265,7 +265,7 @@ import { clearExpenseAutomationFluxAnalysisView, fetchFluxAnalysisView, reviewFl
265
265
  import { clearJeScheduleLocalData as clearExpenseAutomationJEScheduleLocalData, clearExpenseAutomationJESchedulesView, fetchJeSchedulesPage as fetchExpenseAutomationJESchedulesPage, ignoreRecommendedJeSchedule as ignoreExpenseAutomationJESchedule, initializeAccountSettingsView as initializeJeAccountSettingsView, initializeJeScheduleLocalData, removeJeScheduleTransactionKey, retryJeSchedule as retryExpenseAutomationJESchedule, saveAccountSettings as saveJeAccountSettings, saveAccountSettingsLocalData as saveJeAccountSettingsLocalData, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys } from './view/expenseAutomationView/reducers/jeSchedulesViewReducer';
266
266
  import { fetchMissingReceipts as fetchExpenseAutomationMissingReceipts, markMissingReceiptAsDone as markExpenseAutomationMissingReceiptAsDone, updateMissingReceiptUploadState as updateExpenseAutomationMissingReceiptUploadState, updateMissingReceiptsUIState as updateExpenseAutomationMissingReceiptsUIState, uploadMissingReceiptSuccess as uploadExpenseAutomationMissingReceiptSuccess } from './view/expenseAutomationView/reducers/missingReceiptsViewReducer';
267
267
  import { deleteAccountStatement, fetchReconciliation as fetchReconciliationView, saveReconciliationDetail as saveExpenseAutomationReconciliationDetail, saveReconciliationReview as saveExpenseAutomationReconciliationReview, setConnectionInProgressForAccount as setConnectionInProgressForAccountReconciliation, setStatementParseInProgress, updateAccountReconciliationLocalData as updateExpenseAutomationAccountReconciliationLocalData, updateSelectedAccountId as updateExpenseAutomationAccountReconciliationSelectedAccountId, updateSelectedTab as updateExpenseAutomationAccountReconciliationSelectedTab, updateReconListScrollPosition as updateExpenseAutomationReconListScrollPosition, updateReviewTabSortState as updateExpenseAutomationReconReviewTabListSortState, updateReviewTabLocalData as updateExpenseAutomationReconReviewTabLocalData, updateReconcileTabListScrollState as updateExpenseAutomationReconcileTabListScrollState, updateReconcileTabListSortState as updateExpenseAutomationReconcileTabListSortState, updateReconcileTabLocalData as updateExpenseAutomationReconcileTabLocalData, updateSelectedDrawerAccountId as updateExpenseAutomationSelectedDrawerAccountId, updateStatementUploadChosen, uploadAccountStatement } from './view/expenseAutomationView/reducers/reconciliationViewReducer';
268
- import { clearExpenseAutomationTransactionsView, fetchTransactionCategorization, fetchTransactionCategorizationFailure, fetchTransactionCategorizationView, initializeTransactionCategorizationViewLocalData, markTransactionAsNotMiscategorized, saveTransactionCategorization, saveTransactionCategorizationLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, setEntityRecommendationForLineIdsForCategorization, updateCurrentSelectedTransactionCategorizationTab, updateSelectedCheckboxTransactionIds, updateSelectedCustomerForTransaction, updateSelectedTransactionId, updateSelectedVendorForTransaction, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, updateTransactionCategorizationUIState } from './view/expenseAutomationView/reducers/transactionsViewReducer';
268
+ import { clearExpenseAutomationTransactionsView, fetchTransactionCategorization, fetchTransactionCategorizationFailure, fetchTransactionCategorizationView, initializeTransactionCategorizationViewLocalData, markTransactionAsNotMiscategorized, saveTransactionCategorization, saveTransactionCategorizationLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, setEntityRecommendationForLineIdsForCategorization, syncTransactionCategorizationFromDetailSave, updateCurrentSelectedTransactionCategorizationTab, updateSelectedCheckboxTransactionIds, updateSelectedCustomerForTransaction, updateSelectedTransactionId, updateSelectedVendorForTransaction, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, updateTransactionCategorizationUIState } from './view/expenseAutomationView/reducers/transactionsViewReducer';
269
269
  import { ExpenseAutomationStepDetails, ExpenseAutomationViewSelector } from './view/expenseAutomationView/selectorTypes/expenseAutomationViewSelectorTypes';
270
270
  import { ExpenseAutomationFluxAnalysisViewSelector, FluxAnalysisOperatingExpenseView, FluxAnalysisSectionType, FluxAnalysisVendorView, FluxAnalysisViewSectionReport, FluxVendorAccountsAndClassesView } from './view/expenseAutomationView/selectorTypes/fluxAnalysisViewSelectorTypes';
271
271
  import { JEAccountSettingsView } from './view/expenseAutomationView/selectorTypes/jeAccountSettingsViewSelectorTypes';
@@ -616,7 +616,7 @@ export { fetchMonthEndCloseChecks, fetchMonthClosePerformanceTrend, MonthClosePe
616
616
  export { ExpenseAutomationViewSelector, ExpenseAutomationStepDetails, ExpenseAutomationViewType, ExpenseAutomationMissingReceiptsViewSelector, ExpenseAutomationFluxAnalysisViewSelector, FluxAnalysisVendorView, FluxAnalysisViewSectionReport, FluxVendorAccountsAndClassesView, ExpenseAutomationMissingReceiptsViewUIState, ExpenseAutomationMissingReceiptsViewState, ExpenseAutomationViewState, ExpenseAutomationTransactionsTab, ExpenseAutomationMissingReceiptsSortKey, getExpenseAutomationView, toExpenseAutomationMissingReceiptsSortKey, toExpenseAutomationTransactionsTabKey, toExpenseAutomationViewType, uploadExpenseAutomationMissingReceiptSuccess, markExpenseAutomationMissingReceiptAsDone, fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedTransactionCategorizationTab, fetchExpenseAutomationMissingReceipts, fetchFluxAnalysisView, clearExpenseAutomationFluxAnalysisView, updateOperatingExpensesIdsForReview as updateFluxOperatingExpensesIdsForReview, updateSelectedSectionIdsForReview as updateFluxAnalysisSelectedSectionIdsForReview, reviewFluxAnalysisView, updateExpenseAutomationMissingReceiptUploadState, updateExpenseAutomationMissingReceiptsUIState, FluxAnalysisOperatingExpenseView, FluxAnalysisSectionType, getExpenseAutomationFluxAnalysisView, FluxAnalysisSortKey, FluxAnalysisActionType, FluxBalancesByMonth, updateCurrentSelectedView, updateCurrentSelectedPeriod, getExpenseAutomationTransactionView, ReconReconcileSortKey, ReconciliationReconcileTabLocalData, FluxAnalysisReviewStatus, updateFluxAnalysisViewUIState, FluxAnalysisViewUIState, updateFluxAnalysisViewPageMetaData, MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, getLineItemsByTransactionIdsFromLocalData, isAnyItemWithUncategorizedExpenseAccount, SaveExpenseAutomationReconciliationActionType, saveExpenseAutomationReconciliationDetail, updateExpenseAutomationReconcileTabListScrollState, updateExpenseAutomationReconReviewTabListSortState, updateExpenseAutomationReconcileTabListSortState, updateExpenseAutomationReconcileTabLocalData, updateExpenseAutomationAccountReconciliationSelectedTab, updateExpenseAutomationAccountReconciliationSelectedAccountId, ExpenseAutomationReconciliationViewSelector, getExpenseAutomationReconciliationView, AccountReconciliationBySection, fetchReconciliationView, uploadAccountStatementIntoDocumentAI, UploadStatementDocumentAIResponse, updateExpenseAutomationReconListScrollPosition, setConnectionInProgressForAccountReconciliation, AccountReconciliationByAccount, AccountReconciliationEntity, getAccountReconByAccountIdAndSelectedPeriod, ExpenseAutomationReconciliationViewTab, toReconciliationTabsType, isAccountReconReport, ReconReviewSortKey, AccountReconSectionID, ReconciliationReviewTabLocalData, TransactionsToReview, RecommendedActionCodeType, ReconciliationStatusCodeType, BalanceDataStatusCodeType, updateExpenseAutomationReconReviewTabLocalData, updateExpenseAutomationSelectedDrawerAccountId, saveExpenseAutomationReconciliationReview, updateExpenseAutomationAccountReconciliationLocalData, BankStatusCodeType, ReconciliationAccountSourceType, toReconciliationAccountSource, StatementStatusCodeType, AccountReconciliationLocalData, StatementDataStatusCodeType, deleteAccountStatement, uploadAccountStatement, UploadStatementDocumentAIPayload, updateStatementUploadChosen, isReviewTransactionBankTransferType, isReviewTransactionBillPaymentType, isReviewTransactionCreditCardPaymentType, isReviewTransactionDepositType, isReviewTransactionExpenseType, isReviewTransactionCreditCardCreditType, setStatementParseInProgress, };
617
617
  export { JEScheduleLocalData };
618
618
  export { ExpenseAutomationJESchedulesViewSelector, JEAccountSettingsView, JEScheduledTransactionWithFailedEntries, };
619
- export { fetchTransactionCategorization, fetchTransactionCategorizationView, updateTransactionCategorizationUIState, updateSelectedCheckboxTransactionIds, setEntityRecommendationForLineIdsForCategorization, initializeTransactionCategorizationViewLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, updateSelectedTransactionId, clearExpenseAutomationTransactionsView, TransactionsSortKey, toTransactionsSortKey, TransactionsTab, TransactionCategorizationLineItemData, TransactionReviewLocalData, SupportedTransactionCategorization, ExpenseAutomationTransactionsViewState, ExpenseAutomationTransactionsViewUIState, ExpenseAutomationTransactionViewSelector, TransactionReviewLocalDataSelectorView, };
619
+ export { fetchTransactionCategorization, fetchTransactionCategorizationView, updateTransactionCategorizationUIState, updateSelectedCheckboxTransactionIds, setEntityRecommendationForLineIdsForCategorization, initializeTransactionCategorizationViewLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, updateSelectedTransactionId, syncTransactionCategorizationFromDetailSave, clearExpenseAutomationTransactionsView, TransactionsSortKey, toTransactionsSortKey, TransactionsTab, TransactionCategorizationLineItemData, TransactionReviewLocalData, SupportedTransactionCategorization, ExpenseAutomationTransactionsViewState, ExpenseAutomationTransactionsViewUIState, ExpenseAutomationTransactionViewSelector, TransactionReviewLocalDataSelectorView, };
620
620
  export { TopExpense, TopExTimePeriod, TOP_EX_TIME_PERIODS };
621
621
  export { TimeframeTick, TimeframeTickWithMetaData, toTimeframeTick, mapTimePeriodtoTimeframeTick, toTimePeriod, toAbsoluteDay, toMonthYearPeriodId, convertToPeriod, MonthYearPeriod, };
622
622
  export { VendorSpendTrendFilterTabType, toVendorSpendTrendFilterTabsTypeStrict, } from './entity/vendorExpense/vendorExpenseSelector';