@zeniai/client-epic-state 5.2.22-betaAK1 → 5.2.22-betaAM2

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 (120) hide show
  1. package/lib/entity/invoicing/creditNote/creditNotePayload.d.ts +1 -0
  2. package/lib/entity/invoicing/creditNote/creditNotePayload.js +1 -0
  3. package/lib/entity/invoicing/creditNote/creditNoteState.d.ts +1 -0
  4. package/lib/entity/invoicing/invoice/invoicePayload.d.ts +1 -0
  5. package/lib/entity/invoicing/invoice/invoicePayload.js +1 -0
  6. package/lib/entity/invoicing/invoice/invoiceState.d.ts +1 -0
  7. package/lib/entity/invoicing/invoicingCommonPayload.d.ts +0 -2
  8. package/lib/entity/invoicing/invoicingCustomer/invoicingCustomerPayload.d.ts +1 -0
  9. package/lib/entity/invoicing/invoicingCustomer/invoicingCustomerPayload.js +1 -0
  10. package/lib/entity/invoicing/invoicingCustomer/invoicingCustomerState.d.ts +1 -0
  11. package/lib/entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload.d.ts +2 -1
  12. package/lib/entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload.js +2 -1
  13. package/lib/entity/invoicing/invoicingSubscription/invoicingSubscriptionState.d.ts +2 -1
  14. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +24 -0
  15. package/lib/entity/jeSchedules/jeSchedulesPayload.js +40 -0
  16. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +26 -0
  17. package/lib/epic.d.ts +6 -1
  18. package/lib/epic.js +10 -0
  19. package/lib/esm/entity/invoicing/creditNote/creditNotePayload.js +1 -0
  20. package/lib/esm/entity/invoicing/invoice/invoicePayload.js +1 -0
  21. package/lib/esm/entity/invoicing/invoicingCustomer/invoicingCustomerPayload.js +1 -0
  22. package/lib/esm/entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload.js +2 -1
  23. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +40 -0
  24. package/lib/esm/epic.js +10 -0
  25. package/lib/esm/index.js +6 -2
  26. package/lib/esm/reducer.js +3 -0
  27. package/lib/esm/view/expenseAutomationView/epics/accountRecon/deleteAccountStatementEpic.js +1 -3
  28. package/lib/esm/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingEpic.js +46 -0
  29. package/lib/esm/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingPageEpic.js +7 -0
  30. package/lib/esm/view/expenseAutomationView/epics/actualMatching/matchAndReverseAccrualsEpic.js +50 -0
  31. package/lib/esm/view/expenseAutomationView/epics/actualMatching/searchMatchAccrualsEpic.js +44 -0
  32. package/lib/esm/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.js +44 -0
  33. package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +28 -11
  34. package/lib/esm/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.js +9 -1
  35. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +5 -0
  36. package/lib/esm/view/expenseAutomationView/expenseAutomationViewSelector.js +22 -7
  37. package/lib/esm/view/expenseAutomationView/payload/actualMatchingPayload.js +60 -0
  38. package/lib/esm/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +260 -0
  39. package/lib/esm/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.js +1 -0
  40. package/lib/esm/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +196 -0
  41. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +3 -0
  42. package/lib/esm/view/expenseAutomationView/types/actualMatchingViewState.js +22 -0
  43. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +5 -1
  44. package/lib/esm/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.js +0 -2
  45. package/lib/esm/view/invoicing/invoicingOverview/invoicingOverviewPayload.js +1 -0
  46. package/lib/esm/view/invoicing/invoicingSubscriptionDetailView/invoicingSubscriptionDetailViewSelector.js +1 -2
  47. package/lib/esm/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewSelector.js +0 -1
  48. package/lib/esm/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewState.js +2 -0
  49. package/lib/esm/view/invoicing/settingsView/invoicingBrandingFormConfig.js +0 -5
  50. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPaySetupApproverViewEpic.js +18 -2
  51. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/initializeBillPaySetupApproverViewUpdateDataEpic.js +0 -1
  52. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.js +0 -3
  53. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/fetchRemiSetupApproverViewEpic.js +18 -2
  54. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/initializeRemiSetupApproverViewUpdateDataEpic.js +0 -1
  55. package/lib/index.d.ts +9 -5
  56. package/lib/index.js +73 -47
  57. package/lib/reducer.d.ts +1 -0
  58. package/lib/reducer.js +3 -0
  59. package/lib/rootStateTypes.d.ts +2 -0
  60. package/lib/view/expenseAutomationView/epics/accountRecon/deleteAccountStatementEpic.d.ts +1 -2
  61. package/lib/view/expenseAutomationView/epics/accountRecon/deleteAccountStatementEpic.js +1 -3
  62. package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingEpic.d.ts +9 -0
  63. package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingEpic.js +50 -0
  64. package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingPageEpic.d.ts +5 -0
  65. package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingPageEpic.js +11 -0
  66. package/lib/view/expenseAutomationView/epics/actualMatching/matchAndReverseAccrualsEpic.d.ts +8 -0
  67. package/lib/view/expenseAutomationView/epics/actualMatching/matchAndReverseAccrualsEpic.js +54 -0
  68. package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchAccrualsEpic.d.ts +8 -0
  69. package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchAccrualsEpic.js +48 -0
  70. package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.d.ts +8 -0
  71. package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.js +48 -0
  72. package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.d.ts +2 -1
  73. package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +28 -11
  74. package/lib/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.d.ts +2 -1
  75. package/lib/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.js +9 -1
  76. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.d.ts +2 -1
  77. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +5 -0
  78. package/lib/view/expenseAutomationView/expenseAutomationViewSelector.js +22 -7
  79. package/lib/view/expenseAutomationView/payload/actualMatchingPayload.d.ts +72 -0
  80. package/lib/view/expenseAutomationView/payload/actualMatchingPayload.js +65 -0
  81. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.d.ts +53 -0
  82. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +264 -0
  83. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +2 -2
  84. package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.d.ts +59 -0
  85. package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.js +2 -0
  86. package/lib/view/expenseAutomationView/selectorTypes/expenseAutomationViewSelectorTypes.d.ts +2 -0
  87. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.d.ts +11 -0
  88. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +208 -0
  89. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +3 -0
  90. package/lib/view/expenseAutomationView/types/actualMatchingViewState.d.ts +81 -0
  91. package/lib/view/expenseAutomationView/types/actualMatchingViewState.js +27 -0
  92. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +1 -1
  93. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +5 -1
  94. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewPayload.d.ts +0 -1
  95. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.d.ts +1 -1
  96. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.js +0 -2
  97. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewState.d.ts +0 -1
  98. package/lib/view/invoicing/invoicingOverview/invoicingOverviewPayload.d.ts +1 -0
  99. package/lib/view/invoicing/invoicingOverview/invoicingOverviewPayload.js +1 -0
  100. package/lib/view/invoicing/invoicingOverview/invoicingOverviewState.d.ts +1 -0
  101. package/lib/view/invoicing/invoicingSubscriptionDetailView/invoicingSubscriptionDetailViewSelector.d.ts +1 -3
  102. package/lib/view/invoicing/invoicingSubscriptionDetailView/invoicingSubscriptionDetailViewSelector.js +0 -1
  103. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewSelector.d.ts +0 -2
  104. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewSelector.js +0 -1
  105. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewState.d.ts +2 -2
  106. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewState.js +2 -0
  107. package/lib/view/invoicing/issueCreditNote/issueCreditNotePayload.d.ts +1 -0
  108. package/lib/view/invoicing/settingsView/invoicingBrandingFormConfig.d.ts +0 -1
  109. package/lib/view/invoicing/settingsView/invoicingBrandingFormConfig.js +0 -5
  110. package/lib/view/invoicing/subscriptionAction/subscriptionActionRequestPayload.d.ts +0 -8
  111. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPaySetupApproverViewEpic.d.ts +2 -1
  112. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPaySetupApproverViewEpic.js +18 -2
  113. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/initializeBillPaySetupApproverViewUpdateDataEpic.js +0 -1
  114. package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.d.ts +0 -1
  115. package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.js +0 -3
  116. package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonState.d.ts +0 -1
  117. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/fetchRemiSetupApproverViewEpic.d.ts +2 -1
  118. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/fetchRemiSetupApproverViewEpic.js +18 -2
  119. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/initializeRemiSetupApproverViewUpdateDataEpic.js +0 -1
  120. package/package.json +38 -71
package/lib/esm/index.js CHANGED
@@ -184,6 +184,7 @@ import { toExpenseAutomationViewType, } from './view/expenseAutomationView/expen
184
184
  import { computeNewScheduleJeDetails } from './view/expenseAutomationView/helpers/newScheduleLocalDataHelper';
185
185
  import { isReviewTransactionBankTransferType, isReviewTransactionBillPaymentType, isReviewTransactionCreditCardCreditType, isReviewTransactionCreditCardPaymentType, isReviewTransactionDepositType, isReviewTransactionExpenseType, } from './view/expenseAutomationView/helpers/reconciliationHelpers';
186
186
  import { MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, getLineItemsByTransactionIdsFromLocalData, isAnyItemWithUncategorizedExpenseAccount, } from './view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper';
187
+ import { clearActualMatchingView as clearExpenseAutomationActualMatchingView, clearMatchNewModal, closeMatchNewModal, fetchActualMatching as fetchExpenseAutomationActualMatching, fetchActualMatchingPage as fetchExpenseAutomationActualMatchingPage, matchAndReverseAccruals, openMatchNewModal, searchMatchAccruals, searchMatchTransactions, updateActualMatchingUIState as updateExpenseAutomationActualMatchingUIState, } from './view/expenseAutomationView/reducers/actualMatchingViewReducer';
187
188
  import { clearExpenseAutomationFluxAnalysisView, fetchFluxAnalysisView, reviewFluxAnalysisView, updateFluxAnalysisViewPageMetaData, updateFluxAnalysisViewUIState, updateOperatingExpensesIdsForReview, updateSelectedSectionIdsForReview, } from './view/expenseAutomationView/reducers/fluxAnalysisViewReducer';
188
189
  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, 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, toggleJEPendingGroupCollapsed, updateJESchedulesUIState as updateExpenseAutomationJESchedulesUIState, updateJEScheduleTypeFilter, updateNewScheduleLocalData as updateJeNewScheduleLocalData, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys, } from './view/expenseAutomationView/reducers/jeSchedulesViewReducer';
189
190
  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';
@@ -195,8 +196,9 @@ import { getExpenseAutomationReconciliationView, getLedgerAccountIdsWithStatemen
195
196
  import { getExpenseAutomationTransactionView, getLastTransferEntryReplacement, } from './view/expenseAutomationView/selectors/transactionCategorizationSelector';
196
197
  import { applyTransactionFilters } from './view/expenseAutomationView/transactionFilterHelpers';
197
198
  import { TRANSACTION_FILTER_CATEGORIES, } from './view/expenseAutomationView/transactionFilterTypes';
199
+ import { MATCH_ACCRUAL_SEARCH_LIMIT, MATCH_SEARCH_DEBOUNCE_MS, MATCH_TRANSACTION_SEARCH_PAGE_SIZE, toActualMatchingSortKey as toExpenseAutomationActualMatchingSortKey, toMatchAndReverseResultStatus, } from './view/expenseAutomationView/types/actualMatchingViewState';
198
200
  import { DEFAULT_COMPLETED_SUB_TAB, toCompletedSubTab, } from './view/expenseAutomationView/types/completedSubTab';
199
- import { toJEScheduleSortKey as toExpenseAutomationJEScheduleSortKey, toJEPageTab, } from './view/expenseAutomationView/types/jeSchedulesViewState';
201
+ import { ALL_JE_PAGE_TABS, toJEScheduleSortKey as toExpenseAutomationJEScheduleSortKey, toJEPageTab, } from './view/expenseAutomationView/types/jeSchedulesViewState';
200
202
  import { BATCH_FILE_STATUSES, isUnmatchedTabFileStatus, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toMatchSource, toMissingReceiptsTab, } from './view/expenseAutomationView/types/missingReceiptsViewState';
201
203
  import { toMissingReceiptsSortKey as toExpenseAutomationMissingReceiptsSortKey, } from './view/expenseAutomationView/types/missingReceiptsViewState';
202
204
  import { toReconciliationTabsType, } from './view/expenseAutomationView/types/reconciliationViewState';
@@ -485,7 +487,7 @@ export { stringToUnion, stringToUnionStrict };
485
487
  export { fetchMonthEndCloseChecks, fetchMonthClosePerformanceTrend, getMonthEndCloseChecksViewByTenantId, ALL_MONTH_END_CLOSE_CHECKS_FREQUENCY, };
486
488
  export {
487
489
  // Bulk Upload Types
488
- BATCH_FILE_STATUSES, isUnmatchedTabFileStatus, DEFAULT_COMPLETED_SUB_TAB, DEFAULT_TRANSACTION_GROUP, TRANSACTION_GROUPS, toTransactionGroup, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toCompletedSubTab, toMatchSource, toMissingReceiptsTab, toExpenseAutomationJEScheduleSortKey, toJEPageTab, toggleJECreatedGroupCollapsed, toggleJEPendingGroupCollapsed, updateJEScheduleTypeFilter, getExpenseAutomationView, toExpenseAutomationMissingReceiptsSortKey, toExpenseAutomationTransactionsTabKey, toExpenseAutomationViewType, uploadExpenseAutomationMissingReceiptSuccess, markExpenseAutomationMissingReceiptAsDone, fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedTransactionCategorizationTab, updateTransactionCategorizationCompletedSubTab, updateTransactionGroup, fetchExpenseAutomationMissingReceipts,
490
+ BATCH_FILE_STATUSES, isUnmatchedTabFileStatus, DEFAULT_COMPLETED_SUB_TAB, DEFAULT_TRANSACTION_GROUP, TRANSACTION_GROUPS, toTransactionGroup, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toCompletedSubTab, toMatchSource, toMissingReceiptsTab, ALL_JE_PAGE_TABS, MATCH_ACCRUAL_SEARCH_LIMIT, MATCH_SEARCH_DEBOUNCE_MS, MATCH_TRANSACTION_SEARCH_PAGE_SIZE, toExpenseAutomationJEScheduleSortKey, toExpenseAutomationActualMatchingSortKey, toJEPageTab, toMatchAndReverseResultStatus, toggleJECreatedGroupCollapsed, toggleJEPendingGroupCollapsed, updateJEScheduleTypeFilter, getExpenseAutomationView, toExpenseAutomationMissingReceiptsSortKey, toExpenseAutomationTransactionsTabKey, toExpenseAutomationViewType, uploadExpenseAutomationMissingReceiptSuccess, markExpenseAutomationMissingReceiptAsDone, fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedTransactionCategorizationTab, updateTransactionCategorizationCompletedSubTab, updateTransactionGroup, fetchExpenseAutomationMissingReceipts,
489
491
  // Bulk Upload Actions
490
492
  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, };
491
493
  export { computeNewScheduleJeDetails, createOneTimeAccrual, createOneTimeAccrualFailure, createOneTimeAccrualSuccess, fetchOneTimeAccrual, getJeNewAccrualAccountsView, ignoreOneTimeAccrual, promoteOneTimeAccrual, revertJeSchedule, revertOneTimeAccrual, getJeNewScheduleSearchTransactionsView, getJeNewScheduleView, };
@@ -656,6 +658,7 @@ export { TIME_SERIES_DURATIONS, convertToTimeSeriesSelectionRange, toTimeSeriesD
656
658
  export { fetchApAging, getApAgingReport, updateApAgingUIState, };
657
659
  export { fetchApAgingDetail, getApAgingDetailForVendor, updateApAgingDetailUIState, };
658
660
  export { clearExpenseAutomationJEScheduleLocalData, clearExpenseAutomationJESchedulesView, clearJeSearchTransactionsForNewSchedule, fetchExpenseAutomationJESchedulesPage, ignoreExpenseAutomationJESchedule, initializeJeAccountSettingsView, initializeJeNewSchedule, initializeJeScheduleLocalData, removeJeScheduleTransactionKey, resetJeNewScheduleLocalData, retryExpenseAutomationJESchedule, saveJeNewSchedule, saveJeNewScheduleFailure, saveJeNewScheduleSuccess, searchJeTransactionsForNewSchedule, searchJeTransactionsForNewScheduleFailure, searchJeTransactionsForNewScheduleSuccess, updateExpenseAutomationJESchedulesUIState, updateJeNewScheduleLocalData, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys, };
661
+ export { clearExpenseAutomationActualMatchingView, closeMatchNewModal, clearMatchNewModal, fetchExpenseAutomationActualMatching, fetchExpenseAutomationActualMatchingPage, matchAndReverseAccruals, openMatchNewModal, searchMatchAccruals, searchMatchTransactions, updateExpenseAutomationActualMatchingUIState, };
659
662
  export { createNewSchedulesAccrued, deleteScheduleAccruedDetail, cancelScheduleAccruedJournalEntry, fetchScheduleAccruedDetails, fetchScheduleAccruedDetailsPage, resetJEAccruedLinkInLocalData, saveScheduleAccruedDetails, updateAmountsInScheduleAccruedDetail, updatedJEAccruedLinkWithRecommendedLocalData, updatedJELinkInLocalDataAccruedExpenses, fetchRecommendedTransactionRowIndex, clearSelectedJELinkRowIndex, updateLinkBillExpenseLocalData, updateScheduleAccruedDetailsLocalData, updateSelectedJEAccruedScheduleKey, resetSelectedJEAccruedScheduleKey, resetAccruedDetailNewScheduleState, };
660
663
  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, };
661
664
  export { toVendorFirstReviewViewColumnKeyType, getGlobalMerchantAutoCompleteResults, getVendorFirstReviewView, getVendorFirstReviewAttachmentView, fetchVendorFirstReviewView, fetchVendorFirstReviewAttachments, updateVendorFirstReviewViewScrollYOffset, resetVendorFirstReviewLocalData, updateVendorFirstReviewViewPageToken, clearRecentlySavedErroredVendorData, saveVendorFirstReviewView, updateVendorFirstReviewViewLocalData, updateVendorFirstReviewSortUiState, fetchGlobalMerchantAutoCompleteView, clearGlobalMerchantAutoCompleteResults, updateReviewVendorDetailLocalData, saveVendorDetailsView, getVendorDetailSelectorView, };
@@ -869,3 +872,4 @@ export { getInvoicingOnboardingGateView } from './view/invoicing/invoicingConfig
869
872
  // Accrued JE schedules are not a discriminated union member, so consumers need this guard to
870
873
  // narrow a JEScheduleRow before reading baseTransaction / recurringAmount.
871
874
  export { getExpenseAutomationJEOneTimeAccrualDetailView, getJEScheduleRowType, isAccruedScheduleRow, isAiAccountantSchedule, isExistingTabRow, isOneTimeAccrualRow, isRenderableOneTimeAccrual, isPendingReviewRow, } from './view/expenseAutomationView/selectors/jeSchedulesViewSelector';
875
+ export { getActualMatchingAmount, getActualMatchingReversalDate, getExpenseAutomationActualMatchingView, isAutoReversedAccrual, isManuallyReversedAccrual, isPendingReviewAccrual, } from './view/expenseAutomationView/selectors/actualMatchingViewSelector';
@@ -116,6 +116,7 @@ import creditAgentView, { initialState as initialCreditAgentViewState, } from '.
116
116
  import dashboard, { initialState as initialDashboardState, } from './view/dashboard/dashboardReducer';
117
117
  import dashboardLayout, { initialState as initialDashboardLayoutState, } from './view/dashboardLayout/dashboardLayoutReducer';
118
118
  import expenseAutomationView, { initialState as initialExpenseAutomationViewState, } from './view/expenseAutomationView/expenseAutomationViewReducer';
119
+ import expenseAutomationActualMatchingView, { initialState as initialExpenseAutomationActualMatchingViewState, } from './view/expenseAutomationView/reducers/actualMatchingViewReducer';
119
120
  import expenseAutomationFluxAnalysisView, { initialState as initialExpenseAutomationFluxAnalysisViewState, } from './view/expenseAutomationView/reducers/fluxAnalysisViewReducer';
120
121
  import expenseAutomationJESchedulesView, { initialState as initialExpenseAutomationJESchedulesViewState, } from './view/expenseAutomationView/reducers/jeSchedulesViewReducer';
121
122
  import expenseAutomationMissingReceiptsView, { initialState as initialExpenseAutomationMissingReceiptsViewState, } from './view/expenseAutomationView/reducers/missingReceiptsViewReducer';
@@ -429,6 +430,7 @@ const initialViewsState = {
429
430
  entityAutoCompleteState: initialEntityAutoCompleteState,
430
431
  entityRecommendationState: initialEntityRecommendationState,
431
432
  expenseAutomationFluxAnalysisViewState: initialExpenseAutomationFluxAnalysisViewState,
433
+ expenseAutomationActualMatchingViewState: initialExpenseAutomationActualMatchingViewState,
432
434
  expenseAutomationJESchedulesViewState: initialExpenseAutomationJESchedulesViewState,
433
435
  expenseAutomationMissingReceiptsViewState: initialExpenseAutomationMissingReceiptsViewState,
434
436
  expenseAutomationReconciliationViewState: initialExpenseAutomationReconciliationViewState,
@@ -723,6 +725,7 @@ const viewReducers = {
723
725
  entityAutoCompleteState: entityAutoComplete,
724
726
  entityRecommendationState: recommendation,
725
727
  expenseAutomationFluxAnalysisViewState: expenseAutomationFluxAnalysisView,
728
+ expenseAutomationActualMatchingViewState: expenseAutomationActualMatchingView,
726
729
  expenseAutomationJESchedulesViewState: expenseAutomationJESchedulesView,
727
730
  expenseAutomationMissingReceiptsViewState: expenseAutomationMissingReceiptsView,
728
731
  expenseAutomationReconciliationViewState: expenseAutomationReconciliationView,
@@ -2,17 +2,15 @@ import { of } from 'rxjs';
2
2
  import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
3
3
  import { updateAccountReconDeleteStatement } from '../../../../entity/accountRecon/accountReconReducer';
4
4
  import { toAccountReconKey } from '../../../../entity/accountRecon/accountReconState';
5
- import { removeFiles } from '../../../../entity/file/fileReducer';
6
5
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
7
6
  import { deleteAccountStatement, deleteAccountStatementFailure, deleteAccountStatementSuccess, } from '../../reducers/reconciliationViewReducer';
8
7
  export const deleteAccountStatementEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(deleteAccountStatement.match), switchMap((action) => {
9
- const { accountId, selectedPeriod, statementUploadId, fileId } = action.payload;
8
+ const { accountId, selectedPeriod, statementUploadId } = action.payload;
10
9
  const request = zeniAPI.deleteAndGetJSON(`${zeniAPI.apiEndPoints.reconciliationMicroServiceBaseUrl}/1.0/reconciliation/statements/${statementUploadId}`);
11
10
  return request.pipe(mergeMap((response) => {
12
11
  if (isSuccessResponse(response)) {
13
12
  const actions = [];
14
13
  const accountReconKey = toAccountReconKey(accountId, selectedPeriod);
15
- actions.push(removeFiles([fileId]));
16
14
  if (response.data != null) {
17
15
  actions.push(updateAccountReconDeleteStatement(accountReconKey, response.data));
18
16
  }
@@ -0,0 +1,46 @@
1
+ import { from, of } from 'rxjs';
2
+ import { catchError, filter, mergeMap, takeUntil } from 'rxjs/operators';
3
+ import { updateJEOneTimeAccruals } from '../../../../entity/jeSchedules/jeSchedulesReducer';
4
+ import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
5
+ import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
6
+ import { clearAll } from '../../../../rootActions';
7
+ import { toServiceMonthFromPeriod, } from '../../payload/actualMatchingPayload';
8
+ import { fetchActualMatching, fetchActualMatchingFailure, fetchActualMatchingSuccess, } from '../../reducers/actualMatchingViewReducer';
9
+ export const fetchActualMatchingEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchActualMatching.match), mergeMap((action) => {
10
+ const state = state$.value;
11
+ const { period, refreshViewInBackground } = action.payload;
12
+ const currentTenant = getCurrentTenant(state);
13
+ const selectedPeriod = state.expenseAutomationViewState
14
+ .selectedPeriodByTenantId[currentTenant.tenantId] ?? {
15
+ month: period.start.month,
16
+ year: period.start.year,
17
+ };
18
+ const serviceMonth = toServiceMonthFromPeriod(period);
19
+ return zeniAPI
20
+ .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals?service_month=${encodeURIComponent(serviceMonth)}&view=actual_matching`)
21
+ .pipe(mergeMap((response) => {
22
+ if (isSuccessResponse(response) && response.data != null) {
23
+ const accruals = response.data.accruals ?? [];
24
+ const updateActions = [];
25
+ if (accruals.length > 0) {
26
+ updateActions.push(updateJEOneTimeAccruals(accruals));
27
+ }
28
+ updateActions.push(fetchActualMatchingSuccess({
29
+ accruals,
30
+ selectedPeriod,
31
+ refreshViewInBackground,
32
+ }));
33
+ return from(updateActions);
34
+ }
35
+ return of(fetchActualMatchingFailure({
36
+ status: response.status,
37
+ selectedPeriod,
38
+ refreshViewInBackground,
39
+ }));
40
+ }), catchError((error) => of(fetchActualMatchingFailure({
41
+ status: createZeniAPIStatus('Unexpected Error', 'fetch actual matching REST API call errored out' +
42
+ JSON.stringify(error)),
43
+ selectedPeriod,
44
+ refreshViewInBackground,
45
+ }))), takeUntil(actions$.pipe(filter(clearAll.match))));
46
+ }));
@@ -0,0 +1,7 @@
1
+ import { of } from 'rxjs';
2
+ import { filter, mergeMap } from 'rxjs/operators';
3
+ import { fetchActualMatching, fetchActualMatchingPage, } from '../../reducers/actualMatchingViewReducer';
4
+ export const fetchActualMatchingPageEpic = (actions$) => actions$.pipe(filter(fetchActualMatchingPage.match), mergeMap((action) => {
5
+ const { period, refreshViewInBackground } = action.payload;
6
+ return of(fetchActualMatching(period, refreshViewInBackground));
7
+ }));
@@ -0,0 +1,50 @@
1
+ import { from, of } from 'rxjs';
2
+ import { catchError, filter, mergeMap, takeUntil } from 'rxjs/operators';
3
+ import { convertToPeriod, toAbsoluteDay, } from '../../../../commonStateTypes/timePeriod';
4
+ import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
5
+ import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
6
+ import { clearAll } from '../../../../rootActions';
7
+ import { toMatchAndReverseResult, } from '../../payload/actualMatchingPayload';
8
+ import { clearMatchNewModal, fetchActualMatching, matchAndReverseAccruals, matchAndReverseAccrualsFailure, matchAndReverseAccrualsSuccess, } from '../../reducers/actualMatchingViewReducer';
9
+ function refreshActualMatchingList(state) {
10
+ const selectedMonthYear = state.expenseAutomationViewState.selectedPeriodByTenantId[getCurrentTenant(state).tenantId];
11
+ if (selectedMonthYear == null) {
12
+ return [];
13
+ }
14
+ const period = convertToPeriod(selectedMonthYear);
15
+ const start = toAbsoluteDay(period.start);
16
+ const end = toAbsoluteDay(period.end);
17
+ if (start == null || end == null) {
18
+ return [];
19
+ }
20
+ return [fetchActualMatching({ start, end }, true)];
21
+ }
22
+ export const matchAndReverseAccrualsEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(matchAndReverseAccruals.match), mergeMap((action) => {
23
+ const { transactionId, transactionIntegrationId, transactionType, lineId, accrualIds, } = action.payload;
24
+ const body = {
25
+ transaction_id: transactionId,
26
+ transaction_integration_id: transactionIntegrationId,
27
+ transaction_type: transactionType,
28
+ line_id: lineId,
29
+ accrual_ids: accrualIds,
30
+ };
31
+ return zeniAPI
32
+ .postAndGetJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals/match-and-reverse`, body)
33
+ .pipe(mergeMap((response) => {
34
+ if (isSuccessResponse(response) && response.data != null) {
35
+ const results = (response.data.results ?? []).map(toMatchAndReverseResult);
36
+ const successActions = [
37
+ matchAndReverseAccrualsSuccess({ results }),
38
+ ];
39
+ const anyReversed = results.some((result) => result.status === 'reversed');
40
+ if (anyReversed) {
41
+ successActions.push(...refreshActualMatchingList(state$.value), clearMatchNewModal());
42
+ }
43
+ return from(successActions);
44
+ }
45
+ return of(matchAndReverseAccrualsFailure({ status: response.status }));
46
+ }), catchError((error) => of(matchAndReverseAccrualsFailure({
47
+ status: createZeniAPIStatus('Unexpected Error', 'Match and reverse accruals REST API call errored out' +
48
+ JSON.stringify(error)),
49
+ }))), takeUntil(actions$.pipe(filter(clearAll.match))));
50
+ }));
@@ -0,0 +1,44 @@
1
+ import { from, merge, of } from 'rxjs';
2
+ import { catchError, debounceTime, filter, mergeMap, switchMap, } from 'rxjs/operators';
3
+ import { updateJEOneTimeAccruals } from '../../../../entity/jeSchedules/jeSchedulesReducer';
4
+ import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
5
+ import { searchMatchAccruals, searchMatchAccrualsFailure, searchMatchAccrualsSuccess, } from '../../reducers/actualMatchingViewReducer';
6
+ import { MATCH_ACCRUAL_SEARCH_LIMIT, MATCH_SEARCH_DEBOUNCE_MS, } from '../../types/actualMatchingViewState';
7
+ export const searchMatchAccrualsEpic = (actions$, _state$, zeniAPI) => {
8
+ const searchActions$ = actions$.pipe(filter(searchMatchAccruals.match));
9
+ const pagination$ = searchActions$.pipe(filter((action) => action.payload.pageToken != null));
10
+ const newSearchDebounced$ = searchActions$.pipe(filter((action) => action.payload.pageToken == null), debounceTime(MATCH_SEARCH_DEBOUNCE_MS));
11
+ return merge(pagination$, newSearchDebounced$).pipe(switchMap((action) => {
12
+ const { query, pageToken } = action.payload;
13
+ const offset = pageToken != null && pageToken.length > 0 ? Number(pageToken) : 0;
14
+ const searchText = encodeURIComponent(query);
15
+ const limit = MATCH_ACCRUAL_SEARCH_LIMIT;
16
+ return zeniAPI
17
+ .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals?status=posted&reversal_policy=on_bill_match&search_text=${searchText}&limit=${limit}&offset=${offset}`)
18
+ .pipe(mergeMap((response) => {
19
+ if (isSuccessResponse(response) && response.data != null) {
20
+ const accruals = response.data.accruals ?? [];
21
+ const append = pageToken != null;
22
+ const nextOffset = offset + accruals.length;
23
+ const total = response.data.total ?? nextOffset;
24
+ const nextPageToken = nextOffset < total ? String(nextOffset) : null;
25
+ const actionsOut = [];
26
+ if (accruals.length > 0) {
27
+ actionsOut.push(updateJEOneTimeAccruals(accruals));
28
+ }
29
+ actionsOut.push(searchMatchAccrualsSuccess({
30
+ append,
31
+ nextPageToken,
32
+ results: accruals,
33
+ }));
34
+ return from(actionsOut);
35
+ }
36
+ return of(searchMatchAccrualsFailure({
37
+ error: response.status,
38
+ }));
39
+ }), catchError((error) => of(searchMatchAccrualsFailure({
40
+ error: createZeniAPIStatus('Unexpected Error', 'Search match accruals REST API call errored out' +
41
+ JSON.stringify(error)),
42
+ }))));
43
+ }));
44
+ };
@@ -0,0 +1,44 @@
1
+ import { from, merge, of } from 'rxjs';
2
+ import { catchError, debounceTime, filter, mergeMap, switchMap, } from 'rxjs/operators';
3
+ import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
4
+ import { toActualMatchingTransactionSearchResult, } from '../../payload/actualMatchingPayload';
5
+ import { openMatchNewModal, searchMatchAccruals, searchMatchTransactions, searchMatchTransactionsFailure, searchMatchTransactionsSuccess, } from '../../reducers/actualMatchingViewReducer';
6
+ import { MATCH_SEARCH_DEBOUNCE_MS, MATCH_TRANSACTION_SEARCH_PAGE_SIZE, } from '../../types/actualMatchingViewState';
7
+ export const searchMatchTransactionsEpic = (actions$, _state$, zeniAPI) => {
8
+ const openModal$ = actions$.pipe(filter(openMatchNewModal.match), mergeMap(() => from([
9
+ searchMatchTransactions({ query: '' }),
10
+ searchMatchAccruals({ query: '' }),
11
+ ])));
12
+ const searchActions$ = actions$.pipe(filter(searchMatchTransactions.match));
13
+ const pagination$ = searchActions$.pipe(filter((action) => action.payload.pageToken != null));
14
+ const newSearchDebounced$ = searchActions$.pipe(filter((action) => action.payload.pageToken == null), debounceTime(MATCH_SEARCH_DEBOUNCE_MS));
15
+ const search$ = merge(pagination$, newSearchDebounced$).pipe(switchMap((action) => {
16
+ const { query, pageToken } = action.payload;
17
+ const queryParam = {
18
+ search_text: query,
19
+ page_size: MATCH_TRANSACTION_SEARCH_PAGE_SIZE,
20
+ ...(pageToken != null ? { page_token: pageToken } : {}),
21
+ };
22
+ return zeniAPI
23
+ .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals/match-transaction-search?query=${encodeURIComponent(JSON.stringify(queryParam))}`)
24
+ .pipe(mergeMap((response) => {
25
+ if (isSuccessResponse(response) && response.data != null) {
26
+ const { transactions, next_page_token } = response.data;
27
+ const append = pageToken != null;
28
+ const results = (transactions ?? []).map(toActualMatchingTransactionSearchResult);
29
+ return of(searchMatchTransactionsSuccess({
30
+ append,
31
+ nextPageToken: next_page_token ?? null,
32
+ results,
33
+ }));
34
+ }
35
+ return of(searchMatchTransactionsFailure({
36
+ error: response.status,
37
+ }));
38
+ }), catchError((error) => of(searchMatchTransactionsFailure({
39
+ error: createZeniAPIStatus('Unexpected Error', 'Search match transactions REST API call errored out' +
40
+ JSON.stringify(error)),
41
+ }))));
42
+ }));
43
+ return merge(openModal$, search$);
44
+ };
@@ -3,6 +3,7 @@ import { filter, switchMap } from 'rxjs/operators';
3
3
  import { convertToPeriod, toAbsoluteDay, toMonthYearPeriodId, } from '../../../../commonStateTypes/timePeriod';
4
4
  import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
5
5
  import { fetchAllExpenseAutomationTabs } from '../../expenseAutomationViewReducer';
6
+ import { fetchActualMatchingPage } from '../../reducers/actualMatchingViewReducer';
6
7
  import { fetchFluxAnalysisView } from '../../reducers/fluxAnalysisViewReducer';
7
8
  import { fetchJeSchedulesPage } from '../../reducers/jeSchedulesViewReducer';
8
9
  import { fetchMissingReceipts } from '../../reducers/missingReceiptsViewReducer';
@@ -31,11 +32,14 @@ export const fetchAllExpenseAutomationTabsEpic = (actions$, state$) => actions$.
31
32
  }
32
33
  if (cacheOverride === true) {
33
34
  const actions = [];
35
+ const selectedPageTab = state.expenseAutomationJESchedulesViewState.uiState.selectedPageTab;
34
36
  actions.push(fetchTransactionCategorizationView(selectedTransactionCategorizationTab, { start: timePeriodStart, end: timePeriodEnd }, cacheOverride, false, undefined, undefined, refreshViewInBackground, false), fetchMissingReceipts({ start: timePeriodStart, end: timePeriodEnd }, {
35
37
  amount: 75.0,
36
38
  currencyCode: 'USD',
37
39
  currencySymbol: '$',
38
- }, cacheOverride, refreshViewInBackground), fetchFluxAnalysisView(selectedPeriod, cacheOverride, refreshViewInBackground, null), fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, cacheOverride));
40
+ }, cacheOverride, refreshViewInBackground), fetchFluxAnalysisView(selectedPeriod, cacheOverride, refreshViewInBackground, null), selectedPageTab === 'actual_matching'
41
+ ? fetchActualMatchingPage({ start: timePeriodStart, end: timePeriodEnd }, cacheOverride)
42
+ : fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, cacheOverride));
39
43
  if (reconciliationEnabled) {
40
44
  actions.push(fetchReconciliation(selectedPeriod, undefined, cacheOverride, refreshViewInBackground));
41
45
  }
@@ -61,16 +65,29 @@ export const fetchAllExpenseAutomationTabsEpic = (actions$, state$) => actions$.
61
65
  fetchActions.push(fetchFluxAnalysisView(selectedPeriod, cacheOverride, refreshViewInBackground, null));
62
66
  }
63
67
  // The two JE tabs cache separately, so only the tab actually being shown decides whether a
64
- // fetch is still needed.
65
- const jeSchedulesPeriodTabKey = getJESchedulePeriodTabKey(state.expenseAutomationJESchedulesViewState.uiState.selectedPageTab, monthYearPeriodId);
66
- if (state.expenseAutomationJESchedulesViewState.fetchState !==
67
- 'In-Progress' &&
68
- (!state.expenseAutomationJESchedulesViewState.hasValidState() ||
69
- state.expenseAutomationJESchedulesViewState
70
- .jeScheduleTransactionKeysByPeriodAndTab[jeSchedulesPeriodTabKey] == null ||
71
- state.expenseAutomationJESchedulesViewState
72
- .failedJeScheduleTransactionKeysByPeriodAndTab[jeSchedulesPeriodTabKey] == null)) {
73
- fetchActions.push(fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, cacheOverride));
68
+ // fetch is still needed. Actual Matching is a third tab on the same page with its own
69
+ // endpoint and cache slot.
70
+ const selectedPageTab = state.expenseAutomationJESchedulesViewState.uiState.selectedPageTab;
71
+ if (selectedPageTab === 'actual_matching') {
72
+ const actualMatchingPeriodKeys = state.expenseAutomationActualMatchingViewState.accrualKeysByPeriod[monthYearPeriodId];
73
+ if (state.expenseAutomationActualMatchingViewState.fetchState !==
74
+ 'In-Progress' &&
75
+ (!state.expenseAutomationActualMatchingViewState.hasValidState() ||
76
+ actualMatchingPeriodKeys == null)) {
77
+ fetchActions.push(fetchActualMatchingPage({ start: timePeriodStart, end: timePeriodEnd }, cacheOverride));
78
+ }
79
+ }
80
+ else {
81
+ const jeSchedulesPeriodTabKey = getJESchedulePeriodTabKey(selectedPageTab, monthYearPeriodId);
82
+ if (state.expenseAutomationJESchedulesViewState.fetchState !==
83
+ 'In-Progress' &&
84
+ (!state.expenseAutomationJESchedulesViewState.hasValidState() ||
85
+ state.expenseAutomationJESchedulesViewState
86
+ .jeScheduleTransactionKeysByPeriodAndTab[jeSchedulesPeriodTabKey] == null ||
87
+ state.expenseAutomationJESchedulesViewState
88
+ .failedJeScheduleTransactionKeysByPeriodAndTab[jeSchedulesPeriodTabKey] == null)) {
89
+ fetchActions.push(fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, cacheOverride));
90
+ }
74
91
  }
75
92
  if (state.expenseAutomationReconciliationViewState.fetchState !==
76
93
  'In-Progress' &&
@@ -4,6 +4,7 @@ import { convertToPeriod, toAbsoluteDay, } from '../../../../commonStateTypes/ti
4
4
  import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
5
5
  import { fetchCompanyMonthEndReportTemplates, fetchCompanyMonthEndReportView, } from '../../../companyMonthEndReportView/companyMonthEndReportViewReducer';
6
6
  import { refreshExpenseAutomationCurrentTab } from '../../expenseAutomationViewReducer';
7
+ import { fetchActualMatchingPage } from '../../reducers/actualMatchingViewReducer';
7
8
  import { fetchFluxAnalysisView } from '../../reducers/fluxAnalysisViewReducer';
8
9
  import { fetchJeSchedulesPage } from '../../reducers/jeSchedulesViewReducer';
9
10
  import { fetchMissingReceipts } from '../../reducers/missingReceiptsViewReducer';
@@ -38,10 +39,17 @@ export const refreshExpenseAutomationCurrentTabEpic = (actions$, state$) => acti
38
39
  return from([
39
40
  fetchFluxAnalysisView(selectedPeriod, true, true, null),
40
41
  ]);
41
- case 'je_schedules':
42
+ case 'je_schedules': {
43
+ const selectedPageTab = state.expenseAutomationJESchedulesViewState.uiState.selectedPageTab;
44
+ if (selectedPageTab === 'actual_matching') {
45
+ return from([
46
+ fetchActualMatchingPage({ start: timePeriodStart, end: timePeriodEnd }, true),
47
+ ]);
48
+ }
42
49
  return from([
43
50
  fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, true),
44
51
  ]);
52
+ }
45
53
  case 'month_end_insights':
46
54
  return from([
47
55
  fetchCompanyMonthEndReportView(true, companyId, currentTenant.tenantId, period.end, true),
@@ -2,6 +2,7 @@ import { EMPTY, of } from 'rxjs';
2
2
  import { filter, mergeMap } from 'rxjs/operators';
3
3
  import { convertToPeriod, toAbsoluteDay, } from '../../../../commonStateTypes/timePeriod';
4
4
  import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
5
+ import { fetchActualMatchingPage } from '../../reducers/actualMatchingViewReducer';
5
6
  import { fetchJeSchedulesPage, updateJESchedulesUIState, } from '../../reducers/jeSchedulesViewReducer';
6
7
  export const switchJESchedulesTabEpic = (actions$, state$) => actions$.pipe(filter(updateJESchedulesUIState.match), filter((action) => action.payload.selectedPageTab != null), mergeMap(() => {
7
8
  const state = state$.value;
@@ -24,5 +25,9 @@ export const switchJESchedulesTabEpic = (actions$, state$) => actions$.pipe(filt
24
25
  if (timePeriodStart == null || timePeriodEnd == null) {
25
26
  return EMPTY;
26
27
  }
28
+ const { selectedPageTab } = state.expenseAutomationJESchedulesViewState.uiState;
29
+ if (selectedPageTab === 'actual_matching') {
30
+ return of(fetchActualMatchingPage({ start: timePeriodStart, end: timePeriodEnd }, true));
31
+ }
27
32
  return of(fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, true));
28
33
  }));
@@ -4,6 +4,7 @@ import { getMonthEndCloseChecksForATenantForSelectedPeriod } from '../../entity/
4
4
  import { getCurrentTenant, } from '../../entity/tenant/tenantSelector';
5
5
  import { getCompanyMonthEndReportSelectorView } from '../companyMonthEndReportView/companyMonthEndReportViewSelector';
6
6
  import { getMonthEndCloseChecksViewByTenantId, isMonthEndInsightDisabled, } from '../monthEndCloseChecksView/monthEndCloseChecksViewSelector';
7
+ import { getExpenseAutomationActualMatchingView } from './selectors/actualMatchingViewSelector';
7
8
  import { getExpenseAutomationFluxAnalysisView } from './selectors/fluxAnalysisViewSelector';
8
9
  import { getAllSteps } from './selectors/getAllStepsHelper';
9
10
  import { getExpenseAutomationJESchedulesView } from './selectors/jeSchedulesViewSelector';
@@ -21,7 +22,7 @@ const isPreviousStepDisabled = (selectedTransactionCategorizationTab, allSteps,
21
22
  return allSteps[stepIndex - 1].isDisabled;
22
23
  };
23
24
  export function getExpenseAutomationView(state) {
24
- const { expenseAutomationViewState, tenantState, expenseAutomationMissingReceiptsViewState, expenseAutomationJESchedulesViewState, expenseAutomationTransactionsViewState, expenseAutomationReconciliationViewState, monthEndCloseChecksState, companyState, } = state;
25
+ const { expenseAutomationViewState, tenantState, expenseAutomationMissingReceiptsViewState, expenseAutomationJESchedulesViewState, expenseAutomationActualMatchingViewState, expenseAutomationTransactionsViewState, expenseAutomationReconciliationViewState, monthEndCloseChecksState, companyState, } = state;
25
26
  const { loggedInUser, currentTenantId } = tenantState;
26
27
  const currentTenant = getCurrentTenant(state);
27
28
  const { currentSelectedView, selectedPeriodByTenantId } = expenseAutomationViewState;
@@ -42,6 +43,7 @@ export function getExpenseAutomationView(state) {
42
43
  const reconciliation = getExpenseAutomationReconciliationView(state);
43
44
  const expenseAutomationTransactionsView = getExpenseAutomationTransactionView(state);
44
45
  const jeSchedules = getExpenseAutomationJESchedulesView(state);
46
+ const actualMatching = getExpenseAutomationActualMatchingView(state);
45
47
  switch (currentSelectedView) {
46
48
  case 'reconciliation':
47
49
  currentSelectedViewFetchState = reconciliation.fetchStatus;
@@ -54,12 +56,23 @@ export function getExpenseAutomationView(state) {
54
56
  fluxAnalysis.refreshStatus;
55
57
  break;
56
58
  case 'je_schedules':
57
- currentSelectedViewFetchState = {
58
- fetchState: jeSchedules.fetchState,
59
- error: jeSchedules.error,
60
- };
61
- currentSelectedViewBackgroundRefreshFetchState =
62
- jeSchedules.refreshStatus;
59
+ if (expenseAutomationJESchedulesViewState.uiState.selectedPageTab ===
60
+ 'actual_matching') {
61
+ currentSelectedViewFetchState = {
62
+ fetchState: actualMatching.fetchState,
63
+ error: actualMatching.error,
64
+ };
65
+ currentSelectedViewBackgroundRefreshFetchState =
66
+ actualMatching.refreshStatus;
67
+ }
68
+ else {
69
+ currentSelectedViewFetchState = {
70
+ fetchState: jeSchedules.fetchState,
71
+ error: jeSchedules.error,
72
+ };
73
+ currentSelectedViewBackgroundRefreshFetchState =
74
+ jeSchedules.refreshStatus;
75
+ }
63
76
  break;
64
77
  case 'missing_receipts':
65
78
  currentSelectedViewFetchState = {
@@ -91,6 +104,7 @@ export function getExpenseAutomationView(state) {
91
104
  const fetchStateVariables = [
92
105
  expenseAutomationMissingReceiptsViewState,
93
106
  expenseAutomationJESchedulesViewState,
107
+ expenseAutomationActualMatchingViewState,
94
108
  expenseAutomationTransactionsView,
95
109
  expenseAutomationReconciliationViewState,
96
110
  ];
@@ -176,6 +190,7 @@ export function getExpenseAutomationView(state) {
176
190
  ]);
177
191
  return {
178
192
  jeSchedules,
193
+ actualMatching,
179
194
  transactionView: expenseAutomationTransactionsView,
180
195
  missingReceipts,
181
196
  reconciliation,
@@ -0,0 +1,60 @@
1
+ import { toString } from '../../../commonStateTypes/timePeriod';
2
+ import { toMatchAndReverseResultStatus, } from '../types/actualMatchingViewState';
3
+ export function toServiceMonthFromPeriod(period) {
4
+ return toString(period.start).slice(0, 7);
5
+ }
6
+ const DEFAULT_CURRENCY_CODE = 'USD';
7
+ const DEFAULT_CURRENCY_SYMBOL = '$';
8
+ function resolveMatchSearchAmount(payload) {
9
+ const raw = payload.total_amount ?? payload.amount;
10
+ if (typeof raw === 'number' && Number.isFinite(raw)) {
11
+ return raw;
12
+ }
13
+ if (typeof raw === 'string' && raw !== '') {
14
+ const parsed = Number(raw);
15
+ if (Number.isFinite(parsed)) {
16
+ return parsed;
17
+ }
18
+ }
19
+ return 0;
20
+ }
21
+ function resolveMatchSearchCurrencySymbol(payload, currencyCode) {
22
+ if (payload.currency_symbol != null && payload.currency_symbol !== '') {
23
+ return payload.currency_symbol;
24
+ }
25
+ return currencyCode === DEFAULT_CURRENCY_CODE
26
+ ? DEFAULT_CURRENCY_SYMBOL
27
+ : currencyCode;
28
+ }
29
+ export function toActualMatchingTransactionSearchResult(payload) {
30
+ const currencyCode = payload.currency_code != null && payload.currency_code !== ''
31
+ ? payload.currency_code
32
+ : DEFAULT_CURRENCY_CODE;
33
+ return {
34
+ transactionId: payload.transaction_id,
35
+ transactionIntegrationId: payload.transaction_integration_id,
36
+ transactionType: payload.transaction_type,
37
+ lineId: payload.line_id,
38
+ vendorId: payload.vendor_id ?? undefined,
39
+ vendorName: payload.vendor_name ?? '',
40
+ amount: resolveMatchSearchAmount(payload),
41
+ transactionDate: payload.transaction_date,
42
+ accountId: payload.account_id ?? undefined,
43
+ accountName: payload.account_name ?? undefined,
44
+ accountDescription: payload.account_description ?? undefined,
45
+ accountingClassId: payload.accounting_class_id ?? undefined,
46
+ accountingClassName: payload.accounting_class_name ?? undefined,
47
+ currencyCode,
48
+ currencySymbol: resolveMatchSearchCurrencySymbol(payload, currencyCode),
49
+ transactionMemo: payload.transaction_memo ?? undefined,
50
+ transactionDescription: payload.transaction_description ?? undefined,
51
+ transactionTypeName: payload.transaction_type_name ?? undefined,
52
+ };
53
+ }
54
+ export function toMatchAndReverseResult(payload) {
55
+ return {
56
+ accrualId: payload.accrual_id,
57
+ status: toMatchAndReverseResultStatus(payload.status),
58
+ reason: payload.reason ?? undefined,
59
+ };
60
+ }