@zeniai/client-epic-state 5.2.35-beta0MM → 5.2.35-beta11MM
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.
- package/lib/entity/actualMatching/actualMatchingPayload.d.ts +7 -1
- package/lib/entity/actualMatching/actualMatchingPayload.js +19 -12
- package/lib/entity/actualMatching/actualMatchingReducer.d.ts +3 -2
- package/lib/entity/actualMatching/actualMatchingReducer.js +3 -3
- package/lib/entity/actualMatching/actualMatchingState.d.ts +3 -2
- package/lib/entity/aiCfo/aiCfoReducer.js +78 -4
- package/lib/entity/aiCfo/aiCfoState.d.ts +16 -0
- package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +2 -0
- package/lib/entity/jeSchedules/jeSchedulesPayload.js +4 -0
- package/lib/entity/jeSchedules/jeSchedulesState.d.ts +2 -0
- package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
- package/lib/entity/snackbar/snackbarTypes.js +2 -0
- package/lib/esm/entity/actualMatching/actualMatchingPayload.js +18 -12
- package/lib/esm/entity/actualMatching/actualMatchingReducer.js +3 -3
- package/lib/esm/entity/aiCfo/aiCfoReducer.js +79 -5
- package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +4 -0
- package/lib/esm/entity/snackbar/snackbarTypes.js +2 -0
- package/lib/esm/index.js +6 -6
- package/lib/esm/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingEpic.js +3 -5
- package/lib/esm/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingMatchEpic.js +3 -2
- package/lib/esm/view/expenseAutomationView/epics/actualMatching/matchAndReverseAccrualsEpic.js +80 -25
- package/lib/esm/view/expenseAutomationView/epics/actualMatching/refreshActualMatchingList.js +16 -0
- package/lib/esm/view/expenseAutomationView/epics/actualMatching/searchMatchAccrualsEpic.js +16 -6
- package/lib/esm/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.js +12 -11
- package/lib/esm/view/expenseAutomationView/epics/actualMatching/undoReversalAccrualsEpic.js +50 -26
- package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +5 -9
- package/lib/esm/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.js +1 -9
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +13 -3
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/prefetchOtherJeSchedulesTabEpic.js +34 -16
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +8 -8
- package/lib/esm/view/expenseAutomationView/expenseAutomationViewReducer.js +2 -1
- package/lib/esm/view/expenseAutomationView/expenseAutomationViewSelector.js +5 -2
- package/lib/esm/view/expenseAutomationView/expenseAutomationViewState.js +4 -2
- package/lib/esm/view/expenseAutomationView/payload/actualMatchingPayload.js +10 -10
- package/lib/esm/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +107 -20
- package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +2 -1
- package/lib/esm/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +206 -61
- package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +1 -0
- package/lib/esm/view/expenseAutomationView/types/actualMatchingViewState.js +3 -0
- package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +3 -0
- package/lib/esm/view/financeStatement/financeStatementReducer.js +17 -27
- package/lib/esm/view/spendManagement/billPay/billList/billListSelector.js +3 -3
- package/lib/index.d.ts +7 -6
- package/lib/index.js +52 -48
- package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingEpic.js +3 -5
- package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingMatchEpic.d.ts +1 -1
- package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingMatchEpic.js +3 -2
- package/lib/view/expenseAutomationView/epics/actualMatching/matchAndReverseAccrualsEpic.d.ts +2 -1
- package/lib/view/expenseAutomationView/epics/actualMatching/matchAndReverseAccrualsEpic.js +77 -22
- package/lib/view/expenseAutomationView/epics/actualMatching/refreshActualMatchingList.d.ts +3 -0
- package/lib/view/expenseAutomationView/epics/actualMatching/refreshActualMatchingList.js +19 -0
- package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchAccrualsEpic.d.ts +3 -2
- package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchAccrualsEpic.js +15 -5
- package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.js +10 -9
- package/lib/view/expenseAutomationView/epics/actualMatching/undoReversalAccrualsEpic.d.ts +2 -1
- package/lib/view/expenseAutomationView/epics/actualMatching/undoReversalAccrualsEpic.js +48 -24
- package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.d.ts +1 -2
- package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +5 -9
- package/lib/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.d.ts +1 -2
- package/lib/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.js +1 -9
- package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.d.ts +2 -1
- package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +13 -3
- package/lib/view/expenseAutomationView/epics/jeSchedule/prefetchOtherJeSchedulesTabEpic.d.ts +5 -1
- package/lib/view/expenseAutomationView/epics/jeSchedule/prefetchOtherJeSchedulesTabEpic.js +33 -15
- package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.d.ts +1 -2
- package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +8 -8
- package/lib/view/expenseAutomationView/expenseAutomationViewReducer.d.ts +2 -1
- package/lib/view/expenseAutomationView/expenseAutomationViewReducer.js +2 -1
- package/lib/view/expenseAutomationView/expenseAutomationViewSelector.js +5 -2
- package/lib/view/expenseAutomationView/expenseAutomationViewState.d.ts +2 -1
- package/lib/view/expenseAutomationView/expenseAutomationViewState.js +6 -3
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
- package/lib/view/expenseAutomationView/payload/actualMatchingPayload.d.ts +3 -3
- package/lib/view/expenseAutomationView/payload/actualMatchingPayload.js +10 -10
- package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.d.ts +21 -16
- package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +107 -20
- package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +2 -1
- package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +2 -1
- package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.d.ts +13 -9
- package/lib/view/expenseAutomationView/selectorTypes/expenseAutomationViewSelectorTypes.d.ts +9 -0
- package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.d.ts +11 -2
- package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +209 -60
- package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +1 -0
- package/lib/view/expenseAutomationView/types/actualMatchingViewState.d.ts +8 -2
- package/lib/view/expenseAutomationView/types/actualMatchingViewState.js +4 -0
- package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +3 -0
- package/lib/view/financeStatement/financeStatementReducer.js +17 -27
- package/lib/view/spendManagement/billPay/billList/billListSelector.js +2 -2
- package/package.json +1 -1
package/lib/esm/index.js
CHANGED
|
@@ -184,11 +184,11 @@ import { updateDashboardLayout } from './view/dashboardLayout/dashboardLayoutRed
|
|
|
184
184
|
import uploadAccountStatementIntoDocumentAI from './view/expenseAutomationView/epics/accountRecon/uploadAccountStatementDocumentAIHelper';
|
|
185
185
|
import { fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedPeriod, updateCurrentSelectedView, } from './view/expenseAutomationView/expenseAutomationViewReducer';
|
|
186
186
|
import { getExpenseAutomationView } from './view/expenseAutomationView/expenseAutomationViewSelector';
|
|
187
|
-
import { toExpenseAutomationViewType, } from './view/expenseAutomationView/expenseAutomationViewState';
|
|
187
|
+
import { toExpenseAutomationViewType, toExpenseAutomationViewTypeStrict, } from './view/expenseAutomationView/expenseAutomationViewState';
|
|
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 { clearActualMatchingView as clearExpenseAutomationActualMatchingView, clearMatchNewModal, closeMatchNewModal, fetchActualMatching as fetchExpenseAutomationActualMatching, fetchActualMatchingMatch, fetchActualMatchingPage as fetchExpenseAutomationActualMatchingPage, matchAndReverseAccruals, openMatchNewModal, searchMatchAccruals, searchMatchTransactions, undoReversalAccruals, updateActualMatchingUIState as updateExpenseAutomationActualMatchingUIState, } from './view/expenseAutomationView/reducers/actualMatchingViewReducer';
|
|
191
|
+
import { ackCloseMatchAfterUndo, clearActualMatchingView as clearExpenseAutomationActualMatchingView, clearMatchNewModal, closeMatchNewModal, fetchActualMatching as fetchExpenseAutomationActualMatching, fetchActualMatchingMatch, 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, 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, toActualMatchingSortKey as toExpenseAutomationActualMatchingSortKey, 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';
|
|
@@ -491,7 +491,7 @@ export { stringToUnion, stringToUnionStrict };
|
|
|
491
491
|
export { fetchMonthEndCloseChecks, fetchMonthClosePerformanceTrend, getMonthEndCloseChecksViewByTenantId, ALL_MONTH_END_CLOSE_CHECKS_FREQUENCY, };
|
|
492
492
|
export {
|
|
493
493
|
// Bulk Upload Types
|
|
494
|
-
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, toUndoReversalResultStatus, toggleJECreatedGroupCollapsed, toggleJEPendingGroupCollapsed, updateJEScheduleTypeFilter, getExpenseAutomationView, toExpenseAutomationMissingReceiptsSortKey, toExpenseAutomationTransactionsTabKey, toExpenseAutomationViewType, uploadExpenseAutomationMissingReceiptSuccess, markExpenseAutomationMissingReceiptAsDone, fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedTransactionCategorizationTab, updateTransactionCategorizationCompletedSubTab, updateTransactionGroup, fetchExpenseAutomationMissingReceipts,
|
|
494
|
+
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, toggleJEPendingGroupCollapsed, updateJEScheduleTypeFilter, getExpenseAutomationView, toExpenseAutomationMissingReceiptsSortKey, toExpenseAutomationTransactionsTabKey, toExpenseAutomationViewType, toExpenseAutomationViewTypeStrict, uploadExpenseAutomationMissingReceiptSuccess, markExpenseAutomationMissingReceiptAsDone, fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedTransactionCategorizationTab, updateTransactionCategorizationCompletedSubTab, updateTransactionGroup, fetchExpenseAutomationMissingReceipts,
|
|
495
495
|
// Bulk Upload Actions
|
|
496
496
|
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, };
|
|
497
497
|
export { computeNewScheduleJeDetails, createOneTimeAccrual, createOneTimeAccrualFailure, createOneTimeAccrualSuccess, fetchOneTimeAccrual, getJeNewAccrualAccountsView, ignoreOneTimeAccrual, promoteOneTimeAccrual, revertJeSchedule, revertOneTimeAccrual, getJeNewScheduleSearchTransactionsView, getJeNewScheduleView, };
|
|
@@ -662,7 +662,7 @@ export { TIME_SERIES_DURATIONS, convertToTimeSeriesSelectionRange, toTimeSeriesD
|
|
|
662
662
|
export { fetchApAging, getApAgingReport, updateApAgingUIState, };
|
|
663
663
|
export { fetchApAgingDetail, getApAgingDetailForVendor, updateApAgingDetailUIState, };
|
|
664
664
|
export { clearExpenseAutomationJEScheduleLocalData, clearExpenseAutomationJESchedulesView, clearJeSearchTransactionsForNewSchedule, fetchExpenseAutomationJESchedulesPage, ignoreExpenseAutomationJESchedule, initializeJeAccountSettingsView, initializeJeNewSchedule, initializeJeScheduleLocalData, removeJeScheduleTransactionKey, resetJeNewScheduleLocalData, retryExpenseAutomationJESchedule, saveJeNewSchedule, saveJeNewScheduleFailure, saveJeNewScheduleSuccess, searchJeTransactionsForNewSchedule, searchJeTransactionsForNewScheduleFailure, searchJeTransactionsForNewScheduleSuccess, updateExpenseAutomationJESchedulesUIState, updateJeNewScheduleLocalData, removeJeOneTimeAccrualLocalData, updateJeOneTimeAccrualLocalData, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys, };
|
|
665
|
-
export { clearExpenseAutomationActualMatchingView, closeMatchNewModal, clearMatchNewModal, fetchExpenseAutomationActualMatching, fetchActualMatchingMatch, fetchExpenseAutomationActualMatchingPage, matchAndReverseAccruals, openMatchNewModal, searchMatchAccruals, searchMatchTransactions, undoReversalAccruals, updateExpenseAutomationActualMatchingUIState, };
|
|
665
|
+
export { ackCloseMatchAfterUndo, clearExpenseAutomationActualMatchingView, closeMatchNewModal, clearMatchNewModal, fetchExpenseAutomationActualMatching, fetchActualMatchingMatch, fetchExpenseAutomationActualMatchingPage, matchAndReverseAccruals, openMatchNewModal, searchMatchAccruals, searchMatchTransactions, undoReversalAccruals, updateExpenseAutomationActualMatchingUIState, };
|
|
666
666
|
export { createNewSchedulesAccrued, deleteScheduleAccruedDetail, cancelScheduleAccruedJournalEntry, fetchScheduleAccruedDetails, fetchScheduleAccruedDetailsPage, resetJEAccruedLinkInLocalData, saveScheduleAccruedDetails, updateAmountsInScheduleAccruedDetail, updatedJEAccruedLinkWithRecommendedLocalData, updatedJELinkInLocalDataAccruedExpenses, fetchRecommendedTransactionRowIndex, clearSelectedJELinkRowIndex, updateLinkBillExpenseLocalData, updateScheduleAccruedDetailsLocalData, updateSelectedJEAccruedScheduleKey, resetSelectedJEAccruedScheduleKey, resetAccruedDetailNewScheduleState, };
|
|
667
667
|
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, };
|
|
668
668
|
export { toVendorFirstReviewViewColumnKeyType, getGlobalMerchantAutoCompleteResults, getVendorFirstReviewView, getVendorFirstReviewAttachmentView, fetchVendorFirstReviewView, fetchVendorFirstReviewAttachments, updateVendorFirstReviewViewScrollYOffset, resetVendorFirstReviewLocalData, updateVendorFirstReviewViewPageToken, clearRecentlySavedErroredVendorData, saveVendorFirstReviewView, updateVendorFirstReviewViewLocalData, updateVendorFirstReviewSortUiState, fetchGlobalMerchantAutoCompleteView, clearGlobalMerchantAutoCompleteResults, updateReviewVendorDetailLocalData, saveVendorDetailsView, getVendorDetailSelectorView, };
|
|
@@ -866,4 +866,4 @@ export { getInvoicingOnboardingGateView } from './view/invoicing/invoicingConfig
|
|
|
866
866
|
// Accrued JE schedules are not a discriminated union member, so consumers need this guard to
|
|
867
867
|
// narrow a JEScheduleRow before reading baseTransaction / recurringAmount.
|
|
868
868
|
export { getExpenseAutomationJEOneTimeAccrualDetailView, getJEScheduleRowType, isAccruedScheduleRow, isAiAccountantSchedule, isExistingTabRow, isOneTimeAccrualRow, isRenderableOneTimeAccrual, isPendingReviewRow, } from './view/expenseAutomationView/selectors/jeSchedulesViewSelector';
|
|
869
|
-
export { getActualMatchingAmount, getActualMatchingReversalDate, parseActualMatchingMatchId, getExpenseAutomationActualMatchingMatchView, getExpenseAutomationActualMatchingView, isAutoReversedAccrual, isManuallyReversedAccrual, isPendingReviewAccrual, } from './view/expenseAutomationView/selectors/actualMatchingViewSelector';
|
|
869
|
+
export { getActualMatchingAmount, getActualMatchingReversalDate, getCloseMatchAfterUndo, parseActualMatchingMatchId, getExpenseAutomationActualMatchingMatchView, getExpenseAutomationActualMatchingView, isAutoReversedAccrual, isManuallyReversedAccrual, isPendingReviewAccrual, } from './view/expenseAutomationView/selectors/actualMatchingViewSelector';
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import { from, of } from 'rxjs';
|
|
2
2
|
import { catchError, filter, mergeMap, switchMap, takeUntil, } from 'rxjs/operators';
|
|
3
3
|
import { updateActualMatchingMatches } from '../../../../entity/actualMatching/actualMatchingReducer';
|
|
4
|
-
import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
|
|
5
4
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
6
5
|
import { clearAll } from '../../../../rootActions';
|
|
7
6
|
import { toServiceMonthFromPeriod, } from '../../payload/actualMatchingPayload';
|
|
8
7
|
import { fetchActualMatching, fetchActualMatchingFailure, fetchActualMatchingSuccess, } from '../../reducers/actualMatchingViewReducer';
|
|
8
|
+
import { getSelectedMonthYearForCurrentTenant, getTenantDisplayCurrency, } from '../../selectors/actualMatchingViewSelector';
|
|
9
9
|
export const fetchActualMatchingEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchActualMatching.match), switchMap((action) => {
|
|
10
10
|
const state = state$.value;
|
|
11
11
|
const { period, refreshViewInBackground } = action.payload;
|
|
12
|
-
const
|
|
13
|
-
const selectedPeriod = state.expenseAutomationViewState
|
|
14
|
-
.selectedPeriodByTenantId[currentTenant?.tenantId ?? ''] ?? {
|
|
12
|
+
const selectedPeriod = getSelectedMonthYearForCurrentTenant(state) ?? {
|
|
15
13
|
month: period.start.month,
|
|
16
14
|
year: period.start.year,
|
|
17
15
|
};
|
|
@@ -23,7 +21,7 @@ export const fetchActualMatchingEpic = (actions$, state$, zeniAPI) => actions$.p
|
|
|
23
21
|
const matches = response.data.matches;
|
|
24
22
|
const updateActions = [];
|
|
25
23
|
if (matches.length > 0) {
|
|
26
|
-
updateActions.push(updateActualMatchingMatches(matches));
|
|
24
|
+
updateActions.push(updateActualMatchingMatches(matches, getTenantDisplayCurrency(state)));
|
|
27
25
|
}
|
|
28
26
|
updateActions.push(fetchActualMatchingSuccess({
|
|
29
27
|
matchIds: matches.map((match) => match.match_id),
|
package/lib/esm/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingMatchEpic.js
CHANGED
|
@@ -4,14 +4,15 @@ import { updateActualMatchingMatches } from '../../../../entity/actualMatching/a
|
|
|
4
4
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
5
5
|
import { clearAll } from '../../../../rootActions';
|
|
6
6
|
import { fetchActualMatchingMatch, fetchActualMatchingMatchFailure, fetchActualMatchingMatchSuccess, } from '../../reducers/actualMatchingViewReducer';
|
|
7
|
-
|
|
7
|
+
import { getTenantDisplayCurrency } from '../../selectors/actualMatchingViewSelector';
|
|
8
|
+
export const fetchActualMatchingMatchEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchActualMatchingMatch.match), mergeMap((action) => {
|
|
8
9
|
const { matchId, refreshViewInBackground } = action.payload;
|
|
9
10
|
return zeniAPI
|
|
10
11
|
.getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals/actual-matching/${encodeURIComponent(matchId)}`)
|
|
11
12
|
.pipe(mergeMap((response) => {
|
|
12
13
|
if (isSuccessResponse(response) && response.data != null) {
|
|
13
14
|
return from([
|
|
14
|
-
updateActualMatchingMatches([response.data]),
|
|
15
|
+
updateActualMatchingMatches([response.data], getTenantDisplayCurrency(state$.value)),
|
|
15
16
|
fetchActualMatchingMatchSuccess({
|
|
16
17
|
matchId,
|
|
17
18
|
refreshViewInBackground,
|
package/lib/esm/view/expenseAutomationView/epics/actualMatching/matchAndReverseAccrualsEpic.js
CHANGED
|
@@ -1,52 +1,107 @@
|
|
|
1
1
|
import { from, of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap, takeUntil } from 'rxjs/operators';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { createZeniAPIStatus, isSuccessResponse
|
|
2
|
+
import { catchError, exhaustMap, filter, mergeMap, takeUntil } from 'rxjs/operators';
|
|
3
|
+
import { getActualMatchingMatchById } from '../../../../entity/actualMatching/actualMatchingSelector';
|
|
4
|
+
import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
|
|
5
|
+
import { createZeniAPIStatus, isSuccessResponse } from '../../../../responsePayload';
|
|
6
6
|
import { clearAll } from '../../../../rootActions';
|
|
7
7
|
import { toMatchAndReverseResult, } from '../../payload/actualMatchingPayload';
|
|
8
|
-
import { clearMatchNewModal,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
import { clearMatchNewModal, matchAndReverseAccruals, matchAndReverseAccrualsFailure, matchAndReverseAccrualsSuccess, } from '../../reducers/actualMatchingViewReducer';
|
|
9
|
+
import { refreshActualMatchingList } from './refreshActualMatchingList';
|
|
10
|
+
function isMatchCompleteStatus(status) {
|
|
11
|
+
return status === 'reversed' || status === 'noop';
|
|
12
|
+
}
|
|
13
|
+
function isMatchFailedStatus(status) {
|
|
14
|
+
return (status === 'conflict' || status === 'claim_lost' || status === 'error');
|
|
15
|
+
}
|
|
16
|
+
function matchAndReverseSnackbar(results, vendorName) {
|
|
17
|
+
const reversedCount = results.filter((result) => result.status === 'reversed').length;
|
|
18
|
+
const failedCount = results.filter((result) => isMatchFailedStatus(result.status)).length;
|
|
19
|
+
const variables = [
|
|
20
|
+
{ variableName: '_count_', variableValue: String(reversedCount) },
|
|
21
|
+
{ variableName: '_vendor_name_', variableValue: vendorName },
|
|
22
|
+
];
|
|
23
|
+
if (results.length === 0 || (reversedCount === 0 && failedCount > 0)) {
|
|
24
|
+
return openSnackbar({
|
|
25
|
+
messageSection: 'actual_matching_match_and_reverse',
|
|
26
|
+
messageText: 'failed',
|
|
27
|
+
type: 'error',
|
|
28
|
+
variables,
|
|
29
|
+
});
|
|
14
30
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
31
|
+
if (reversedCount > 0 && failedCount === 0) {
|
|
32
|
+
return openSnackbar({
|
|
33
|
+
messageSection: 'actual_matching_match_and_reverse',
|
|
34
|
+
messageText: 'success',
|
|
35
|
+
type: 'success',
|
|
36
|
+
variables,
|
|
37
|
+
});
|
|
20
38
|
}
|
|
21
|
-
|
|
39
|
+
if (reversedCount > 0 && failedCount > 0) {
|
|
40
|
+
return openSnackbar({
|
|
41
|
+
messageSection: 'actual_matching_match_and_reverse',
|
|
42
|
+
messageText: 'notification',
|
|
43
|
+
type: 'warning',
|
|
44
|
+
variables,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
function matchAndReverseHttpFailSnackbar(vendorName) {
|
|
50
|
+
return openSnackbar({
|
|
51
|
+
messageSection: 'actual_matching_match_and_reverse',
|
|
52
|
+
messageText: 'failed',
|
|
53
|
+
type: 'error',
|
|
54
|
+
variables: [
|
|
55
|
+
{ variableName: '_count_', variableValue: '0' },
|
|
56
|
+
{ variableName: '_vendor_name_', variableValue: vendorName },
|
|
57
|
+
],
|
|
58
|
+
});
|
|
22
59
|
}
|
|
23
|
-
|
|
24
|
-
|
|
60
|
+
function matchVendorName(state, matchId) {
|
|
61
|
+
return getActualMatchingMatchById(state.actualMatchingState, matchId)?.vendorName ?? '';
|
|
62
|
+
}
|
|
63
|
+
export const matchAndReverseAccrualsEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(matchAndReverseAccruals.match),
|
|
64
|
+
// Posts reversing JEs; drop duplicate clicks while a request is in flight.
|
|
65
|
+
exhaustMap((action) => {
|
|
66
|
+
const { transactionId, transactionIntegrationId, transactionType, lineIds, accrualIds, transactionSyncToken, } = action.payload;
|
|
25
67
|
const body = {
|
|
26
68
|
transaction_id: transactionId,
|
|
27
69
|
transaction_integration_id: transactionIntegrationId,
|
|
28
70
|
transaction_type: transactionType,
|
|
29
|
-
|
|
71
|
+
line_ids: lineIds,
|
|
30
72
|
transaction_sync_token: transactionSyncToken,
|
|
31
73
|
accrual_ids: accrualIds,
|
|
32
74
|
};
|
|
75
|
+
// Key leftover results and snackbar vendor to the confirmed bill, not the
|
|
76
|
+
// row Match New was opened from (user can pick a different txn).
|
|
77
|
+
const matchId = `${transactionType.toLowerCase()}:${transactionIntegrationId}`;
|
|
78
|
+
const vendorName = matchVendorName(state$.value, matchId);
|
|
33
79
|
return zeniAPI
|
|
34
80
|
.postAndGetJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals/match-and-reverse`, body)
|
|
35
81
|
.pipe(mergeMap((response) => {
|
|
36
82
|
if (isSuccessResponse(response) && response.data != null) {
|
|
37
83
|
const results = response.data.results.map(toMatchAndReverseResult);
|
|
38
84
|
const successActions = [
|
|
39
|
-
matchAndReverseAccrualsSuccess({ results }),
|
|
85
|
+
matchAndReverseAccrualsSuccess({ matchId, results }),
|
|
40
86
|
];
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
87
|
+
const occupancyChanged = results.some((result) => isMatchCompleteStatus(result.status));
|
|
88
|
+
const allComplete = results.length > 0 &&
|
|
89
|
+
results.every((result) => isMatchCompleteStatus(result.status));
|
|
90
|
+
if (occupancyChanged) {
|
|
91
|
+
successActions.push(...refreshActualMatchingList(state$.value));
|
|
92
|
+
}
|
|
93
|
+
const snackbar = matchAndReverseSnackbar(results, vendorName);
|
|
94
|
+
if (snackbar != null) {
|
|
95
|
+
successActions.push(snackbar);
|
|
96
|
+
}
|
|
97
|
+
if (allComplete) {
|
|
98
|
+
successActions.push(clearMatchNewModal());
|
|
44
99
|
}
|
|
45
100
|
return from(successActions);
|
|
46
101
|
}
|
|
47
|
-
return of(matchAndReverseAccrualsFailure({ status: response.status }));
|
|
102
|
+
return of(matchAndReverseAccrualsFailure({ status: response.status }), matchAndReverseHttpFailSnackbar(vendorName));
|
|
48
103
|
}), catchError((error) => of(matchAndReverseAccrualsFailure({
|
|
49
104
|
status: createZeniAPIStatus('Unexpected Error', 'Match and reverse accruals REST API call errored out' +
|
|
50
105
|
JSON.stringify(error)),
|
|
51
|
-
}))), takeUntil(actions$.pipe(filter(clearAll.match))));
|
|
106
|
+
}), matchAndReverseHttpFailSnackbar(vendorName))), takeUntil(actions$.pipe(filter(clearAll.match))));
|
|
52
107
|
}));
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { convertToPeriod, toAbsoluteDay, } from '../../../../commonStateTypes/timePeriod';
|
|
2
|
+
import { fetchActualMatching } from '../../reducers/actualMatchingViewReducer';
|
|
3
|
+
import { getSelectedMonthYearForCurrentTenant } from '../../selectors/actualMatchingViewSelector';
|
|
4
|
+
export function refreshActualMatchingList(state) {
|
|
5
|
+
const selectedMonthYear = getSelectedMonthYearForCurrentTenant(state);
|
|
6
|
+
if (selectedMonthYear == null) {
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
const period = convertToPeriod(selectedMonthYear);
|
|
10
|
+
const start = toAbsoluteDay(period.start);
|
|
11
|
+
const end = toAbsoluteDay(period.end);
|
|
12
|
+
if (start == null || end == null) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
return [fetchActualMatching({ start, end }, true)];
|
|
16
|
+
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { from, merge, of } from 'rxjs';
|
|
2
|
-
import { catchError, debounceTime, filter, mergeMap, switchMap, } from 'rxjs/operators';
|
|
2
|
+
import { catchError, debounceTime, filter, mergeMap, switchMap, takeUntil, } from 'rxjs/operators';
|
|
3
|
+
import { withInheritedAccrualCurrency } from '../../../../entity/actualMatching/actualMatchingPayload';
|
|
3
4
|
import { updateJEOneTimeAccruals } from '../../../../entity/jeSchedules/jeSchedulesReducer';
|
|
4
5
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
6
|
+
import { clearAll } from '../../../../rootActions';
|
|
5
7
|
import { searchMatchAccruals, searchMatchAccrualsFailure, searchMatchAccrualsSuccess, } from '../../reducers/actualMatchingViewReducer';
|
|
8
|
+
import { getTenantDisplayCurrency } from '../../selectors/actualMatchingViewSelector';
|
|
6
9
|
import { MATCH_ACCRUAL_SEARCH_LIMIT, MATCH_SEARCH_DEBOUNCE_MS, } from '../../types/actualMatchingViewState';
|
|
7
|
-
export const searchMatchAccrualsEpic = (actions$,
|
|
10
|
+
export const searchMatchAccrualsEpic = (actions$, state$, zeniAPI) => {
|
|
8
11
|
const searchActions$ = actions$.pipe(filter(searchMatchAccruals.match));
|
|
9
12
|
const pagination$ = searchActions$.pipe(filter((action) => action.payload.pageToken != null));
|
|
10
13
|
const newSearchDebounced$ = searchActions$.pipe(filter((action) => action.payload.pageToken == null), debounceTime(MATCH_SEARCH_DEBOUNCE_MS));
|
|
@@ -22,14 +25,18 @@ export const searchMatchAccrualsEpic = (actions$, _state$, zeniAPI) => {
|
|
|
22
25
|
const nextOffset = offset + accruals.length;
|
|
23
26
|
const total = response.data.total ?? nextOffset;
|
|
24
27
|
const nextPageToken = nextOffset < total ? String(nextOffset) : null;
|
|
28
|
+
// toJEOneTimeAccrual still defaults a missing code to USD. Stamp
|
|
29
|
+
// tenant currency first, same as list members.
|
|
30
|
+
const fallbackCurrencyCode = getTenantDisplayCurrency(state$.value)?.currencyCode ?? '';
|
|
31
|
+
const stampedAccruals = accruals.map((accrual) => withInheritedAccrualCurrency(accrual, fallbackCurrencyCode));
|
|
25
32
|
const actionsOut = [];
|
|
26
|
-
if (
|
|
27
|
-
actionsOut.push(updateJEOneTimeAccruals(
|
|
33
|
+
if (stampedAccruals.length > 0) {
|
|
34
|
+
actionsOut.push(updateJEOneTimeAccruals(stampedAccruals));
|
|
28
35
|
}
|
|
29
36
|
actionsOut.push(searchMatchAccrualsSuccess({
|
|
30
37
|
append,
|
|
31
38
|
nextPageToken,
|
|
32
|
-
results:
|
|
39
|
+
results: stampedAccruals,
|
|
33
40
|
}));
|
|
34
41
|
return from(actionsOut);
|
|
35
42
|
}
|
|
@@ -39,6 +46,9 @@ export const searchMatchAccrualsEpic = (actions$, _state$, zeniAPI) => {
|
|
|
39
46
|
}), catchError((error) => of(searchMatchAccrualsFailure({
|
|
40
47
|
error: createZeniAPIStatus('Unexpected Error', 'Search match accruals REST API call errored out' +
|
|
41
48
|
JSON.stringify(error)),
|
|
42
|
-
})))
|
|
49
|
+
}))),
|
|
50
|
+
// On the HTTP stream only. Wrapping the outer merge would complete
|
|
51
|
+
// the epic on the first `clearAll` and drop later searches.
|
|
52
|
+
takeUntil(actions$.pipe(filter(clearAll.match))));
|
|
43
53
|
}));
|
|
44
54
|
};
|
package/lib/esm/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { from, merge, of } from 'rxjs';
|
|
2
|
-
import { catchError, debounceTime, filter, mergeMap, switchMap, } from 'rxjs/operators';
|
|
2
|
+
import { catchError, debounceTime, filter, mergeMap, switchMap, takeUntil, } from 'rxjs/operators';
|
|
3
3
|
import { getActualMatchingMatchById } from '../../../../entity/actualMatching/actualMatchingSelector';
|
|
4
4
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
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 { parseActualMatchingMatchId } 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
11
|
const openModal$ = actions$.pipe(filter(openMatchNewModal.match), mergeMap((action) => {
|
|
11
12
|
const matchId = action.payload.matchId;
|
|
12
13
|
if (matchId == null || matchId === '') {
|
|
13
14
|
return from([
|
|
14
|
-
searchMatchTransactions(
|
|
15
|
-
searchMatchAccruals(
|
|
15
|
+
searchMatchTransactions(''),
|
|
16
|
+
searchMatchAccruals(''),
|
|
16
17
|
]);
|
|
17
18
|
}
|
|
18
19
|
const match = getActualMatchingMatchById(state$.value.actualMatchingState, matchId);
|
|
@@ -25,11 +26,7 @@ export const searchMatchTransactionsEpic = (actions$, state$, zeniAPI) => {
|
|
|
25
26
|
? match.transactionIntegrationId
|
|
26
27
|
: parsed?.transactionIntegrationId;
|
|
27
28
|
return from([
|
|
28
|
-
searchMatchTransactions(
|
|
29
|
-
query: '',
|
|
30
|
-
transactionType,
|
|
31
|
-
transactionIntegrationId,
|
|
32
|
-
}),
|
|
29
|
+
searchMatchTransactions('', undefined, transactionType, transactionIntegrationId),
|
|
33
30
|
]);
|
|
34
31
|
}));
|
|
35
32
|
const searchActions$ = actions$.pipe(filter(searchMatchTransactions.match));
|
|
@@ -54,7 +51,8 @@ export const searchMatchTransactionsEpic = (actions$, state$, zeniAPI) => {
|
|
|
54
51
|
if (isSuccessResponse(response) && response.data != null) {
|
|
55
52
|
const { transactions, next_page_token } = response.data;
|
|
56
53
|
const append = pageToken != null;
|
|
57
|
-
const
|
|
54
|
+
const fallbackCurrency = getTenantDisplayCurrency(state$.value);
|
|
55
|
+
const results = transactions.map((transaction) => toActualMatchingTransactionSearchResult(transaction, fallbackCurrency));
|
|
58
56
|
return of(searchMatchTransactionsSuccess({
|
|
59
57
|
append,
|
|
60
58
|
nextPageToken: next_page_token ?? null,
|
|
@@ -67,7 +65,10 @@ export const searchMatchTransactionsEpic = (actions$, state$, zeniAPI) => {
|
|
|
67
65
|
}), catchError((error) => of(searchMatchTransactionsFailure({
|
|
68
66
|
error: createZeniAPIStatus('Unexpected Error', 'Search match transactions REST API call errored out' +
|
|
69
67
|
JSON.stringify(error)),
|
|
70
|
-
})))
|
|
68
|
+
}))),
|
|
69
|
+
// On the HTTP stream only. Wrapping `merge(openModal$, search$)`
|
|
70
|
+
// would complete the epic on the first `clearAll` and drop later searches.
|
|
71
|
+
takeUntil(actions$.pipe(filter(clearAll.match))));
|
|
71
72
|
}));
|
|
72
73
|
return merge(openModal$, search$);
|
|
73
74
|
};
|
|
@@ -1,52 +1,76 @@
|
|
|
1
1
|
import { from, of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap, takeUntil } from 'rxjs/operators';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { catchError, exhaustMap, filter, mergeMap, takeUntil, } from 'rxjs/operators';
|
|
3
|
+
import { getActualMatchingMatchById } from '../../../../entity/actualMatching/actualMatchingSelector';
|
|
4
|
+
import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
|
|
5
5
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
6
6
|
import { clearAll } from '../../../../rootActions';
|
|
7
7
|
import { toUndoReversalResult, } from '../../payload/actualMatchingPayload';
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
import { fetchActualMatchingMatch, undoReversalAccruals, undoReversalAccrualsFailure, undoReversalAccrualsSuccess, } from '../../reducers/actualMatchingViewReducer';
|
|
9
|
+
import { refreshActualMatchingList } from './refreshActualMatchingList';
|
|
10
|
+
function undoReversalSnackbar(results, vendorName) {
|
|
11
|
+
const undoneCount = results.filter((result) => result.status === 'undone').length;
|
|
12
|
+
const failedCount = results.length - undoneCount;
|
|
13
|
+
const variables = [
|
|
14
|
+
{ variableName: '_count_', variableValue: String(undoneCount) },
|
|
15
|
+
{ variableName: '_vendor_name_', variableValue: vendorName },
|
|
16
|
+
];
|
|
17
|
+
if (results.length > 0 && failedCount === 0) {
|
|
18
|
+
return openSnackbar({
|
|
19
|
+
messageSection: 'actual_matching_undo_reversal',
|
|
20
|
+
messageText: 'success',
|
|
21
|
+
type: 'success',
|
|
22
|
+
variables,
|
|
23
|
+
});
|
|
14
24
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
25
|
+
if (undoneCount > 0 && failedCount > 0) {
|
|
26
|
+
return openSnackbar({
|
|
27
|
+
messageSection: 'actual_matching_undo_reversal',
|
|
28
|
+
messageText: 'notification',
|
|
29
|
+
type: 'warning',
|
|
30
|
+
variables,
|
|
31
|
+
});
|
|
20
32
|
}
|
|
21
|
-
return
|
|
33
|
+
return openSnackbar({
|
|
34
|
+
messageSection: 'actual_matching_undo_reversal',
|
|
35
|
+
messageText: 'failed',
|
|
36
|
+
type: 'error',
|
|
37
|
+
variables,
|
|
38
|
+
});
|
|
22
39
|
}
|
|
23
|
-
function
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
.filter((matchId) => detailState[matchId]?.fetchState !== 'Not-Started')
|
|
27
|
-
.map((matchId) => fetchActualMatchingMatch(matchId, true));
|
|
40
|
+
function matchVendorName(state, matchId) {
|
|
41
|
+
return (getActualMatchingMatchById(state.actualMatchingState, matchId)?.vendorName ??
|
|
42
|
+
'');
|
|
28
43
|
}
|
|
29
|
-
export const undoReversalAccrualsEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(undoReversalAccruals.match),
|
|
44
|
+
export const undoReversalAccrualsEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(undoReversalAccruals.match),
|
|
45
|
+
// Posts QBO deletes; drop duplicate clicks while the first request is in flight.
|
|
46
|
+
exhaustMap((action) => {
|
|
47
|
+
const { accrualIds, matchId } = action.payload;
|
|
30
48
|
const body = {
|
|
31
|
-
accrual_ids:
|
|
49
|
+
accrual_ids: accrualIds,
|
|
32
50
|
};
|
|
51
|
+
const vendorName = matchVendorName(state$.value, matchId);
|
|
33
52
|
return zeniAPI
|
|
34
53
|
.postAndGetJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals/undo-reversal`, body)
|
|
35
54
|
.pipe(mergeMap((response) => {
|
|
36
55
|
if (isSuccessResponse(response) && response.data != null) {
|
|
37
56
|
const results = response.data.results.map(toUndoReversalResult);
|
|
38
57
|
const successActions = [
|
|
39
|
-
undoReversalAccrualsSuccess(
|
|
58
|
+
undoReversalAccrualsSuccess(matchId, results),
|
|
40
59
|
];
|
|
41
60
|
const anyUndone = results.some((result) => result.status === 'undone');
|
|
42
61
|
if (anyUndone) {
|
|
43
|
-
successActions.push(...refreshActualMatchingList(state$.value),
|
|
62
|
+
successActions.push(...refreshActualMatchingList(state$.value), fetchActualMatchingMatch(matchId, true));
|
|
44
63
|
}
|
|
64
|
+
successActions.push(undoReversalSnackbar(results, vendorName));
|
|
45
65
|
return from(successActions);
|
|
46
66
|
}
|
|
47
|
-
return of(undoReversalAccrualsFailure({
|
|
67
|
+
return of(undoReversalAccrualsFailure({
|
|
68
|
+
matchId,
|
|
69
|
+
status: response.status,
|
|
70
|
+
}), undoReversalSnackbar([], vendorName));
|
|
48
71
|
}), catchError((error) => of(undoReversalAccrualsFailure({
|
|
72
|
+
matchId,
|
|
49
73
|
status: createZeniAPIStatus('Unexpected Error', 'Undo reversal accruals REST API call errored out' +
|
|
50
74
|
JSON.stringify(error)),
|
|
51
|
-
}))), takeUntil(actions$.pipe(filter(clearAll.match))));
|
|
75
|
+
}), undoReversalSnackbar([], vendorName))), takeUntil(actions$.pipe(filter(clearAll.match))));
|
|
52
76
|
}));
|
package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js
CHANGED
|
@@ -3,7 +3,6 @@ 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';
|
|
7
6
|
import { fetchFluxAnalysisView } from '../../reducers/fluxAnalysisViewReducer';
|
|
8
7
|
import { fetchJeSchedulesPage } from '../../reducers/jeSchedulesViewReducer';
|
|
9
8
|
import { fetchMissingReceipts } from '../../reducers/missingReceiptsViewReducer';
|
|
@@ -11,7 +10,7 @@ import { fetchReconciliation } from '../../reducers/reconciliationViewReducer';
|
|
|
11
10
|
import { fetchTransactionCategorizationView } from '../../reducers/transactionsViewReducer';
|
|
12
11
|
import { getJESchedulePeriodTabKey } from '../../types/jeSchedulesViewState';
|
|
13
12
|
export const fetchAllExpenseAutomationTabsEpic = (actions$, state$) => actions$.pipe(filter(fetchAllExpenseAutomationTabs.match), switchMap((action) => {
|
|
14
|
-
const { cacheOverride, refreshViewInBackground } = action.payload;
|
|
13
|
+
const { cacheOverride, refreshViewInBackground, isAccrualEnabled } = action.payload;
|
|
15
14
|
const state = state$.value;
|
|
16
15
|
const { monthEndCloseChecksState } = state;
|
|
17
16
|
const { monthEndCloseChecksByTenantId } = monthEndCloseChecksState;
|
|
@@ -32,14 +31,11 @@ export const fetchAllExpenseAutomationTabsEpic = (actions$, state$) => actions$.
|
|
|
32
31
|
}
|
|
33
32
|
if (cacheOverride === true) {
|
|
34
33
|
const actions = [];
|
|
35
|
-
const selectedPageTab = state.expenseAutomationJESchedulesViewState.uiState.selectedPageTab;
|
|
36
34
|
actions.push(fetchTransactionCategorizationView(selectedTransactionCategorizationTab, { start: timePeriodStart, end: timePeriodEnd }, cacheOverride, false, undefined, undefined, refreshViewInBackground, false), fetchMissingReceipts({ start: timePeriodStart, end: timePeriodEnd }, {
|
|
37
35
|
amount: 75.0,
|
|
38
36
|
currencyCode: 'USD',
|
|
39
37
|
currencySymbol: '$',
|
|
40
|
-
}, cacheOverride, refreshViewInBackground), fetchFluxAnalysisView(selectedPeriod, cacheOverride, refreshViewInBackground, null),
|
|
41
|
-
? fetchActualMatchingPage({ start: timePeriodStart, end: timePeriodEnd }, cacheOverride)
|
|
42
|
-
: fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, cacheOverride));
|
|
38
|
+
}, cacheOverride, refreshViewInBackground), fetchFluxAnalysisView(selectedPeriod, cacheOverride, refreshViewInBackground, null), fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, cacheOverride, isAccrualEnabled));
|
|
43
39
|
if (reconciliationEnabled) {
|
|
44
40
|
actions.push(fetchReconciliation(selectedPeriod, undefined, cacheOverride, refreshViewInBackground));
|
|
45
41
|
}
|
|
@@ -66,7 +62,7 @@ export const fetchAllExpenseAutomationTabsEpic = (actions$, state$) => actions$.
|
|
|
66
62
|
}
|
|
67
63
|
// The two JE tabs cache separately, so only the tab actually being shown decides whether a
|
|
68
64
|
// fetch is still needed. Actual Matching is a third tab on the same page with its own
|
|
69
|
-
// endpoint
|
|
65
|
+
// endpoint; fetchJeSchedulesPage carries isAccrualEnabled so the prefetch epic can warm AM.
|
|
70
66
|
const selectedPageTab = state.expenseAutomationJESchedulesViewState.uiState.selectedPageTab;
|
|
71
67
|
if (selectedPageTab === 'actual_matching') {
|
|
72
68
|
const actualMatchingPeriodKeys = state.expenseAutomationActualMatchingViewState.matchIdsByPeriod[monthYearPeriodId];
|
|
@@ -74,7 +70,7 @@ export const fetchAllExpenseAutomationTabsEpic = (actions$, state$) => actions$.
|
|
|
74
70
|
'In-Progress' &&
|
|
75
71
|
(!state.expenseAutomationActualMatchingViewState.hasValidState() ||
|
|
76
72
|
actualMatchingPeriodKeys == null)) {
|
|
77
|
-
fetchActions.push(
|
|
73
|
+
fetchActions.push(fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, cacheOverride, isAccrualEnabled));
|
|
78
74
|
}
|
|
79
75
|
}
|
|
80
76
|
else {
|
|
@@ -86,7 +82,7 @@ export const fetchAllExpenseAutomationTabsEpic = (actions$, state$) => actions$.
|
|
|
86
82
|
.jeScheduleTransactionKeysByPeriodAndTab[jeSchedulesPeriodTabKey] == null ||
|
|
87
83
|
state.expenseAutomationJESchedulesViewState
|
|
88
84
|
.failedJeScheduleTransactionKeysByPeriodAndTab[jeSchedulesPeriodTabKey] == null)) {
|
|
89
|
-
fetchActions.push(fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, cacheOverride));
|
|
85
|
+
fetchActions.push(fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, cacheOverride, isAccrualEnabled));
|
|
90
86
|
}
|
|
91
87
|
}
|
|
92
88
|
if (state.expenseAutomationReconciliationViewState.fetchState !==
|
package/lib/esm/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.js
CHANGED
|
@@ -4,7 +4,6 @@ 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';
|
|
8
7
|
import { fetchFluxAnalysisView } from '../../reducers/fluxAnalysisViewReducer';
|
|
9
8
|
import { fetchJeSchedulesPage } from '../../reducers/jeSchedulesViewReducer';
|
|
10
9
|
import { fetchMissingReceipts } from '../../reducers/missingReceiptsViewReducer';
|
|
@@ -39,17 +38,10 @@ export const refreshExpenseAutomationCurrentTabEpic = (actions$, state$) => acti
|
|
|
39
38
|
return from([
|
|
40
39
|
fetchFluxAnalysisView(selectedPeriod, true, true, null),
|
|
41
40
|
]);
|
|
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
|
-
}
|
|
41
|
+
case 'je_schedules':
|
|
49
42
|
return from([
|
|
50
43
|
fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, true),
|
|
51
44
|
]);
|
|
52
|
-
}
|
|
53
45
|
case 'month_end_insights':
|
|
54
46
|
return from([
|
|
55
47
|
fetchCompanyMonthEndReportView(true, companyId, currentTenant.tenantId, period.end, true),
|