@zeniai/client-epic-state 5.2.62-beta0MM → 5.2.62-beta1KB

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 (70) hide show
  1. package/lib/entity/actualMatching/actualMatchingReducer.d.ts +1 -3
  2. package/lib/entity/actualMatching/actualMatchingReducer.js +2 -11
  3. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +0 -1
  4. package/lib/entity/jeSchedules/jeSchedulesPayload.js +0 -1
  5. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +0 -1
  6. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  7. package/lib/entity/snackbar/snackbarTypes.js +1 -1
  8. package/lib/entity/transaction/stateTypes/paymentType.d.ts +2 -2
  9. package/lib/entity/transaction/stateTypes/paymentType.js +9 -1
  10. package/lib/entity/transaction/stateTypes/printStatus.d.ts +4 -0
  11. package/lib/entity/transaction/stateTypes/printStatus.js +15 -0
  12. package/lib/epic.d.ts +4 -2
  13. package/lib/epic.js +6 -2
  14. package/lib/esm/entity/actualMatching/actualMatchingReducer.js +1 -9
  15. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +0 -1
  16. package/lib/esm/entity/snackbar/snackbarTypes.js +1 -1
  17. package/lib/esm/entity/transaction/stateTypes/paymentType.js +9 -1
  18. package/lib/esm/entity/transaction/stateTypes/printStatus.js +11 -0
  19. package/lib/esm/epic.js +6 -2
  20. package/lib/esm/index.js +10 -7
  21. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.js +3 -7
  22. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchTransactionsEpic.js +23 -2
  23. package/lib/esm/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +35 -66
  24. package/lib/esm/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +64 -60
  25. package/lib/esm/view/expenseAutomationView/types/actualMatchingViewState.js +0 -15
  26. package/lib/esm/view/spendManagement/billPay/editBillView/editBillViewSelector.js +4 -30
  27. package/lib/esm/view/transactionDetail/createTransaction/createTransactionLocalDataHelper.js +133 -0
  28. package/lib/esm/view/transactionDetail/createTransaction/createTransactionPayload.js +124 -0
  29. package/lib/esm/view/transactionDetail/createTransaction/createTransactionSelector.js +41 -0
  30. package/lib/esm/view/transactionDetail/createTransaction/createTransactionState.js +11 -0
  31. package/lib/esm/view/transactionDetail/createTransaction/epics/createTransactionEpic.js +58 -0
  32. package/lib/esm/view/transactionDetail/createTransaction/epics/fetchVendorRecommendationsForCreateTransactionEpic.js +55 -0
  33. package/lib/esm/view/transactionDetail/createTransaction/epics/initializeCreateTransactionLocalDataEpic.js +14 -0
  34. package/lib/esm/view/transactionDetail/transactionDetailReducer.js +174 -1
  35. package/lib/index.d.ts +12 -8
  36. package/lib/index.js +70 -57
  37. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.js +3 -7
  38. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchTransactionsEpic.js +22 -1
  39. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  40. package/lib/view/expenseAutomationView/payload/actualMatchingPayload.d.ts +1 -12
  41. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.d.ts +8 -16
  42. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +36 -67
  43. package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.d.ts +8 -20
  44. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.d.ts +4 -7
  45. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +64 -63
  46. package/lib/view/expenseAutomationView/types/actualMatchingViewState.d.ts +4 -20
  47. package/lib/view/expenseAutomationView/types/actualMatchingViewState.js +1 -18
  48. package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.d.ts +1 -1
  49. package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.js +4 -30
  50. package/lib/view/transactionDetail/createTransaction/createTransactionLocalDataHelper.d.ts +51 -0
  51. package/lib/view/transactionDetail/createTransaction/createTransactionLocalDataHelper.js +148 -0
  52. package/lib/view/transactionDetail/createTransaction/createTransactionPayload.d.ts +82 -0
  53. package/lib/view/transactionDetail/createTransaction/createTransactionPayload.js +128 -0
  54. package/lib/view/transactionDetail/createTransaction/createTransactionSelector.d.ts +40 -0
  55. package/lib/view/transactionDetail/createTransaction/createTransactionSelector.js +48 -0
  56. package/lib/view/transactionDetail/createTransaction/createTransactionState.d.ts +81 -0
  57. package/lib/view/transactionDetail/createTransaction/createTransactionState.js +14 -0
  58. package/lib/view/transactionDetail/createTransaction/epics/createTransactionEpic.d.ts +9 -0
  59. package/lib/view/transactionDetail/createTransaction/epics/createTransactionEpic.js +62 -0
  60. package/lib/view/transactionDetail/createTransaction/epics/fetchVendorRecommendationsForCreateTransactionEpic.d.ts +20 -0
  61. package/lib/view/transactionDetail/createTransaction/epics/fetchVendorRecommendationsForCreateTransactionEpic.js +59 -0
  62. package/lib/view/transactionDetail/createTransaction/epics/initializeCreateTransactionLocalDataEpic.d.ts +12 -0
  63. package/lib/view/transactionDetail/createTransaction/epics/initializeCreateTransactionLocalDataEpic.js +18 -0
  64. package/lib/view/transactionDetail/transactionDetailReducer.d.ts +37 -1
  65. package/lib/view/transactionDetail/transactionDetailReducer.js +176 -2
  66. package/lib/view/transactionDetail/transactionDetailState.d.ts +12 -0
  67. package/package.json +1 -1
  68. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.js +0 -50
  69. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.d.ts +0 -10
  70. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.js +0 -54
package/lib/esm/index.js CHANGED
@@ -188,7 +188,7 @@ import { toExpenseAutomationViewType, toExpenseAutomationViewTypeStrict, } from
188
188
  import { computeNewScheduleJeDetails } from './view/expenseAutomationView/helpers/newScheduleLocalDataHelper';
189
189
  import { isReviewTransactionBankTransferType, isReviewTransactionBillPaymentType, isReviewTransactionCreditCardCreditType, isReviewTransactionCreditCardPaymentType, isReviewTransactionDepositType, isReviewTransactionExpenseType, } from './view/expenseAutomationView/helpers/reconciliationHelpers';
190
190
  import { MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, getLineItemsByTransactionIdsFromLocalData, isAnyItemWithUncategorizedExpenseAccount, } from './view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper';
191
- import { ackCloseMatchAfterIgnore, ackCloseMatchAfterUndo, clearActualMatchingView as clearExpenseAutomationActualMatchingView, clearMatchNewModal, closeMatchNewModal, fetchActualMatching as fetchExpenseAutomationActualMatching, fetchActualMatchingMatch, fetchActualMatchingPage as fetchExpenseAutomationActualMatchingPage, ignoreActualMatchingSuggestion, matchAndReverseAccruals, openMatchNewModal, searchMatchAccruals, searchMatchTransactions, undoReversalAccruals, updateActualMatchingUIState as updateExpenseAutomationActualMatchingUIState, } from './view/expenseAutomationView/reducers/actualMatchingViewReducer';
191
+ import { ackCloseMatchAfterUndo, clearActualMatchingView as clearExpenseAutomationActualMatchingView, clearMatchNewModal, closeMatchNewModal, fetchActualMatchingMatch, fetchActualMatching as fetchExpenseAutomationActualMatching, fetchActualMatchingPage as fetchExpenseAutomationActualMatchingPage, matchAndReverseAccruals, openMatchNewModal, searchMatchAccruals, searchMatchTransactions, undoReversalAccruals, updateActualMatchingUIState as updateExpenseAutomationActualMatchingUIState, } from './view/expenseAutomationView/reducers/actualMatchingViewReducer';
192
192
  import { clearExpenseAutomationFluxAnalysisView, fetchFluxAnalysisView, reviewFluxAnalysisView, updateFluxAnalysisViewPageMetaData, updateFluxAnalysisViewUIState, updateOperatingExpensesIdsForReview, updateSelectedSectionIdsForReview, } from './view/expenseAutomationView/reducers/fluxAnalysisViewReducer';
193
193
  import { clearJeScheduleLocalData as clearExpenseAutomationJEScheduleLocalData, clearExpenseAutomationJESchedulesView, clearSearchTransactionsForNewSchedule as clearJeSearchTransactionsForNewSchedule, createOneTimeAccrual, createOneTimeAccrualFailure, createOneTimeAccrualSuccess, fetchJeSchedulesPage as fetchExpenseAutomationJESchedulesPage, fetchOneTimeAccrual, ignoreRecommendedJeSchedule as ignoreExpenseAutomationJESchedule, ignoreOneTimeAccrual, initializeAccountSettingsView as initializeJeAccountSettingsView, initializeNewSchedule as initializeJeNewSchedule, initializeJeScheduleLocalData, promoteOneTimeAccrual, removeJeOneTimeAccrualLocalData, removeJeScheduleTransactionKey, resetNewScheduleLocalData as resetJeNewScheduleLocalData, retryJeSchedule as retryExpenseAutomationJESchedule, revertJeSchedule, revertOneTimeAccrual, saveAccountSettings as saveJeAccountSettings, saveAccountSettingsLocalData as saveJeAccountSettingsLocalData, saveNewSchedule as saveJeNewSchedule, saveNewScheduleFailure as saveJeNewScheduleFailure, saveNewScheduleSuccess as saveJeNewScheduleSuccess, searchTransactionsForNewSchedule as searchJeTransactionsForNewSchedule, searchTransactionsForNewScheduleFailure as searchJeTransactionsForNewScheduleFailure, searchTransactionsForNewScheduleSuccess as searchJeTransactionsForNewScheduleSuccess, toggleJECreatedGroupCollapsed, toggleJEFailedGroupCollapsed, toggleJEPendingGroupCollapsed, updateJESchedulesUIState as updateExpenseAutomationJESchedulesUIState, updateJEScheduleTypeFilter, updateNewScheduleLocalData as updateJeNewScheduleLocalData, updateJeOneTimeAccrualLocalData, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys, } from './view/expenseAutomationView/reducers/jeSchedulesViewReducer';
194
194
  import { acknowledgeBulkUploadConfirmMatchComplete, bulkUploadAutomatchingTimedOut, bulkUploadReceipts, bulkUploadReceiptsFailure, bulkUploadReceiptsSuccess, clearBulkUpload, clearBulkUploadBatchDetailsForScopeChange, clearManualSearchResults, clearMissingReceiptsTabNavigation, confirmBulkUploadMatch, confirmBulkUploadMatchFailure, confirmBulkUploadMatchSuccess, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsFailure, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatches, fetchBulkUploadBatchesFailure, fetchBulkUploadBatchesSuccess, fetchCompletedTransactions, fetchCompletedTransactionsFailure, fetchCompletedTransactionsSuccess, fetchMissingReceipts as fetchExpenseAutomationMissingReceipts, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, markBatchDetailRefreshAttempted, markMissingReceiptAsDone as markExpenseAutomationMissingReceiptAsDone, pusherBatchStatusUpdate, refreshBatchDetailsForBatchId, requestMissingReceiptsTabNavigation, restoreBulkUploadAutomatchingOnMount, restoreBulkUploadMatchingState, searchTransactionsForManualMatch, searchTransactionsForManualMatchFailure, searchTransactionsForManualMatchSuccess, setBulkUploadCompletedSubTab, setBulkUploadResultsTab, setBulkUploadSortConfig, setBulkUploadUploadedFileCount, storeBatchDetails, updateBulkUploadProgress, updateMissingReceiptUploadState as updateExpenseAutomationMissingReceiptUploadState, updateMissingReceiptsUIState as updateExpenseAutomationMissingReceiptsUIState, uploadMissingReceiptSuccess as uploadExpenseAutomationMissingReceiptSuccess, } from './view/expenseAutomationView/reducers/missingReceiptsViewReducer';
@@ -200,7 +200,7 @@ import { getExpenseAutomationReconciliationView, getLedgerAccountIdsWithStatemen
200
200
  import { getExpenseAutomationTransactionView, getLastTransferEntryReplacement, } from './view/expenseAutomationView/selectors/transactionCategorizationSelector';
201
201
  import { applyTransactionFilters } from './view/expenseAutomationView/transactionFilterHelpers';
202
202
  import { TRANSACTION_FILTER_CATEGORIES, } from './view/expenseAutomationView/transactionFilterTypes';
203
- import { MATCH_ACCRUAL_SEARCH_LIMIT, MATCH_SEARCH_DEBOUNCE_MS, MATCH_TRANSACTION_SEARCH_PAGE_SIZE, ALL_ACTUAL_MATCHING_IGNORE_REASONS, actualMatchingTransactionLineKey, toActualMatchingIgnoreReasonType, toActualMatchingSortKey as toExpenseAutomationActualMatchingSortKey, toActualMatchingStatusFilter as toExpenseAutomationActualMatchingStatusFilter, toMatchAndReverseResultStatus, toUndoReversalResultStatus, } from './view/expenseAutomationView/types/actualMatchingViewState';
203
+ import { MATCH_ACCRUAL_SEARCH_LIMIT, MATCH_SEARCH_DEBOUNCE_MS, MATCH_TRANSACTION_SEARCH_PAGE_SIZE, actualMatchingTransactionLineKey, toActualMatchingSortKey as toExpenseAutomationActualMatchingSortKey, toMatchAndReverseResultStatus, toUndoReversalResultStatus, } from './view/expenseAutomationView/types/actualMatchingViewState';
204
204
  import { DEFAULT_COMPLETED_SUB_TAB, toCompletedSubTab, } from './view/expenseAutomationView/types/completedSubTab';
205
205
  import { ALL_JE_PAGE_TABS, toJEScheduleSortKey as toExpenseAutomationJEScheduleSortKey, toJEPageTab, } from './view/expenseAutomationView/types/jeSchedulesViewState';
206
206
  import { BATCH_FILE_STATUSES, isUnmatchedTabFileStatus, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toMatchSource, toMissingReceiptsTab, } from './view/expenseAutomationView/types/missingReceiptsViewState';
@@ -428,8 +428,11 @@ import { getAllTopExpenses, getTop6Expenses, getTopExpenses, } from './view/topE
428
428
  import { TOP_EX_TIME_PERIODS, } from './view/topEx/topExState';
429
429
  import { getAccountingProviderAttachment, } from './view/transactionDetail/getAccountingProviderAttachmentSelector';
430
430
  import { JOURNAL_ENTRY_SORT_KEYS, filterJournalEntryLinesExcludingLinked, journalEntryDefaultSortConfig, journalEntrySplitReconciliation, journalEntryTotalsByPostingSide, sortJournalEntryLines, sumJournalEntryAmounts, toJournalEntrySortKey, } from './view/transactionDetail/journalEntryLinesViewModel';
431
+ import { prepareCreateTransactionPayload, } from './view/transactionDetail/createTransaction/createTransactionPayload';
432
+ import { getCreateTransactionLocalData, getCreateTransactionStatus, getCreateTransactionVendorRecommendations, getCreateTransactionView, } from './view/transactionDetail/createTransaction/createTransactionSelector';
433
+ import { ALL_CREATABLE_TRANSACTION_TYPES, } from './view/transactionDetail/createTransaction/createTransactionState';
431
434
  import { getChangedLineItemCountFromLocalData, isAccountUncategorized, } from './view/transactionDetail/transactionDetailLocalDataHelper';
432
- import { addSplitLine, clearTransactionDetailSaveStatus, deleteSplitLine, deleteTransactionAttachment, downloadAccountingProviderAttachment, downloadAccountingProviderAttachmentFailure, downloadAccountingProviderAttachmentSuccess, fetchTransactionDetail, initializeTransactionDetailLocalData, markCategoryClassRecommendationsFailureForTransactionDetail, removeEntityRecommendationForLineIdForTransactionDetail, resetAllLineItemsToVendor, resetLineItemsCategoryClassInLocalData, resetSelectedCustomer, resetVendor, saveTransactionDetail, saveTransactionDetailLocalData, setAllLineItemsLocalDataIsUpdateAllChecked, setAllLineItemsToCategoryClassInLocalData, setIsVendorUpdateAllChecked, toggleSplitEditMode, updateLatestSelectedEntity, updateLocalDataWithTransactionsUpdateWithVendorCheckbox, updateSelectedCustomer, updateSelectedVendor, updateTransactionDetail, updateVendorBulkRecommendationsFetchStatus, updateVendorToAllLineItems, uploadMissingAttachmentSuccess, } from './view/transactionDetail/transactionDetailReducer';
435
+ import { addCreateTransactionLine, addSplitLine, clearRecommendationsForCreateTransactionLines, clearTransactionDetailSaveStatus, createTransaction, createTransactionSuccessOrFailure, fetchVendorRecommendationsForCreateTransaction, initializeCreateTransactionLocalData, removeCreateTransactionLine, resetCreateTransactionLocalData, setRecommendationsForCreateTransactionLines, updateCreateTransactionLineLocalData, updateCreateTransactionLocalData, deleteSplitLine, deleteTransactionAttachment, downloadAccountingProviderAttachment, downloadAccountingProviderAttachmentFailure, downloadAccountingProviderAttachmentSuccess, fetchTransactionDetail, initializeTransactionDetailLocalData, markCategoryClassRecommendationsFailureForTransactionDetail, removeEntityRecommendationForLineIdForTransactionDetail, resetAllLineItemsToVendor, resetLineItemsCategoryClassInLocalData, resetSelectedCustomer, resetVendor, saveTransactionDetail, saveTransactionDetailLocalData, setAllLineItemsLocalDataIsUpdateAllChecked, setAllLineItemsToCategoryClassInLocalData, setIsVendorUpdateAllChecked, toggleSplitEditMode, updateLatestSelectedEntity, updateLocalDataWithTransactionsUpdateWithVendorCheckbox, updateSelectedCustomer, updateSelectedVendor, updateTransactionDetail, updateVendorBulkRecommendationsFetchStatus, updateVendorToAllLineItems, uploadMissingAttachmentSuccess, } from './view/transactionDetail/transactionDetailReducer';
433
436
  import { getInitialUpdatablePeriodsForTransactionRecommendations, getTransactionDetail, getTransactionDetailForTransaction, } from './view/transactionDetail/transactionDetailSelector';
434
437
  import { getThirdPartyIdFromTransactionId, } from './view/transactionDetail/transactionDetailState';
435
438
  import { getTransactionListByAccount, getTransactionListUIStateByAccountKey, } from './view/transactionList/transactionListByAccountSelector';
@@ -492,7 +495,7 @@ export { stringToUnion, stringToUnionStrict };
492
495
  export { fetchMonthEndCloseChecks, fetchMonthClosePerformanceTrend, getMonthEndCloseChecksViewByTenantId, ALL_MONTH_END_CLOSE_CHECKS_FREQUENCY, };
493
496
  export {
494
497
  // Bulk Upload Types
495
- BATCH_FILE_STATUSES, isUnmatchedTabFileStatus, DEFAULT_COMPLETED_SUB_TAB, DEFAULT_TRANSACTION_GROUP, TRANSACTION_GROUPS, toTransactionGroup, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toCompletedSubTab, toMatchSource, toMissingReceiptsTab, ALL_ACTUAL_MATCHING_IGNORE_REASONS, actualMatchingTransactionLineKey, ALL_JE_PAGE_TABS, MATCH_ACCRUAL_SEARCH_LIMIT, MATCH_SEARCH_DEBOUNCE_MS, MATCH_TRANSACTION_SEARCH_PAGE_SIZE, toExpenseAutomationJEScheduleSortKey, toExpenseAutomationActualMatchingSortKey, toExpenseAutomationActualMatchingStatusFilter, toActualMatchingIgnoreReasonType, toJEPageTab, toMatchAndReverseResultStatus, toUndoReversalResultStatus, toggleJECreatedGroupCollapsed, toggleJEFailedGroupCollapsed, toggleJEPendingGroupCollapsed, updateJEScheduleTypeFilter, getExpenseAutomationView, toExpenseAutomationMissingReceiptsSortKey, toExpenseAutomationTransactionsTabKey, toExpenseAutomationViewType, toExpenseAutomationViewTypeStrict, uploadExpenseAutomationMissingReceiptSuccess, markExpenseAutomationMissingReceiptAsDone, fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedTransactionCategorizationTab, updateTransactionCategorizationCompletedSubTab, updateTransactionGroup, fetchExpenseAutomationMissingReceipts,
498
+ BATCH_FILE_STATUSES, isUnmatchedTabFileStatus, DEFAULT_COMPLETED_SUB_TAB, DEFAULT_TRANSACTION_GROUP, TRANSACTION_GROUPS, toTransactionGroup, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toCompletedSubTab, toMatchSource, toMissingReceiptsTab, actualMatchingTransactionLineKey, ALL_JE_PAGE_TABS, MATCH_ACCRUAL_SEARCH_LIMIT, MATCH_SEARCH_DEBOUNCE_MS, MATCH_TRANSACTION_SEARCH_PAGE_SIZE, toExpenseAutomationJEScheduleSortKey, toExpenseAutomationActualMatchingSortKey, toJEPageTab, toMatchAndReverseResultStatus, toUndoReversalResultStatus, toggleJECreatedGroupCollapsed, toggleJEFailedGroupCollapsed, toggleJEPendingGroupCollapsed, updateJEScheduleTypeFilter, getExpenseAutomationView, toExpenseAutomationMissingReceiptsSortKey, toExpenseAutomationTransactionsTabKey, toExpenseAutomationViewType, toExpenseAutomationViewTypeStrict, uploadExpenseAutomationMissingReceiptSuccess, markExpenseAutomationMissingReceiptAsDone, fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedTransactionCategorizationTab, updateTransactionCategorizationCompletedSubTab, updateTransactionGroup, fetchExpenseAutomationMissingReceipts,
496
499
  // Bulk Upload Actions
497
500
  bulkUploadReceipts, bulkUploadAutomatchingTimedOut, bulkUploadReceiptsSuccess, bulkUploadReceiptsFailure, restoreBulkUploadAutomatchingOnMount, restoreBulkUploadMatchingState, updateBulkUploadProgress, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, clearMissingReceiptsTabNavigation, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatchDetailsFailure, storeBatchDetails, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, fetchBulkUploadBatches, fetchBulkUploadBatchesSuccess, fetchBulkUploadBatchesFailure, clearBulkUploadBatchDetailsForScopeChange, markBatchDetailRefreshAttempted, refreshBatchDetailsForBatchId, confirmBulkUploadMatch, confirmBulkUploadMatchSuccess, confirmBulkUploadMatchFailure, setBulkUploadResultsTab, setBulkUploadCompletedSubTab, setBulkUploadSortConfig, setBulkUploadUploadedFileCount, clearBulkUpload, searchTransactionsForManualMatch, searchTransactionsForManualMatchSuccess, searchTransactionsForManualMatchFailure, clearManualSearchResults, acknowledgeBulkUploadConfirmMatchComplete, fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, fetchFluxAnalysisView, clearExpenseAutomationFluxAnalysisView, updateOperatingExpensesIdsForReview as updateFluxOperatingExpensesIdsForReview, updateSelectedSectionIdsForReview as updateFluxAnalysisSelectedSectionIdsForReview, reviewFluxAnalysisView, updateExpenseAutomationMissingReceiptUploadState, updateExpenseAutomationMissingReceiptsUIState, updateTransactionCategorizationUploadReceiptState, uploadTransactionCategorizationReceiptSuccess, getExpenseAutomationFluxAnalysisView, updateCurrentSelectedView, updateCurrentSelectedPeriod, getExpenseAutomationTransactionView, getLastTransferEntryReplacement, updateFluxAnalysisViewUIState, updateFluxAnalysisViewPageMetaData, MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, getLineItemsByTransactionIdsFromLocalData, isAnyItemWithUncategorizedExpenseAccount, excludeAccountFromReconciliation, includeAccountInReconciliation, saveExpenseAutomationReconciliationDetail, updateExpenseAutomationReconcileTabListScrollState, updateExpenseAutomationReconReviewTabListSortState, updateExpenseAutomationReconcileTabListSortState, updateExpenseAutomationReconcileTabLocalData, updateExpenseAutomationAccountReconciliationSelectedTab, updateExpenseAutomationAccountReconciliationSelectedAccountId, getExpenseAutomationReconciliationView, getLedgerAccountIdsWithStatementOverrideWarning, getLedgerAccountsForCombinedStatementMapping, getReparseStatementStatusByAccountId, getUnavailableLedgerAccountIds, fetchReconciliationView, uploadAccountStatementIntoDocumentAI, updateExpenseAutomationReconListScrollPosition, setConnectionInProgressForAccountReconciliation, getAccountReconByAccountIdAndSelectedPeriod, toReconciliationTabsType, isAccountReconReport, updateExpenseAutomationReconReviewTabLocalData, updateExpenseAutomationSelectedDrawerAccountId, updateStatementProcessingFailed, saveExpenseAutomationReconciliationReview, updateExpenseAutomationAccountReconciliationLocalData, toReconciliationAccountSource, deleteAccountStatement, deleteCombinedStatement, uploadAccountStatement, parseCombinedStatement, parseStatement, parseStatementSuccess, parseStatementFailure, reparseStatement, reparseStatementSuccess, reparseStatementFailure, resetReparseStatementStatus, updateParsedStatementData, updateNodeCollapseState, updateStatementUploadChosen, submitCombinedStatementUpdate, submitStatementUpdate, clearStatementDateConflict, confirmStatementMapping, updateStatementUpdateLocalData, isReviewTransactionBankTransferType, isReviewTransactionBillPaymentType, isReviewTransactionCreditCardPaymentType, isReviewTransactionDepositType, isReviewTransactionExpenseType, isReviewTransactionCreditCardCreditType, setStatementParseInProgress, setStatementProcessingDismissedToBackground, updateStatementProcessingBackgroundCompletedSteps, };
498
501
  export { computeNewScheduleJeDetails, createOneTimeAccrual, createOneTimeAccrualFailure, createOneTimeAccrualSuccess, fetchOneTimeAccrual, getJeNewAccrualAccountsView, ignoreOneTimeAccrual, promoteOneTimeAccrual, revertJeSchedule, revertOneTimeAccrual, getJeNewScheduleSearchTransactionsView, getJeNewScheduleView, };
@@ -554,7 +557,7 @@ export { isTransferTransaction };
554
557
  export { getScheduleTransactionById, getSupportedTransactionById, };
555
558
  export { updateLatestTransactionId, parallelFetchAccountTransactionList, parallelFetchEntityTransactionList, fetchAccountTransactionList, updateTransactionListByAccount, updateTransactionListByAccountFailure, updateTransactionListByAccountUIState, parallelFetchClassTransactionList, updateTransactionListByClassUIState, updateTransactionListByClass, parallelFetchProjectTransactionList, updateTransactionListByProjectUIState, updateTransactionListByProject, updateTransactionListUIStateByCategoryType, parallelFetchTransactionListByCategoryType, };
556
559
  export { getTransactionListByAccount, getTransactionListUIStateByAccountKey, };
557
- export { fetchEntityTransactionList, updateTransactionListByEntity, saveTransactionDetailLocalData, clearTransactionDetailSaveStatus, updateTransactionListByEntityFailure, resetLineItemsCategoryClassInLocalData, setAllLineItemsToCategoryClassInLocalData, saveTransactionDetail, setAllLineItemsLocalDataIsUpdateAllChecked, initializeTransactionDetailLocalData, markCategoryClassRecommendationsFailureForTransactionDetail, removeEntityRecommendationForLineIdForTransactionDetail, updateSelectedVendor, updateSelectedCustomer, resetSelectedCustomer, resetVendor, updateLocalDataWithTransactionsUpdateWithVendorCheckbox, updateVendorToAllLineItems, resetAllLineItemsToVendor, updateLatestSelectedEntity, updateVendorBulkRecommendationsFetchStatus, setIsVendorUpdateAllChecked, addSplitLine, deleteSplitLine, toggleSplitEditMode, };
560
+ export { ALL_CREATABLE_TRANSACTION_TYPES, initializeCreateTransactionLocalData, updateCreateTransactionLocalData, updateCreateTransactionLineLocalData, addCreateTransactionLine, removeCreateTransactionLine, resetCreateTransactionLocalData, createTransaction, createTransactionSuccessOrFailure, fetchVendorRecommendationsForCreateTransaction, setRecommendationsForCreateTransactionLines, clearRecommendationsForCreateTransactionLines, getCreateTransactionView, getCreateTransactionLocalData, getCreateTransactionStatus, getCreateTransactionVendorRecommendations, prepareCreateTransactionPayload, fetchEntityTransactionList, updateTransactionListByEntity, saveTransactionDetailLocalData, clearTransactionDetailSaveStatus, updateTransactionListByEntityFailure, resetLineItemsCategoryClassInLocalData, setAllLineItemsToCategoryClassInLocalData, saveTransactionDetail, setAllLineItemsLocalDataIsUpdateAllChecked, initializeTransactionDetailLocalData, markCategoryClassRecommendationsFailureForTransactionDetail, removeEntityRecommendationForLineIdForTransactionDetail, updateSelectedVendor, updateSelectedCustomer, resetSelectedCustomer, resetVendor, updateLocalDataWithTransactionsUpdateWithVendorCheckbox, updateVendorToAllLineItems, resetAllLineItemsToVendor, updateLatestSelectedEntity, updateVendorBulkRecommendationsFetchStatus, setIsVendorUpdateAllChecked, addSplitLine, deleteSplitLine, toggleSplitEditMode, };
558
561
  export { downloadAccountingProviderAttachment, downloadAccountingProviderAttachmentSuccess, downloadAccountingProviderAttachmentFailure, fetchTransactionDetail, updateTransactionDetail, uploadMissingAttachmentSuccess, deleteTransactionAttachment, getThirdPartyIdFromTransactionId, };
559
562
  export { getTransactionListByEntity };
560
563
  export { getTransactionListByClass, getTransactionListUIStateByClassKey, getTransactionListByProject, getTransactionListUIStateByProjectKey, getTransactionListByEntityForSinglePeriod, };
@@ -663,7 +666,7 @@ export { TIME_SERIES_DURATIONS, convertToTimeSeriesSelectionRange, toTimeSeriesD
663
666
  export { fetchApAging, getApAgingReport, updateApAgingUIState, };
664
667
  export { fetchApAgingDetail, getApAgingDetailForVendor, updateApAgingDetailUIState, };
665
668
  export { clearExpenseAutomationJEScheduleLocalData, clearExpenseAutomationJESchedulesView, clearJeSearchTransactionsForNewSchedule, fetchExpenseAutomationJESchedulesPage, ignoreExpenseAutomationJESchedule, initializeJeAccountSettingsView, initializeJeNewSchedule, initializeJeScheduleLocalData, removeJeScheduleTransactionKey, resetJeNewScheduleLocalData, retryExpenseAutomationJESchedule, saveJeNewSchedule, saveJeNewScheduleFailure, saveJeNewScheduleSuccess, searchJeTransactionsForNewSchedule, searchJeTransactionsForNewScheduleFailure, searchJeTransactionsForNewScheduleSuccess, updateExpenseAutomationJESchedulesUIState, updateJeNewScheduleLocalData, removeJeOneTimeAccrualLocalData, updateJeOneTimeAccrualLocalData, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys, };
666
- export { ackCloseMatchAfterIgnore, ackCloseMatchAfterUndo, clearExpenseAutomationActualMatchingView, closeMatchNewModal, clearMatchNewModal, fetchExpenseAutomationActualMatching, fetchActualMatchingMatch, fetchExpenseAutomationActualMatchingPage, ignoreActualMatchingSuggestion, matchAndReverseAccruals, openMatchNewModal, searchMatchAccruals, searchMatchTransactions, undoReversalAccruals, updateExpenseAutomationActualMatchingUIState, };
669
+ export { ackCloseMatchAfterUndo, clearExpenseAutomationActualMatchingView, closeMatchNewModal, clearMatchNewModal, fetchExpenseAutomationActualMatching, fetchActualMatchingMatch, fetchExpenseAutomationActualMatchingPage, matchAndReverseAccruals, openMatchNewModal, searchMatchAccruals, searchMatchTransactions, undoReversalAccruals, updateExpenseAutomationActualMatchingUIState, };
667
670
  export { createNewSchedulesAccrued, deleteScheduleAccruedDetail, cancelScheduleAccruedJournalEntry, fetchScheduleAccruedDetails, fetchScheduleAccruedDetailsPage, resetJEAccruedLinkInLocalData, saveScheduleAccruedDetails, updateAmountsInScheduleAccruedDetail, updatedJEAccruedLinkWithRecommendedLocalData, updatedJELinkInLocalDataAccruedExpenses, fetchRecommendedTransactionRowIndex, clearSelectedJELinkRowIndex, updateLinkBillExpenseLocalData, updateScheduleAccruedDetailsLocalData, updateSelectedJEAccruedScheduleKey, resetSelectedJEAccruedScheduleKey, resetAccruedDetailNewScheduleState, };
668
671
  export { getJEScheduleTransactionKey, ALL_JE_SCHEDULE_IGNORE_REASONS, ALL_JE_SCHEDULE_REVERT_REASONS, ALL_ONE_TIME_ACCRUAL_IGNORE_REASONS, ALL_ONE_TIME_ACCRUAL_REVERT_REASONS, ALL_SCHEDULES_TYPES, getScheduleListReport, getAccruedScheduleListReport, fetchScheduleList, fetchAccruedScheduleList, fetchDownloadSchedules, fetchSchedulesAccount, updateScheduleListLocalData, getFetchStateForScheduleAccountList, toScheduleTypesType, toScheduleTypesTypeStrict, toScheduleListTabsFileTypeStrict, toScheduleSubTabType, updateScheduleListSubTab, updateScheduleListSearchText, updateScheduleListScrollState, updateScheduleListSortState, updateSelectedJEScheduleKey, fetchScheduleDetails, getScheduleDetailsView, getAccruedScheduleDetailsView, fetchScheduleDetailsPage, saveScheduleDetails, deleteScheduleDetail, createNewSchedules, updateScheduleDetailsLocalData, updateScheduleListDownloadState, updateAccruedJEScheduleAccruedByListKey, updatedSelectedJELinkRowIndex, getQBOUrlForLink, getThirdPartyIDFromQBOURL, updatedJELinkInLocalData, updateAmountsInScheduleDetail, resetJELinkInLocalData, updatedJELinkWithRecommendedLocalData, getFetchStateForScheduleListByType, getDefaultSelectedTimeframeForScheduleType, markAsCompleteScheduleDetail, resetMarkAsCompleteStatus, fetchVendorTabView, updateVendorTabViewTab, getVendorTabView, };
669
672
  export { toVendorFirstReviewViewColumnKeyType, getGlobalMerchantAutoCompleteResults, getVendorFirstReviewView, getVendorFirstReviewAttachmentView, fetchVendorFirstReviewView, fetchVendorFirstReviewAttachments, updateVendorFirstReviewViewScrollYOffset, resetVendorFirstReviewLocalData, updateVendorFirstReviewViewPageToken, clearRecentlySavedErroredVendorData, saveVendorFirstReviewView, updateVendorFirstReviewViewLocalData, updateVendorFirstReviewSortUiState, fetchGlobalMerchantAutoCompleteView, clearGlobalMerchantAutoCompleteResults, updateReviewVendorDetailLocalData, saveVendorDetailsView, getVendorDetailSelectorView, };
@@ -867,4 +870,4 @@ export { getInvoicingOnboardingGateView } from './view/invoicing/invoicingConfig
867
870
  // Accrued JE schedules are not a discriminated union member, so consumers need this guard to
868
871
  // narrow a JEScheduleRow before reading baseTransaction / recurringAmount.
869
872
  export { getExpenseAutomationJEOneTimeAccrualDetailView, getJEScheduleRowType, isAccruedScheduleRow, isAiAccountantSchedule, isExistingTabRow, isOneTimeAccrualRow, isRenderableOneTimeAccrual, isPendingReviewRow, } from './view/expenseAutomationView/selectors/jeSchedulesViewSelector';
870
- export { getActualMatchingAmount, getActualMatchingReversalDate, getActualMatchingMatchModalConfirmStatus, getCloseMatchAfterIgnoreMatchId, getCloseMatchAfterUndo, getCloseMatchAfterUndoMatchId, parseActualMatchingMatchId, getExpenseAutomationActualMatchingMatchView, getExpenseAutomationActualMatchingView, isAutoReversedAccrual, isManuallyReversedAccrual, isPendingReviewAccrual, } from './view/expenseAutomationView/selectors/actualMatchingViewSelector';
873
+ export { getActualMatchingAmount, getActualMatchingReversalDate, getCloseMatchAfterUndo, parseActualMatchingMatchId, getExpenseAutomationActualMatchingMatchView, getExpenseAutomationActualMatchingView, isAutoReversedAccrual, isManuallyReversedAccrual, isPendingReviewAccrual, } from './view/expenseAutomationView/selectors/actualMatchingViewSelector';
@@ -87,8 +87,8 @@ exhaustMap((action) => {
87
87
  results.every((result) => isMatchAndReverseCompleteStatus(result.status));
88
88
  if (occupancyChanged) {
89
89
  // List + detail: list can omit leftovers; detail GET always
90
- // writes intended occupancy so leftover retry can join C
91
- // onto the occupied bill instead of a stale cached row.
90
+ // writes intended occupancy so Continue match prefills the
91
+ // remaining leftover set instead of a stale cached row.
92
92
  successActions.push(...refreshActualMatchingList(state$.value), fetchActualMatchingMatch(matchId, true));
93
93
  }
94
94
  const snackbar = matchAndReverseSnackbar(results, vendorName);
@@ -100,12 +100,8 @@ exhaustMap((action) => {
100
100
  }
101
101
  return from(successActions);
102
102
  }
103
- return of(matchAndReverseAccrualsFailure({
104
- status: response.status,
105
- matchId,
106
- }), matchAndReverseHttpFailSnackbar(vendorName));
103
+ return of(matchAndReverseAccrualsFailure({ status: response.status }), matchAndReverseHttpFailSnackbar(vendorName));
107
104
  }), catchError((error) => of(matchAndReverseAccrualsFailure({
108
- matchId,
109
105
  status: createZeniAPIStatus('Unexpected Error', 'Match and reverse accruals REST API call errored out' +
110
106
  JSON.stringify(error)),
111
107
  }), matchAndReverseHttpFailSnackbar(vendorName))), takeUntil(actions$.pipe(filter(clearAll.match))));
@@ -1,13 +1,34 @@
1
1
  import { from, merge, of } from 'rxjs';
2
2
  import { catchError, debounceTime, filter, mergeMap, switchMap, takeUntil, } from 'rxjs/operators';
3
+ import { getActualMatchingMatchById } from '../../../../../entity/actualMatching/actualMatchingSelector';
3
4
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
4
5
  import { clearAll } from '../../../../../rootActions';
5
6
  import { toActualMatchingTransactionSearchResult, } from '../../../payload/actualMatchingPayload';
6
7
  import { openMatchNewModal, searchMatchAccruals, searchMatchTransactions, searchMatchTransactionsFailure, searchMatchTransactionsSuccess, } from '../../../reducers/actualMatchingViewReducer';
7
- import { getTenantDisplayCurrency } from '../../../selectors/actualMatchingViewSelector';
8
+ import { getTenantDisplayCurrency, parseActualMatchingMatchId, } from '../../../selectors/actualMatchingViewSelector';
8
9
  import { MATCH_SEARCH_DEBOUNCE_MS, MATCH_TRANSACTION_SEARCH_PAGE_SIZE, } from '../../../types/actualMatchingViewState';
9
10
  export const searchMatchTransactionsEpic = (actions$, state$, zeniAPI) => {
10
- const openModal$ = actions$.pipe(filter(openMatchNewModal.match), mergeMap(() => from([searchMatchTransactions(''), searchMatchAccruals('')])));
11
+ const openModal$ = actions$.pipe(filter(openMatchNewModal.match), mergeMap((action) => {
12
+ const matchId = action.payload.matchId;
13
+ if (matchId == null || matchId === '') {
14
+ return from([
15
+ searchMatchTransactions(''),
16
+ searchMatchAccruals(''),
17
+ ]);
18
+ }
19
+ const match = getActualMatchingMatchById(state$.value.actualMatchingState, matchId);
20
+ const parsed = parseActualMatchingMatchId(matchId);
21
+ const transactionType = match?.transactionType != null && match.transactionType !== ''
22
+ ? match.transactionType
23
+ : parsed?.transactionType;
24
+ const transactionIntegrationId = match?.transactionIntegrationId != null &&
25
+ match.transactionIntegrationId !== ''
26
+ ? match.transactionIntegrationId
27
+ : parsed?.transactionIntegrationId;
28
+ return from([
29
+ searchMatchTransactions('', undefined, transactionType, transactionIntegrationId),
30
+ ]);
31
+ }));
11
32
  const searchActions$ = actions$.pipe(filter(searchMatchTransactions.match));
12
33
  const pagination$ = searchActions$.pipe(filter((action) => action.payload.pageToken != null));
13
34
  const newSearchDebounced$ = searchActions$.pipe(filter((action) => action.payload.pageToken == null), debounceTime(MATCH_SEARCH_DEBOUNCE_MS));
@@ -22,6 +22,9 @@ export const initialAccrualSearchState = {
22
22
  };
23
23
  export const initialMatchModalState = {
24
24
  isOpen: false,
25
+ openedFromMatchId: undefined,
26
+ didPinPrefillTransactions: false,
27
+ pinnedTransactionResults: [],
25
28
  transactionSearch: initialTransactionSearchState,
26
29
  accrualSearch: initialAccrualSearchState,
27
30
  confirmStatus: { fetchState: 'Not-Started', error: undefined },
@@ -41,14 +44,10 @@ export const initialState = {
41
44
  sortOrder: 'descending',
42
45
  searchString: '',
43
46
  scrollPosition: { scrollTop: 0, scrollLeft: undefined },
44
- statusFilter: 'all',
45
47
  },
46
48
  matchModal: initialMatchModalState,
47
49
  undoReversalStatusByMatchId: {},
48
- ignoreStatusByMatchId: {},
49
- confirmStatusByMatchId: {},
50
- closeMatchAfterUndoMatchId: undefined,
51
- closeMatchAfterIgnoreMatchId: undefined,
50
+ closeMatchAfterUndo: false,
52
51
  lastMatchResultsByMatchId: {},
53
52
  lastUndoResultsByMatchId: {},
54
53
  hasValidState() {
@@ -97,6 +96,9 @@ function resetMatchModalSearches(draft) {
97
96
  error: undefined,
98
97
  };
99
98
  draft.matchModal.lastBatchResults = undefined;
99
+ draft.matchModal.openedFromMatchId = undefined;
100
+ draft.matchModal.didPinPrefillTransactions = false;
101
+ draft.matchModal.pinnedTransactionResults = [];
100
102
  }
101
103
  const expenseAutomationActualMatchingView = createSlice({
102
104
  name: 'expenseAutomationActualMatchingView',
@@ -237,13 +239,21 @@ const expenseAutomationActualMatchingView = createSlice({
237
239
  if (action.payload.scrollPosition != null) {
238
240
  draft.uiState.scrollPosition = action.payload.scrollPosition;
239
241
  }
240
- if (action.payload.statusFilter != null) {
241
- draft.uiState.statusFilter = action.payload.statusFilter;
242
- }
243
242
  },
244
- openMatchNewModal(draft) {
245
- resetMatchModalSearches(draft);
246
- draft.matchModal.isOpen = true;
243
+ openMatchNewModal: {
244
+ prepare(matchId) {
245
+ return { payload: { matchId } };
246
+ },
247
+ reducer(draft, action) {
248
+ resetMatchModalSearches(draft);
249
+ draft.matchModal.isOpen = true;
250
+ const matchId = action.payload.matchId;
251
+ draft.matchModal.openedFromMatchId =
252
+ matchId != null && matchId !== '' ? matchId : undefined;
253
+ if (draft.matchModal.openedFromMatchId != null) {
254
+ draft.matchModal.accrualSearch.fetchState = 'Completed';
255
+ }
256
+ },
247
257
  },
248
258
  // Dismiss (Cancel / overlay). Store reset matches `clearMatchNewModal`;
249
259
  // the actions stay distinct so confirm-success vs user-dismiss stay observable.
@@ -298,6 +308,11 @@ const expenseAutomationActualMatchingView = createSlice({
298
308
  }
299
309
  else {
300
310
  draft.matchModal.transactionSearch.results = results;
311
+ if (draft.matchModal.openedFromMatchId != null &&
312
+ !draft.matchModal.didPinPrefillTransactions) {
313
+ draft.matchModal.didPinPrefillTransactions = true;
314
+ draft.matchModal.pinnedTransactionResults = results;
315
+ }
301
316
  }
302
317
  draft.matchModal.transactionSearch.nextPageToken = nextPageToken;
303
318
  draft.matchModal.transactionSearch.isLoadingMore = false;
@@ -350,24 +365,21 @@ const expenseAutomationActualMatchingView = createSlice({
350
365
  draft.matchModal.accrualSearch.error = action.payload.error;
351
366
  },
352
367
  matchAndReverseAccruals: {
353
- reducer(draft, action) {
354
- const inProgress = {
368
+ reducer(draft) {
369
+ draft.matchModal.confirmStatus = {
355
370
  fetchState: 'In-Progress',
356
371
  error: undefined,
357
372
  };
358
- draft.matchModal.confirmStatus = inProgress;
359
- const matchId = `${action.payload.transactionType.toLowerCase()}:${action.payload.transactionIntegrationId}`;
360
- draft.confirmStatusByMatchId[matchId] = inProgress;
361
373
  },
362
374
  prepare(transactionId, transactionIntegrationId, transactionType, lineIds, transactionSyncToken, accrualIds) {
363
375
  return {
364
376
  payload: {
365
- accrualIds,
366
- lineIds,
367
377
  transactionId,
368
378
  transactionIntegrationId,
369
- transactionSyncToken,
370
379
  transactionType,
380
+ lineIds,
381
+ transactionSyncToken,
382
+ accrualIds,
371
383
  },
372
384
  };
373
385
  },
@@ -384,21 +396,15 @@ const expenseAutomationActualMatchingView = createSlice({
384
396
  };
385
397
  draft.matchModal.lastBatchResults = results;
386
398
  if (action.payload.matchId != null) {
387
- draft.confirmStatusByMatchId[action.payload.matchId] =
388
- draft.matchModal.confirmStatus;
389
399
  draft.lastMatchResultsByMatchId[action.payload.matchId] = results;
390
400
  pruneLastUndoResultsForMatched(draft, action.payload.matchId, action.payload.results);
391
401
  }
392
402
  },
393
403
  matchAndReverseAccrualsFailure(draft, action) {
394
- const failed = {
404
+ draft.matchModal.confirmStatus = {
395
405
  fetchState: 'Error',
396
406
  error: action.payload.status,
397
407
  };
398
- draft.matchModal.confirmStatus = failed;
399
- if (action.payload.matchId != null) {
400
- draft.confirmStatusByMatchId[action.payload.matchId] = failed;
401
- }
402
408
  },
403
409
  undoReversalAccruals: {
404
410
  reducer(draft, action) {
@@ -420,7 +426,7 @@ const expenseAutomationActualMatchingView = createSlice({
420
426
  };
421
427
  const allUndone = results.length > 0 &&
422
428
  results.every((result) => result.status === 'undone');
423
- draft.closeMatchAfterUndoMatchId = allUndone ? matchId : undefined;
429
+ draft.closeMatchAfterUndo = allUndone;
424
430
  pruneLastMatchResultsForUndone(draft, matchId, results);
425
431
  if (allUndone) {
426
432
  delete draft.lastUndoResultsByMatchId[matchId];
@@ -434,44 +440,7 @@ const expenseAutomationActualMatchingView = createSlice({
434
440
  },
435
441
  },
436
442
  ackCloseMatchAfterUndo(draft) {
437
- draft.closeMatchAfterUndoMatchId = undefined;
438
- },
439
- ignoreActualMatchingSuggestion: {
440
- prepare(matchId, reason, note) {
441
- return { payload: { matchId, reason, note } };
442
- },
443
- reducer(draft, action) {
444
- draft.ignoreStatusByMatchId[action.payload.matchId] = {
445
- fetchState: 'In-Progress',
446
- error: undefined,
447
- };
448
- },
449
- },
450
- ignoreActualMatchingSuggestionSuccess(draft, action) {
451
- const { matchId } = action.payload;
452
- draft.ignoreStatusByMatchId[matchId] = {
453
- fetchState: 'Completed',
454
- error: undefined,
455
- };
456
- draft.closeMatchAfterIgnoreMatchId = matchId;
457
- delete draft.lastMatchResultsByMatchId[matchId];
458
- delete draft.lastUndoResultsByMatchId[matchId];
459
- delete draft.detailFetchStateByMatchId[matchId];
460
- delete draft.detailRefreshStatusByMatchId[matchId];
461
- delete draft.undoReversalStatusByMatchId[matchId];
462
- delete draft.confirmStatusByMatchId[matchId];
463
- Object.keys(draft.matchIdsByPeriod).forEach((periodId) => {
464
- draft.matchIdsByPeriod[periodId] = draft.matchIdsByPeriod[periodId].filter((id) => id !== matchId);
465
- });
466
- },
467
- ignoreActualMatchingSuggestionFailure(draft, action) {
468
- draft.ignoreStatusByMatchId[action.payload.matchId] = {
469
- fetchState: 'Error',
470
- error: action.payload.status,
471
- };
472
- },
473
- ackCloseMatchAfterIgnore(draft) {
474
- draft.closeMatchAfterIgnoreMatchId = undefined;
443
+ draft.closeMatchAfterUndo = false;
475
444
  },
476
445
  undoReversalAccrualsFailure(draft, action) {
477
446
  draft.undoReversalStatusByMatchId[action.payload.matchId] = {
@@ -489,5 +458,5 @@ const expenseAutomationActualMatchingView = createSlice({
489
458
  });
490
459
  },
491
460
  });
492
- export const { ackCloseMatchAfterIgnore, ackCloseMatchAfterUndo, clearActualMatchingView, clearMatchNewModal, closeMatchNewModal, fetchActualMatching, fetchActualMatchingFailure, fetchActualMatchingMatch, fetchActualMatchingMatchFailure, fetchActualMatchingMatchSuccess, fetchActualMatchingPage, fetchActualMatchingSuccess, ignoreActualMatchingSuggestion, ignoreActualMatchingSuggestionFailure, ignoreActualMatchingSuggestionSuccess, matchAndReverseAccruals, matchAndReverseAccrualsFailure, matchAndReverseAccrualsSuccess, openMatchNewModal, searchMatchAccruals, searchMatchAccrualsFailure, searchMatchAccrualsSuccess, searchMatchTransactions, searchMatchTransactionsFailure, searchMatchTransactionsSuccess, undoReversalAccruals, undoReversalAccrualsFailure, undoReversalAccrualsSuccess, updateActualMatchingUIState, } = expenseAutomationActualMatchingView.actions;
461
+ export const { ackCloseMatchAfterUndo, clearActualMatchingView, clearMatchNewModal, closeMatchNewModal, fetchActualMatching, fetchActualMatchingFailure, fetchActualMatchingMatch, fetchActualMatchingMatchFailure, fetchActualMatchingMatchSuccess, fetchActualMatchingPage, fetchActualMatchingSuccess, matchAndReverseAccruals, matchAndReverseAccrualsFailure, matchAndReverseAccrualsSuccess, openMatchNewModal, searchMatchAccruals, searchMatchAccrualsFailure, searchMatchAccrualsSuccess, searchMatchTransactions, searchMatchTransactionsFailure, searchMatchTransactionsSuccess, undoReversalAccruals, undoReversalAccrualsFailure, undoReversalAccrualsSuccess, updateActualMatchingUIState, } = expenseAutomationActualMatchingView.actions;
493
462
  export default expenseAutomationActualMatchingView.reducer;
@@ -1,11 +1,11 @@
1
1
  import orderBy from 'lodash/orderBy';
2
- import { createSelector } from '@reduxjs/toolkit';
3
2
  import { toMonthYearPeriodId, } from '../../../commonStateTypes/timePeriod';
4
3
  import { getActualMatchingMatchById } from '../../../entity/actualMatching/actualMatchingSelector';
5
4
  import { generateJEOneTimeAccrualKey } from '../../../entity/jeSchedules/jeScheduleHelper';
6
5
  import { getJEOneTimeAccrualByKey, } from '../../../entity/jeSchedules/jeSchedulesSelector';
7
6
  import { getCurrentTenant } from '../../../entity/tenant/tenantSelector';
8
7
  import { date } from '../../../zeniDayJS';
8
+ import { actualMatchingTransactionLineKey, } from '../types/actualMatchingViewState';
9
9
  export function getSelectedMonthYearForCurrentTenant(state) {
10
10
  const tenantId = getCurrentTenant(state)?.tenantId;
11
11
  if (tenantId == null) {
@@ -34,6 +34,27 @@ function toMatchModalAccrual(member) {
34
34
  jeOneTimeAccrualKey: generateJEOneTimeAccrualKey(member.accrualId),
35
35
  };
36
36
  }
37
+ function uniqueMatchModalAccruals(pinned, searched) {
38
+ const byId = new Map();
39
+ pinned.forEach((row) => byId.set(row.accrualId, row));
40
+ searched.forEach((row) => {
41
+ if (!byId.has(row.accrualId)) {
42
+ byId.set(row.accrualId, row);
43
+ }
44
+ });
45
+ return Array.from(byId.values());
46
+ }
47
+ function uniqueTransactionSearchResults(pinned, searched) {
48
+ const byKey = new Map();
49
+ pinned.forEach((row) => byKey.set(actualMatchingTransactionLineKey(row.transactionType, row.transactionIntegrationId, row.lineId), row));
50
+ searched.forEach((row) => {
51
+ const key = actualMatchingTransactionLineKey(row.transactionType, row.transactionIntegrationId, row.lineId);
52
+ if (!byKey.has(key)) {
53
+ byKey.set(key, row);
54
+ }
55
+ });
56
+ return Array.from(byKey.values());
57
+ }
37
58
  export function parseActualMatchingMatchId(matchId) {
38
59
  const separator = matchId.indexOf(':');
39
60
  if (separator <= 0 || separator === matchId.length - 1) {
@@ -206,7 +227,6 @@ function emptyKpiSummary() {
206
227
  actualsReceived: { count: 0, expectedCount: 0, vendorsPending: 0 },
207
228
  autoReversed: { count: 0, percent: 0, clearedAmount: 0 },
208
229
  pendingReview: { count: 0, amount: 0, estimatedMinutesToClear: 0 },
209
- reversed: { count: 0 },
210
230
  variance: { percent: 0, averagePercentPerMatch: 0, netAmount: 0 },
211
231
  };
212
232
  }
@@ -262,7 +282,6 @@ export function buildActualMatchingKpiSummary(rows, displayCurrencyCode) {
262
282
  }
263
283
  const autoReversed = kpiRows.filter((row) => row.kind === 'auto_reversed');
264
284
  const pendingReview = kpiRows.filter((row) => row.kind === 'pending_review');
265
- const reversed = kpiRows.filter((row) => isReversedMatchKind(row.kind));
266
285
  const receivedCount = kpiRows.length;
267
286
  const rowsWithActual = kpiRows.filter((row) => row.actualAmount?.amount != null);
268
287
  const accruedTotal = rowsWithActual.reduce((sum, row) => sum + (row.accruedAmount?.amount ?? row.estimatedAmount.amount), 0);
@@ -288,9 +307,6 @@ export function buildActualMatchingKpiSummary(rows, displayCurrencyCode) {
288
307
  amount: sumRowAmounts(pendingReview, displayCurrencyCode),
289
308
  estimatedMinutesToClear: pendingReview.length * ESTIMATED_MINUTES_PER_PENDING_MATCH,
290
309
  },
291
- reversed: {
292
- count: reversed.length,
293
- },
294
310
  variance: {
295
311
  percent: accruedTotal === 0
296
312
  ? 0
@@ -303,55 +319,23 @@ export function buildActualMatchingKpiSummary(rows, displayCurrencyCode) {
303
319
  },
304
320
  };
305
321
  }
306
- function toActualMatchingMatchView(match) {
322
+ export function getExpenseAutomationActualMatchingMatchView(state, matchId) {
323
+ const view = state.expenseAutomationActualMatchingViewState;
307
324
  return {
308
- ...match,
309
- members: match.members.map(toMatchModalAccrual),
310
- leftovers: match.leftovers == null
311
- ? undefined
312
- : match.leftovers.map(toMatchModalAccrual),
325
+ match: getActualMatchingMatchById(state.actualMatchingState, matchId),
326
+ detailFetchState: view.detailFetchStateByMatchId[matchId] ?? NOT_STARTED,
327
+ refreshStatus: view.detailRefreshStatusByMatchId[matchId] ?? NOT_STARTED,
328
+ undoReversalStatus: view.undoReversalStatusByMatchId[matchId] ?? NOT_STARTED,
329
+ lastMatchResults: view.lastMatchResultsByMatchId?.[matchId],
330
+ lastUndoResults: view.lastUndoResultsByMatchId?.[matchId],
313
331
  };
314
332
  }
315
- const EMPTY_ACTUAL_MATCHING_ROWS = [];
316
- const matchViewSelectorById = new Map();
317
- export function getExpenseAutomationActualMatchingMatchView(state, matchId) {
318
- let selector = matchViewSelectorById.get(matchId);
319
- if (selector == null) {
320
- selector = createSelector([
321
- (root) => root.expenseAutomationActualMatchingViewState,
322
- (root) => getActualMatchingMatchById(root.actualMatchingState, matchId),
323
- ], (view, match) => ({
324
- detailFetchState: view.detailFetchStateByMatchId[matchId] ?? NOT_STARTED,
325
- ignoreStatus: view.ignoreStatusByMatchId[matchId] ?? NOT_STARTED,
326
- lastMatchResults: view.lastMatchResultsByMatchId?.[matchId],
327
- lastUndoResults: view.lastUndoResultsByMatchId?.[matchId],
328
- match: match == null ? undefined : toActualMatchingMatchView(match),
329
- refreshStatus: view.detailRefreshStatusByMatchId[matchId] ?? NOT_STARTED,
330
- undoReversalStatus: view.undoReversalStatusByMatchId[matchId] ?? NOT_STARTED,
331
- }));
332
- matchViewSelectorById.set(matchId, selector);
333
- }
334
- return selector(state);
335
- }
336
333
  export function getCloseMatchAfterUndo(state) {
337
- return state.expenseAutomationActualMatchingViewState.closeMatchAfterUndoMatchId;
338
- }
339
- export function getCloseMatchAfterUndoMatchId(state) {
340
- return getCloseMatchAfterUndo(state);
341
- }
342
- export function getCloseMatchAfterIgnoreMatchId(state) {
343
- return state.expenseAutomationActualMatchingViewState
344
- .closeMatchAfterIgnoreMatchId;
345
- }
346
- export function getActualMatchingMatchModalConfirmStatus(state, matchId) {
347
- if (matchId != null && matchId !== '') {
348
- return (state.expenseAutomationActualMatchingViewState.confirmStatusByMatchId[matchId] ?? NOT_STARTED);
349
- }
350
- return state.expenseAutomationActualMatchingViewState.matchModal.confirmStatus;
334
+ return state.expenseAutomationActualMatchingViewState.closeMatchAfterUndo;
351
335
  }
352
336
  export function getExpenseAutomationActualMatchingView(state) {
353
337
  const { expenseAutomationActualMatchingViewState } = state;
354
- const { matchIdsByPeriod, fetchState, error, refreshStatus, uiState, matchModal, ignoreStatusByMatchId, undoReversalStatusByMatchId, } = expenseAutomationActualMatchingViewState;
338
+ const { matchIdsByPeriod, fetchState, error, refreshStatus, uiState, matchModal, } = expenseAutomationActualMatchingViewState;
355
339
  const selectedPeriod = getSelectedMonthYearForCurrentTenant(state);
356
340
  const monthYearPeriodId = selectedPeriod != null ? toMonthYearPeriodId(selectedPeriod) : undefined;
357
341
  const matchIds = monthYearPeriodId != null ? matchIdsByPeriod[monthYearPeriodId] : undefined;
@@ -361,18 +345,38 @@ export function getExpenseAutomationActualMatchingView(state) {
361
345
  .filter((match) => match.members.length > 0)
362
346
  .map(toActualMatchingRow);
363
347
  const rows = allRows.filter((row) => matchesSearch(row, uiState.searchString));
364
- const includePendingReview = uiState.statusFilter !== 'reversed';
365
- const includeReversed = uiState.statusFilter !== 'pending_review';
366
- const reversed = includeReversed
367
- ? sortActualMatchingRows(rows.filter((row) => isReversedMatchKind(row.kind)), uiState)
368
- : EMPTY_ACTUAL_MATCHING_ROWS;
369
- const pendingReview = includePendingReview
370
- ? sortActualMatchingRows(rows.filter((row) => row.kind === 'pending_review'), uiState)
371
- : EMPTY_ACTUAL_MATCHING_ROWS;
348
+ const reversed = sortActualMatchingRows(rows.filter((row) => isReversedMatchKind(row.kind)), uiState);
349
+ const pendingReview = sortActualMatchingRows(rows.filter((row) => row.kind === 'pending_review'), uiState);
372
350
  const kpiSummary = buildActualMatchingKpiSummary(allRows, getTenantDisplayCurrency(state)?.currencyCode);
373
351
  const searchedAccruals = matchModal.accrualSearch.results
374
352
  .map((key) => getJEOneTimeAccrualByKey(key, state.jeSchedulesState))
375
353
  .filter((accrual) => accrual != null);
354
+ const openedMatch = matchModal.openedFromMatchId != null
355
+ ? getActualMatchingMatchById(state.actualMatchingState, matchModal.openedFromMatchId)
356
+ : undefined;
357
+ const pinnedAccruals = [
358
+ ...(openedMatch?.members ?? []),
359
+ ...(openedMatch?.leftovers ?? []),
360
+ ].map(toMatchModalAccrual);
361
+ const firstMember = openedMatch?.members[0];
362
+ const cleared = firstMember?.cleared;
363
+ const suggestion = firstMember?.matchSuggestion;
364
+ const stamp = cleared ?? suggestion;
365
+ const consumedLineIds = cleared?.consumedLineIds;
366
+ const prefill = openedMatch == null
367
+ ? undefined
368
+ : {
369
+ selectedAccrualIds: [
370
+ ...openedMatch.members.map((member) => member.accrualId),
371
+ ...(openedMatch.leftovers ?? []).map((leftover) => leftover.accrualId),
372
+ ],
373
+ actualAmount: openedMatch.actualAmount.amount,
374
+ matchedTransactionId: stamp?.matchedTransactionId,
375
+ matchedLineId: cleared == null ? suggestion?.matchedLineId : undefined,
376
+ ...(consumedLineIds != null && consumedLineIds.length > 0
377
+ ? { consumedLineIds }
378
+ : {}),
379
+ };
376
380
  // `fetchState` is a flat slice field that survives a period switch. Until this
377
381
  // month's ids land, leftover Completed/Error is the previous month. Report
378
382
  // Not-Started so chrome matches Review's "cache slot missing" skeleton, not
@@ -390,16 +394,16 @@ export function getExpenseAutomationActualMatchingView(state) {
390
394
  kpiSummary,
391
395
  uiState,
392
396
  refreshStatus,
393
- ignoreStatusByMatchId,
394
- undoReversalStatusByMatchId,
395
397
  hasLoadedForSelectedPeriod: matchIds != null,
396
398
  matchModal: {
397
399
  isOpen: matchModal.isOpen,
400
+ openedFromMatchId: matchModal.openedFromMatchId,
401
+ prefill,
398
402
  confirmStatus: matchModal.confirmStatus,
399
403
  lastBatchResults: matchModal.lastBatchResults,
400
404
  transactionSearch: {
401
405
  query: matchModal.transactionSearch.query,
402
- results: matchModal.transactionSearch.results,
406
+ results: uniqueTransactionSearchResults(matchModal.pinnedTransactionResults, matchModal.transactionSearch.results),
403
407
  fetchState: {
404
408
  fetchState: matchModal.transactionSearch.fetchState,
405
409
  error: matchModal.transactionSearch.error,
@@ -409,7 +413,7 @@ export function getExpenseAutomationActualMatchingView(state) {
409
413
  },
410
414
  accrualSearch: {
411
415
  query: matchModal.accrualSearch.query,
412
- results: searchedAccruals,
416
+ results: uniqueMatchModalAccruals(pinnedAccruals, searchedAccruals),
413
417
  fetchState: {
414
418
  fetchState: matchModal.accrualSearch.fetchState,
415
419
  error: matchModal.accrualSearch.error,
@@ -13,12 +13,6 @@ const ACTUAL_MATCHING_SORT_KEYS = [
13
13
  'variance',
14
14
  ];
15
15
  export const toActualMatchingSortKey = (v) => stringToUnion(v, ACTUAL_MATCHING_SORT_KEYS);
16
- const ACTUAL_MATCHING_STATUS_FILTERS = [
17
- 'all',
18
- 'pending_review',
19
- 'reversed',
20
- ];
21
- export const toActualMatchingStatusFilter = (v) => stringToUnion(v, ACTUAL_MATCHING_STATUS_FILTERS);
22
16
  export const MATCH_TRANSACTION_SEARCH_PAGE_SIZE = 50;
23
17
  export const MATCH_ACCRUAL_SEARCH_LIMIT = 50;
24
18
  export const MATCH_SEARCH_DEBOUNCE_MS = 300;
@@ -39,15 +33,6 @@ const UNDO_REVERSAL_RESULT_STATUSES = [
39
33
  'error',
40
34
  ];
41
35
  export const toUndoReversalResultStatus = (v) => stringToUnion(v, UNDO_REVERSAL_RESULT_STATUSES);
42
- const ACTUAL_MATCHING_IGNORE_REASONS = [
43
- 'wrong_bill',
44
- 'wrong_period',
45
- 'amount_off',
46
- 'already_handled',
47
- 'other_ignore',
48
- ];
49
- export const toActualMatchingIgnoreReasonType = (v) => stringToUnion(v, ACTUAL_MATCHING_IGNORE_REASONS);
50
- export const ALL_ACTUAL_MATCHING_IGNORE_REASONS = ACTUAL_MATCHING_IGNORE_REASONS;
51
36
  export function actualMatchingTransactionLineKey(transactionType, transactionIntegrationId, lineId) {
52
37
  return `${transactionType}:${transactionIntegrationId}:${lineId}`;
53
38
  }