@zeniai/client-epic-state 5.1.55 → 5.1.57-beta0GS

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 (40) hide show
  1. package/lib/entity/accountRecon/accountReconPayload.d.ts +1 -1
  2. package/lib/entity/accountRecon/accountReconReducer.js +15 -1
  3. package/lib/entity/tenant/clearAllEpic.d.ts +2 -1
  4. package/lib/entity/tenant/clearAllEpic.js +2 -0
  5. package/lib/epic.d.ts +3 -1
  6. package/lib/epic.js +3 -1
  7. package/lib/esm/entity/accountRecon/accountReconReducer.js +15 -1
  8. package/lib/esm/entity/tenant/clearAllEpic.js +2 -0
  9. package/lib/esm/epic.js +3 -1
  10. package/lib/esm/index.js +5 -3
  11. package/lib/esm/reducer.js +3 -0
  12. package/lib/esm/view/expenseAutomationView/selectors/statementParseViewSelector.js +0 -224
  13. package/lib/esm/view/settings/jeScheduleApprovalRules/epic/fetchJEScheduleApprovalRulesEpic.js +21 -0
  14. package/lib/esm/view/settings/jeScheduleApprovalRules/epic/saveJEScheduleApprovalRulesEpic.js +20 -0
  15. package/lib/esm/view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesPayload.js +1 -0
  16. package/lib/esm/view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesReducer.js +76 -0
  17. package/lib/esm/view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesSelector.js +9 -0
  18. package/lib/esm/view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesState.js +1 -0
  19. package/lib/esm/view/transactionDetail/transactionDetailLocalDataHelper.js +28 -0
  20. package/lib/index.d.ts +8 -4
  21. package/lib/index.js +46 -42
  22. package/lib/reducer.d.ts +3 -0
  23. package/lib/reducer.js +3 -0
  24. package/lib/view/expenseAutomationView/selectors/statementParseViewSelector.d.ts +1 -15
  25. package/lib/view/expenseAutomationView/selectors/statementParseViewSelector.js +1 -233
  26. package/lib/view/expenseAutomationView/types/reconciliationViewState.d.ts +7 -44
  27. package/lib/view/settings/jeScheduleApprovalRules/epic/fetchJEScheduleApprovalRulesEpic.d.ts +7 -0
  28. package/lib/view/settings/jeScheduleApprovalRules/epic/fetchJEScheduleApprovalRulesEpic.js +25 -0
  29. package/lib/view/settings/jeScheduleApprovalRules/epic/saveJEScheduleApprovalRulesEpic.d.ts +6 -0
  30. package/lib/view/settings/jeScheduleApprovalRules/epic/saveJEScheduleApprovalRulesEpic.js +24 -0
  31. package/lib/view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesPayload.d.ts +29 -0
  32. package/lib/view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesPayload.js +2 -0
  33. package/lib/view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesReducer.d.ts +16 -0
  34. package/lib/view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesReducer.js +80 -0
  35. package/lib/view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesSelector.d.ts +12 -0
  36. package/lib/view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesSelector.js +12 -0
  37. package/lib/view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesState.d.ts +8 -0
  38. package/lib/view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesState.js +2 -0
  39. package/lib/view/transactionDetail/transactionDetailLocalDataHelper.js +28 -0
  40. package/package.json +1 -1
package/lib/esm/index.js CHANGED
@@ -176,8 +176,8 @@ import { acknowledgeBulkUploadConfirmMatchComplete, bulkUploadAutomatchingTimedO
176
176
  import { clearStatementDateConflict, deleteAccountStatement, excludeAccountFromReconciliation, fetchReconciliation as fetchReconciliationView, includeAccountInReconciliation, parseStatement, parseStatementFailure, parseStatementSuccess, reparseStatement, reparseStatementFailure, reparseStatementSuccess, resetReparseStatementStatus, saveReconciliationDetail as saveExpenseAutomationReconciliationDetail, saveReconciliationReview as saveExpenseAutomationReconciliationReview, setConnectionInProgressForAccount as setConnectionInProgressForAccountReconciliation, setStatementParseInProgress, setStatementProcessingDismissedToBackground, submitStatementUpdate, updateAccountReconciliationLocalData as updateExpenseAutomationAccountReconciliationLocalData, updateSelectedAccountId as updateExpenseAutomationAccountReconciliationSelectedAccountId, updateSelectedTab as updateExpenseAutomationAccountReconciliationSelectedTab, updateReconListScrollPosition as updateExpenseAutomationReconListScrollPosition, updateReviewTabSortState as updateExpenseAutomationReconReviewTabListSortState, updateReviewTabLocalData as updateExpenseAutomationReconReviewTabLocalData, updateReconcileTabListScrollState as updateExpenseAutomationReconcileTabListScrollState, updateReconcileTabListSortState as updateExpenseAutomationReconcileTabListSortState, updateReconcileTabLocalData as updateExpenseAutomationReconcileTabLocalData, updateSelectedDrawerAccountId as updateExpenseAutomationSelectedDrawerAccountId, updateNodeCollapseState, updateParsedStatementData, updateStatementProcessingBackgroundCompletedSteps, updateStatementProcessingFailed, updateStatementUpdateLocalData, updateStatementUploadChosen, uploadAccountStatement, } from './view/expenseAutomationView/reducers/reconciliationViewReducer';
177
177
  import { backgroundRefetchReviewTab, clearExpenseAutomationTransactionsView, fetchTransactionCategorization, fetchTransactionCategorizationFailure, fetchTransactionCategorizationView, initializeTransactionCategorizationViewLocalData, markCategoryClassRecommendationsFailureForCategorization, markTransactionAsNotMiscategorized, removeTransactionFromAllTabs, saveTransactionCategorization, saveTransactionCategorizationLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, setEntityRecommendationForLineIdsForCategorization, syncTransactionCategorizationFromDetailSave, updateCurrentSelectedTransactionCategorizationTab, updateSelectedCheckboxTransactionIds, updateSelectedCustomerForTransaction, updateSelectedTransactionId, updateSelectedVendorForTransaction, updateTransactionCategorization, updateTransactionCategorizationCompletedSubTab, updateTransactionCategorizationSaveStatus, updateTransactionCategorizationUIState, updateTransactionCategorizationUploadReceiptState, updateTransactionFilters, uploadTransactionCategorizationReceiptSuccess, } from './view/expenseAutomationView/reducers/transactionsViewReducer';
178
178
  import { getExpenseAutomationFluxAnalysisView } from './view/expenseAutomationView/selectors/fluxAnalysisViewSelector';
179
+ import { getJEAccountSettingsView } from './view/expenseAutomationView/selectors/jeAccountSettingsViewSelector';
179
180
  import { getExpenseAutomationReconciliationView, getReparseStatementStatusByAccountId, isAccountReconReport, } from './view/expenseAutomationView/selectors/reconciliationViewSelector';
180
- import { applyStatementParseFormChange, areStatementParseBalancesConsistent, getStatementParseFormView, } from './view/expenseAutomationView/selectors/statementParseViewSelector';
181
181
  import { getExpenseAutomationTransactionView, getLastTransferEntryReplacement, } from './view/expenseAutomationView/selectors/transactionCategorizationSelector';
182
182
  import { TRANSACTION_FILTER_CATEGORIES, applyTransactionFilters, } from './view/expenseAutomationView/transactionFilterHelpers';
183
183
  import { DEFAULT_COMPLETED_SUB_TAB, toCompletedSubTab, } from './view/expenseAutomationView/types/completedSubTab';
@@ -286,6 +286,8 @@ import { clearBillPayReview, fetchDuplicateBill, } from './view/spendManagement/
286
286
  import { getReviewPageBillDetail, } from './view/spendManagement/billPay/billPayReview/billPayReviewSelector';
287
287
  import { clearBillPaySetupApproverView, clearBillPaySetupApproverViewUpdateData, deleteBillPayApprovalRule, fetchBillPayApproversDetails, fetchBillPayApproversList, fetchBillPaySetupApproverView, initializeBillPaySetupApproverViewUpdateData, reorderBillPayApprovalRules, saveBillPaySetupApproverViewUpdateData, saveBillPaySetupApproverViewUpdates, setListeningToPusherEvent as setBillsSetupApproverViewListeningToPusherEvent, } from './view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewReducer';
288
288
  import { getBillPaySetupApproverUpdateDataView, getBillPaySetupApproverView, } from './view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewSelector';
289
+ import { clearJEScheduleApprovalRules, fetchJEScheduleApprovalRules, saveJEScheduleApprovalRules, } from './view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesReducer';
290
+ import { getJEScheduleApprovalRulesView } from './view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesSelector';
289
291
  import { acceptBillPayTerms, acceptBillPayUpdatedTerms, clearBillPaySetupView, fetchBillPaySetupView, } from './view/spendManagement/billPay/billPaySetupView/billPaySetupViewReducer';
290
292
  import { getBillPayBusinessVerificationDetails, getBillPaySetupViewDetails, } from './view/spendManagement/billPay/billPaySetupView/billPaySetupViewSelector';
291
293
  import { approveOrRejectBillsBulkAction, autoReviewPendingApprovalBills, cancelOrDeleteBillsBulkAction, clearAllBillsFromBulkActionList, clearBillPayBulkActionView, incrementBulkActionProcessedCount, removeBillFromBulkActionList, submitDraftBillsBulkAction, updateBillsBulkActionList, validateBillsBulkAction, } from './view/spendManagement/billPay/billsBulkActionView/billsBulkActionViewReducer';
@@ -462,7 +464,7 @@ export {
462
464
  // Bulk Upload Types
463
465
  BATCH_FILE_STATUSES, isUnmatchedTabFileStatus, DEFAULT_COMPLETED_SUB_TAB, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toCompletedSubTab, toMatchSource, toMissingReceiptsTab, toExpenseAutomationJEScheduleMainTab, toExpenseAutomationJEScheduleSortKey, getExpenseAutomationView, toExpenseAutomationMissingReceiptsSortKey, toExpenseAutomationTransactionsTabKey, toExpenseAutomationViewType, uploadExpenseAutomationMissingReceiptSuccess, markExpenseAutomationMissingReceiptAsDone, fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedTransactionCategorizationTab, updateTransactionCategorizationCompletedSubTab, fetchExpenseAutomationMissingReceipts,
464
466
  // Bulk Upload Actions
465
- 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, getReparseStatementStatusByAccountId, applyStatementParseFormChange, areStatementParseBalancesConsistent, getStatementParseFormView, fetchReconciliationView, uploadAccountStatementIntoDocumentAI, updateExpenseAutomationReconListScrollPosition, setConnectionInProgressForAccountReconciliation, getAccountReconByAccountIdAndSelectedPeriod, toReconciliationTabsType, isAccountReconReport, updateExpenseAutomationReconReviewTabLocalData, updateExpenseAutomationSelectedDrawerAccountId, updateStatementProcessingFailed, saveExpenseAutomationReconciliationReview, updateExpenseAutomationAccountReconciliationLocalData, toReconciliationAccountSource, deleteAccountStatement, uploadAccountStatement, parseStatement, parseStatementSuccess, parseStatementFailure, reparseStatement, reparseStatementSuccess, reparseStatementFailure, resetReparseStatementStatus, updateParsedStatementData, updateNodeCollapseState, updateStatementUploadChosen, submitStatementUpdate, clearStatementDateConflict, updateStatementUpdateLocalData, isReviewTransactionBankTransferType, isReviewTransactionBillPaymentType, isReviewTransactionCreditCardPaymentType, isReviewTransactionDepositType, isReviewTransactionExpenseType, isReviewTransactionCreditCardCreditType, setStatementParseInProgress, setStatementProcessingDismissedToBackground, updateStatementProcessingBackgroundCompletedSteps, };
467
+ 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, getJEAccountSettingsView, updateCurrentSelectedView, updateCurrentSelectedPeriod, getExpenseAutomationTransactionView, getLastTransferEntryReplacement, updateFluxAnalysisViewUIState, updateFluxAnalysisViewPageMetaData, MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, getLineItemsByTransactionIdsFromLocalData, isAnyItemWithUncategorizedExpenseAccount, excludeAccountFromReconciliation, includeAccountInReconciliation, saveExpenseAutomationReconciliationDetail, updateExpenseAutomationReconcileTabListScrollState, updateExpenseAutomationReconReviewTabListSortState, updateExpenseAutomationReconcileTabListSortState, updateExpenseAutomationReconcileTabLocalData, updateExpenseAutomationAccountReconciliationSelectedTab, updateExpenseAutomationAccountReconciliationSelectedAccountId, getExpenseAutomationReconciliationView, getReparseStatementStatusByAccountId, fetchReconciliationView, uploadAccountStatementIntoDocumentAI, updateExpenseAutomationReconListScrollPosition, setConnectionInProgressForAccountReconciliation, getAccountReconByAccountIdAndSelectedPeriod, toReconciliationTabsType, isAccountReconReport, updateExpenseAutomationReconReviewTabLocalData, updateExpenseAutomationSelectedDrawerAccountId, updateStatementProcessingFailed, saveExpenseAutomationReconciliationReview, updateExpenseAutomationAccountReconciliationLocalData, toReconciliationAccountSource, deleteAccountStatement, uploadAccountStatement, parseStatement, parseStatementSuccess, parseStatementFailure, reparseStatement, reparseStatementSuccess, reparseStatementFailure, resetReparseStatementStatus, updateParsedStatementData, updateNodeCollapseState, updateStatementUploadChosen, submitStatementUpdate, clearStatementDateConflict, updateStatementUpdateLocalData, isReviewTransactionBankTransferType, isReviewTransactionBillPaymentType, isReviewTransactionCreditCardPaymentType, isReviewTransactionDepositType, isReviewTransactionExpenseType, isReviewTransactionCreditCardCreditType, setStatementParseInProgress, setStatementProcessingDismissedToBackground, updateStatementProcessingBackgroundCompletedSteps, };
466
468
  export { fetchTransactionCategorization, fetchTransactionCategorizationView, updateTransactionCategorizationUIState, updateTransactionFilters, updateSelectedCheckboxTransactionIds, markCategoryClassRecommendationsFailureForCategorization, setEntityRecommendationForLineIdsForCategorization, initializeTransactionCategorizationViewLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, updateSelectedTransactionId, syncTransactionCategorizationFromDetailSave, backgroundRefetchReviewTab, createTransferEntry, createTransferEntryFailure, createTransferEntryReplacedTransaction, createTransferEntrySuccess, resetCreateTransferEntryStatus, clearTransferEntryRouteReplacement, fetchAccountsForTransferFlow, removeTransactionFromAllTabs, clearExpenseAutomationTransactionsView, toTransactionsSortKey, };
467
469
  export { TOP_EX_TIME_PERIODS };
468
470
  export { toTimeframeTick, mapTimePeriodtoTimeframeTick, toTimePeriod, toAbsoluteDay, toMonthYearPeriodId, convertToPeriod, };
@@ -583,7 +585,7 @@ export { fetchRemiSetupView, updateMileageDetails, saveRemiSetupViewDataInLocalS
583
585
  export { VERIFIED_PAYMENT_ACCOUNT_PROVIDER_VERIFICATION_STATUS, };
584
586
  export { isSuccessResponse, isInvalidSessionError, isAccessDeniedError, };
585
587
  export { getAmountCriteria, getApprovalRulesByEntityType, getDepartmentCriteria, getFallbackApprovalRule, getVendorCriteria, toAttributeTypeStrict, toAttributeOrRoleTypeStrict, toRoleTypeStrict, detectRuleOverlap, };
586
- export { getBillPaySetupApproverView, getBillPaySetupApproverUpdateDataView, fetchBillPaySetupApproverView, fetchBillPayApproversDetails, fetchBillPayApproversList, deleteBillPayApprovalRule, reorderBillPayApprovalRules, saveBillPaySetupApproverViewUpdateData, saveBillPaySetupApproverViewUpdates, setBillsSetupApproverViewListeningToPusherEvent, initializeBillPaySetupApproverViewUpdateData, clearBillPaySetupApproverViewUpdateData, clearBillPaySetupApproverView, };
588
+ export { getBillPaySetupApproverView, getBillPaySetupApproverUpdateDataView, getJEScheduleApprovalRulesView, clearJEScheduleApprovalRules, fetchJEScheduleApprovalRules, saveJEScheduleApprovalRules, fetchBillPaySetupApproverView, fetchBillPayApproversDetails, fetchBillPayApproversList, deleteBillPayApprovalRule, reorderBillPayApprovalRules, saveBillPaySetupApproverViewUpdateData, saveBillPaySetupApproverViewUpdates, setBillsSetupApproverViewListeningToPusherEvent, initializeBillPaySetupApproverViewUpdateData, clearBillPaySetupApproverViewUpdateData, clearBillPaySetupApproverView, };
587
589
  export { getRemiSetupApproverView, getRemiSetupApproverUpdateDataView, fetchRemiSetupApproverView, fetchRemiApproversList, fetchRemiApproversDetails, deleteRemiApprovalRule, reorderRemiApprovalRules, saveRemiSetupApproverViewUpdateData, saveRemiSetupApproverViewUpdates, initializeRemiSetupApproverViewUpdateData, setRemiSetupApproverViewListeningToPusherEvent, clearRemiSetupApproverViewUpdateData, clearRemiSetupApproverView, };
588
590
  export { getRemiDetailView, checkApproveRejectBtnShowForRemi, };
589
591
  export { saveRealTimeApproval, updateIsEditModeRealTimeApprovals, };
@@ -151,6 +151,7 @@ import billList, { initialState as initialBillListState, } from './view/spendMan
151
151
  import billPayConfig, { initialState as initialBillPayConfigState, } from './view/spendManagement/billPay/billPayConfig/billPayConfigReducer';
152
152
  import BillPayReview, { initialState as initialBillPayReviewState, } from './view/spendManagement/billPay/billPayReview/billPayReviewReducer';
153
153
  import billPaySetupApproverView, { initialState as initialBillPaySetupApproverViewState, } from './view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewReducer';
154
+ import jeScheduleApprovalRules, { initialState as initialJEScheduleApprovalRulesState, } from './view/settings/jeScheduleApprovalRules/jeScheduleApprovalRulesReducer';
154
155
  import billPaySetupView, { initialState as initialBillPaySetupViewState, } from './view/spendManagement/billPay/billPaySetupView/billPaySetupViewReducer';
155
156
  import billsBulkActionView, { initialState as initialBillsBulkActionViewState, } from './view/spendManagement/billPay/billsBulkActionView/billsBulkActionViewReducer';
156
157
  import editBillView, { initialState as initialEditBillViewState, } from './view/spendManagement/billPay/editBillView/editBillViewReducer';
@@ -323,6 +324,7 @@ const initialViewsState = {
323
324
  billPayConfigState: initialBillPayConfigState,
324
325
  billPayReviewState: initialBillPayReviewState,
325
326
  billPaySetupApproverViewState: initialBillPaySetupApproverViewState,
327
+ jeScheduleApprovalRulesState: initialJEScheduleApprovalRulesState,
326
328
  billPaySetupViewState: initialBillPaySetupViewState,
327
329
  billsBulkActionViewState: initialBillsBulkActionViewState,
328
330
  cardBalanceState: initialCardBalanceState,
@@ -563,6 +565,7 @@ const viewReducers = {
563
565
  billPayCardState: billPayCard,
564
566
  billPayReviewState: BillPayReview,
565
567
  billPaySetupApproverViewState: billPaySetupApproverView,
568
+ jeScheduleApprovalRulesState: jeScheduleApprovalRules,
566
569
  billPaySetupViewState: billPaySetupView,
567
570
  billsBulkActionViewState: billsBulkActionView,
568
571
  cardBalanceState: cardBalance,
@@ -64,117 +64,6 @@ export const getDateFilteredDeletedTransactionIds = (allParsedTransactions, stat
64
64
  !isStatementTransactionInPeriod(transaction.transactionDate, statementPeriod.statementStartDate, statementPeriod.statementEndDate))
65
65
  .map((transaction) => transaction.statementTransactionId);
66
66
  };
67
- const roundCurrency = (value) => Math.round(value * 100) / 100;
68
- const toApiDateString = (value) => {
69
- if (value == null || value === '') {
70
- return '';
71
- }
72
- return date(value).format('YYYY-MM-DD');
73
- };
74
- const computeStatementTransactionTotals = (transactions) => {
75
- const totalDeposits = roundCurrency(transactions
76
- .filter((txn) => txn.transactionDirection === 'credit')
77
- .reduce((sum, txn) => sum + Math.abs(txn.amount ?? 0), 0));
78
- const totalPayments = roundCurrency(transactions
79
- .filter((txn) => txn.transactionDirection === 'debit')
80
- .reduce((sum, txn) => sum + Math.abs(txn.amount ?? 0), 0));
81
- return { totalDeposits, totalPayments };
82
- };
83
- const computeStatementClosingBalance = (openingBalance, totalDeposits, totalPayments, accountType) => roundCurrency(accountType === 'credit_card'
84
- ? openingBalance + totalPayments - totalDeposits
85
- : openingBalance + totalDeposits - totalPayments);
86
- const filterFormTransactionsInPeriod = (transactions, statementStartDate, statementEndDate) => {
87
- if (statementStartDate === '' || statementEndDate === '') {
88
- return transactions;
89
- }
90
- const periodStart = date(statementStartDate).startOf('day');
91
- const periodEnd = date(statementEndDate).startOf('day');
92
- return transactions.filter((txn) => {
93
- if (txn.transactionDate === '') {
94
- return true;
95
- }
96
- const txnDate = date(txn.transactionDate).startOf('day');
97
- return (txnDate.isSameOrAfter(periodStart, 'day') &&
98
- txnDate.isSameOrBefore(periodEnd, 'day'));
99
- });
100
- };
101
- export const isStatementParseTransactionFieldChange = (changedField) => changedField === 'transactions' ||
102
- changedField?.startsWith('transactions.') === true;
103
- const isStatementParseBalanceAffectingTransactionFieldChange = (changedField) => {
104
- if (changedField === 'transactions') {
105
- return true;
106
- }
107
- if (changedField?.startsWith('transactions.') !== true) {
108
- return false;
109
- }
110
- return !changedField.endsWith('.transactionMemo');
111
- };
112
- export const isStatementParseManualBalanceField = (field) => field === 'totalDeposits' ||
113
- field === 'totalPayments' ||
114
- field === 'closingBalance';
115
- export const shouldRecalculateStatementParseBalances = (changedField) => isStatementParseBalanceAffectingTransactionFieldChange(changedField) ||
116
- changedField === 'statementStartDate' ||
117
- changedField === 'statementEndDate';
118
- export const resolveStatementParseBalanceFields = (formView, changedField, accountType) => {
119
- const inPeriodTransactions = filterFormTransactionsInPeriod(formView.transactions, formView.statementStartDate, formView.statementEndDate);
120
- const { totalDeposits, totalPayments } = computeStatementTransactionTotals(inPeriodTransactions);
121
- if (!shouldRecalculateStatementParseBalances(changedField)) {
122
- return {
123
- openingBalance: formView.openingBalance,
124
- closingBalance: formView.closingBalance,
125
- totalDeposits: formView.totalDeposits,
126
- totalPayments: formView.totalPayments,
127
- };
128
- }
129
- return {
130
- openingBalance: formView.openingBalance,
131
- totalDeposits,
132
- totalPayments,
133
- closingBalance: computeStatementClosingBalance(formView.openingBalance, totalDeposits, totalPayments, accountType),
134
- };
135
- };
136
- export const areStatementParseBalancesConsistent = (formView, accountType) => {
137
- // Validate the four balance fields against each other (what the user sees),
138
- // not against recomputed transaction totals. Manual deposits/payments edits
139
- // are allowed as long as closing matches the account-type formula.
140
- return (roundCurrency(formView.closingBalance) ===
141
- computeStatementClosingBalance(formView.openingBalance, formView.totalDeposits, formView.totalPayments, accountType));
142
- };
143
- const mapParsedTransactionToFormRow = (transaction, index) => ({
144
- id: transaction.statementTransactionId || `parsed-${index}`,
145
- transactionDate: toApiDateString(transaction.transactionDate),
146
- transactionMemo: transaction.transactionMemo,
147
- amount: transaction.amount,
148
- transactionDirection: transaction.transactionDirection,
149
- statementTransactionId: transaction.statementTransactionId,
150
- });
151
- const mapLocalTransactionToFormRow = (transaction, id) => ({
152
- id,
153
- transactionDate: toApiDateString(transaction.transactionDate),
154
- transactionMemo: transaction.transactionMemo,
155
- amount: transaction.amount,
156
- transactionDirection: transaction.transactionDirection,
157
- statementTransactionId: transaction.statementTransactionId,
158
- });
159
- const buildStatementParseFormTransactions = (originalTransactions, localData) => {
160
- const deletedIdSet = new Set(localData.statementTransactions?.deletedIds ?? []);
161
- const updatedById = new Map((localData.statementTransactions?.updated ?? [])
162
- .filter((transaction) => transaction.statementTransactionId != null)
163
- .map((transaction) => [
164
- transaction.statementTransactionId,
165
- transaction,
166
- ]));
167
- const persistedTransactions = originalTransactions
168
- .filter((transaction) => !deletedIdSet.has(transaction.statementTransactionId))
169
- .map((transaction, index) => {
170
- const updated = updatedById.get(transaction.statementTransactionId);
171
- return updated != null
172
- ? mapLocalTransactionToFormRow(updated, transaction.statementTransactionId)
173
- : mapParsedTransactionToFormRow(transaction, index);
174
- });
175
- const addedTransactions = (localData.statementTransactions?.added ?? []).map((transaction, index) => mapLocalTransactionToFormRow(transaction, `added-${index}`));
176
- return [...persistedTransactions, ...addedTransactions];
177
- };
178
67
  export const mergeStatementParseDeletedTransactionIds = (originalTransactions, statementPeriod, currentTransactionIds) => {
179
68
  const dateFilteredDeletedIds = getDateFilteredDeletedTransactionIds(originalTransactions, statementPeriod);
180
69
  const dateFilteredDeletedIdSet = new Set(dateFilteredDeletedIds);
@@ -185,116 +74,3 @@ export const mergeStatementParseDeletedTransactionIds = (originalTransactions, s
185
74
  .map((transaction) => transaction.statementTransactionId);
186
75
  return [...new Set([...userDeletedIds, ...dateFilteredDeletedIds])];
187
76
  };
188
- const resolveStatementMetaDates = (parsedStatementMeta, localMeta) => ({
189
- statementStartDate: localMeta?.statementStartDate != null && localMeta.statementStartDate !== ''
190
- ? localMeta.statementStartDate
191
- : (parsedStatementMeta?.statementStartDate ?? ''),
192
- statementEndDate: localMeta?.statementEndDate != null && localMeta.statementEndDate !== ''
193
- ? localMeta.statementEndDate
194
- : (parsedStatementMeta?.statementEndDate ?? ''),
195
- });
196
- export const getStatementParseFormView = ({ accountType, parsedStatementMeta, originalTransactions, statementUpdateLocalData, }) => {
197
- const transactions = statementUpdateLocalData != null
198
- ? buildStatementParseFormTransactions(originalTransactions, statementUpdateLocalData)
199
- : originalTransactions.map(mapParsedTransactionToFormRow);
200
- const localMeta = statementUpdateLocalData?.statementMeta;
201
- const { statementStartDate, statementEndDate } = resolveStatementMetaDates(parsedStatementMeta, localMeta);
202
- const { totalDeposits, totalPayments } = computeStatementTransactionTotals(filterFormTransactionsInPeriod(transactions, statementStartDate, statementEndDate));
203
- const openingBalance = localMeta?.openingBalance ?? parsedStatementMeta?.openingBalance ?? 0;
204
- const computedClosingBalance = computeStatementClosingBalance(openingBalance, totalDeposits, totalPayments, accountType);
205
- return {
206
- statementStartDate,
207
- statementEndDate,
208
- openingBalance,
209
- closingBalance: localMeta?.closingBalance ?? computedClosingBalance,
210
- totalDeposits: localMeta?.totalDeposits ?? totalDeposits,
211
- totalPayments: localMeta?.totalPayments ?? totalPayments,
212
- transactions: filterFormTransactionsInPeriod(transactions, statementStartDate, statementEndDate),
213
- };
214
- };
215
- export const toStatementUpdateLocalDataFromFormView = ({ accountType, formView, parsedStatementMeta, originalTransactions, changedField, }) => {
216
- const balanceFields = resolveStatementParseBalanceFields(formView, changedField, accountType);
217
- const currentTransactionIds = new Set(formView.transactions
218
- .map((transaction) => transaction.statementTransactionId)
219
- .filter((id) => id != null && id !== ''));
220
- const added = [];
221
- const updated = [];
222
- formView.transactions.forEach((transaction) => {
223
- const transactionDate = toApiDateString(transaction.transactionDate);
224
- if (transaction.statementTransactionId == null) {
225
- if (transaction.transactionDirection != null) {
226
- added.push({
227
- amount: transaction.amount,
228
- transactionDate,
229
- transactionDirection: transaction.transactionDirection,
230
- transactionMemo: transaction.transactionMemo,
231
- });
232
- }
233
- return;
234
- }
235
- const original = originalTransactions.find((candidate) => candidate.statementTransactionId === transaction.statementTransactionId);
236
- if (original != null &&
237
- (original.amount !== transaction.amount ||
238
- toApiDateString(original.transactionDate) !== transactionDate ||
239
- original.transactionMemo !== transaction.transactionMemo)) {
240
- updated.push({
241
- amount: transaction.amount,
242
- transactionDate,
243
- transactionDirection: transaction.transactionDirection,
244
- transactionMemo: transaction.transactionMemo,
245
- statementTransactionId: transaction.statementTransactionId,
246
- });
247
- }
248
- });
249
- const statementPeriod = {
250
- statementStartDate: toApiDateString(formView.statementStartDate),
251
- statementEndDate: toApiDateString(formView.statementEndDate),
252
- };
253
- const deletedIds = mergeStatementParseDeletedTransactionIds(originalTransactions, statementPeriod, currentTransactionIds);
254
- const deletedIdSet = new Set(deletedIds);
255
- const inPeriodAdded = filterFormTransactionsInPeriod(added, statementPeriod.statementStartDate, statementPeriod.statementEndDate);
256
- const inPeriodUpdated = updated.filter((transaction) => transaction.statementTransactionId != null &&
257
- !deletedIdSet.has(transaction.statementTransactionId));
258
- return {
259
- statementMeta: {
260
- closingBalance: balanceFields.closingBalance,
261
- openingBalance: balanceFields.openingBalance,
262
- statementDataStatus: parsedStatementMeta?.statementDataStatus ?? {
263
- code: '',
264
- label: '',
265
- },
266
- statementEndDate: statementPeriod.statementEndDate,
267
- statementStartDate: statementPeriod.statementStartDate,
268
- statementStatus: parsedStatementMeta?.statementStatus ?? {
269
- code: '',
270
- label: '',
271
- },
272
- statementUploadId: parsedStatementMeta?.statementUploadId ?? '',
273
- totalDeposits: balanceFields.totalDeposits,
274
- totalPayments: balanceFields.totalPayments,
275
- },
276
- statementTransactions: {
277
- added: inPeriodAdded,
278
- deletedIds,
279
- updated: inPeriodUpdated,
280
- },
281
- };
282
- };
283
- export const applyStatementParseFormChange = ({ accountType, formView, changedField, parsedStatementMeta, originalTransactions, }) => {
284
- const balanceFields = resolveStatementParseBalanceFields(formView, changedField, accountType);
285
- const shouldRecalculate = shouldRecalculateStatementParseBalances(changedField);
286
- const mergedFormView = shouldRecalculate
287
- ? { ...formView, ...balanceFields }
288
- : formView;
289
- return {
290
- didRecalculateBalances: shouldRecalculate,
291
- formView: mergedFormView,
292
- localData: toStatementUpdateLocalDataFromFormView({
293
- accountType,
294
- formView: mergedFormView,
295
- parsedStatementMeta,
296
- originalTransactions,
297
- changedField,
298
- }),
299
- };
300
- };
@@ -0,0 +1,21 @@
1
+ import { of } from 'rxjs';
2
+ import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
3
+ import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
4
+ import { fetchJEScheduleApprovalRules, fetchJEScheduleApprovalRulesFailure, fetchJEScheduleApprovalRulesSuccess, } from '../jeScheduleApprovalRulesReducer';
5
+ export const fetchJEScheduleApprovalRulesEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchJEScheduleApprovalRules.match), switchMap((action) => {
6
+ const { cacheOverride } = action.payload;
7
+ const { jeScheduleApprovalRulesState } = state$.value;
8
+ const cachedSettings = jeScheduleApprovalRulesState.settings;
9
+ if (cacheOverride !== true &&
10
+ jeScheduleApprovalRulesState.hasValidState() === true &&
11
+ cachedSettings != null) {
12
+ return of(fetchJEScheduleApprovalRulesSuccess(cachedSettings));
13
+ }
14
+ const endpoint = `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/je-schedules/approval-rules`;
15
+ return zeniAPI.getJSON(endpoint).pipe(mergeMap((response) => {
16
+ if (isSuccessResponse(response) && response.data != null) {
17
+ return of(fetchJEScheduleApprovalRulesSuccess(response.data.settings));
18
+ }
19
+ return of(fetchJEScheduleApprovalRulesFailure(response.status));
20
+ }), catchError((error) => of(fetchJEScheduleApprovalRulesFailure(createZeniAPIStatus('Unexpected Error', 'Fetch JE approval rules errored out' + JSON.stringify(error))))));
21
+ }));
@@ -0,0 +1,20 @@
1
+ import { of } from 'rxjs';
2
+ import { catchError, filter, mergeMap } from 'rxjs/operators';
3
+ import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
4
+ import { saveJEScheduleApprovalRules, saveJEScheduleApprovalRulesConflict, saveJEScheduleApprovalRulesFailure, saveJEScheduleApprovalRulesSuccess, } from '../jeScheduleApprovalRulesReducer';
5
+ const HTTP_CONFLICT = 409;
6
+ export const saveJEScheduleApprovalRulesEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(saveJEScheduleApprovalRules.match), mergeMap((action) => {
7
+ const { body } = action.payload;
8
+ const endpoint = `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/je-schedules/approval-rules`;
9
+ return zeniAPI
10
+ .postAndGetJSON(endpoint, body)
11
+ .pipe(mergeMap((response) => {
12
+ if (isSuccessResponse(response) && response.data != null) {
13
+ return of(saveJEScheduleApprovalRulesSuccess(response.data.settings, response.data.reevaluation_triggered));
14
+ }
15
+ if (response.status.code === HTTP_CONFLICT) {
16
+ return of(saveJEScheduleApprovalRulesConflict(response.status));
17
+ }
18
+ return of(saveJEScheduleApprovalRulesFailure(response.status));
19
+ }), catchError((error) => of(saveJEScheduleApprovalRulesFailure(createZeniAPIStatus('Unexpected Error', 'Save JE approval rules errored out' + JSON.stringify(error))))));
20
+ }));
@@ -0,0 +1,76 @@
1
+ import { createSlice } from '@reduxjs/toolkit';
2
+ export const initialState = {
3
+ fetchState: 'Not-Started',
4
+ error: undefined,
5
+ saveStatus: { fetchState: 'Not-Started', error: undefined },
6
+ settings: undefined,
7
+ hadVersionConflict: false,
8
+ reevaluationTriggered: false,
9
+ hasValidState() {
10
+ return this.fetchState === 'Completed';
11
+ },
12
+ };
13
+ const jeScheduleApprovalRules = createSlice({
14
+ name: 'jeScheduleApprovalRules',
15
+ initialState,
16
+ reducers: {
17
+ fetchJEScheduleApprovalRules: {
18
+ reducer(draft) {
19
+ draft.fetchState = 'In-Progress';
20
+ draft.error = undefined;
21
+ },
22
+ prepare(cacheOverride = false) {
23
+ return { payload: { cacheOverride } };
24
+ },
25
+ },
26
+ fetchJEScheduleApprovalRulesSuccess: {
27
+ reducer(draft, action) {
28
+ draft.fetchState = 'Completed';
29
+ draft.error = undefined;
30
+ draft.settings = action.payload.settings;
31
+ },
32
+ prepare(settings) {
33
+ return { payload: { settings } };
34
+ },
35
+ },
36
+ fetchJEScheduleApprovalRulesFailure(draft, action) {
37
+ draft.fetchState = 'Error';
38
+ draft.error = action.payload;
39
+ },
40
+ saveJEScheduleApprovalRules: {
41
+ reducer(draft) {
42
+ draft.saveStatus = { fetchState: 'In-Progress', error: undefined };
43
+ draft.hadVersionConflict = false;
44
+ draft.reevaluationTriggered = false;
45
+ },
46
+ prepare(body) {
47
+ return { payload: { body } };
48
+ },
49
+ },
50
+ saveJEScheduleApprovalRulesSuccess: {
51
+ reducer(draft, action) {
52
+ draft.saveStatus = { fetchState: 'Completed', error: undefined };
53
+ draft.settings = action.payload.settings;
54
+ draft.reevaluationTriggered = action.payload.reevaluationTriggered;
55
+ draft.hadVersionConflict = false;
56
+ },
57
+ prepare(settings, reevaluationTriggered) {
58
+ return { payload: { settings, reevaluationTriggered } };
59
+ },
60
+ },
61
+ // 409 — the stored version moved under us. The screen should re-fetch and
62
+ // ask the user to re-apply. Kept distinct from a generic save failure.
63
+ saveJEScheduleApprovalRulesConflict(draft, action) {
64
+ draft.saveStatus = { fetchState: 'Error', error: action.payload };
65
+ draft.hadVersionConflict = true;
66
+ },
67
+ saveJEScheduleApprovalRulesFailure(draft, action) {
68
+ draft.saveStatus = { fetchState: 'Error', error: action.payload };
69
+ },
70
+ clearJEScheduleApprovalRules() {
71
+ return initialState;
72
+ },
73
+ },
74
+ });
75
+ export const { fetchJEScheduleApprovalRules, fetchJEScheduleApprovalRulesSuccess, fetchJEScheduleApprovalRulesFailure, saveJEScheduleApprovalRules, saveJEScheduleApprovalRulesSuccess, saveJEScheduleApprovalRulesConflict, saveJEScheduleApprovalRulesFailure, clearJEScheduleApprovalRules, } = jeScheduleApprovalRules.actions;
76
+ export default jeScheduleApprovalRules.reducer;
@@ -0,0 +1,9 @@
1
+ import { createSelector } from '@reduxjs/toolkit';
2
+ export const getJEScheduleApprovalRulesView = createSelector((state) => state.jeScheduleApprovalRulesState, (jeScheduleApprovalRulesState) => ({
3
+ fetchState: jeScheduleApprovalRulesState.fetchState,
4
+ error: jeScheduleApprovalRulesState.error,
5
+ saveStatus: jeScheduleApprovalRulesState.saveStatus,
6
+ settings: jeScheduleApprovalRulesState.settings,
7
+ hadVersionConflict: jeScheduleApprovalRulesState.hadVersionConflict ?? false,
8
+ reevaluationTriggered: jeScheduleApprovalRulesState.reevaluationTriggered ?? false,
9
+ }));
@@ -295,11 +295,13 @@ export const toUpdateLineItemsOriginalCategoryClass = (transaction, transactionD
295
295
  const isLineIdInReplaceList = (findLineID) => lineIdsForReplace.find((lineId) => findLineID === lineId);
296
296
  const isLineIdInUpdateList = (findLineID) => lineIdsForUpdateAll.find((lineId) => findLineID === lineId);
297
297
  const newLineItems = {};
298
+ const persistedLineIds = new Set();
298
299
  const checkIfNotJEAndDeposit = isVendorTransaction(transaction) === true ||
299
300
  isCustomerTransaction(transaction) === true;
300
301
  if (transaction.lines != null) {
301
302
  // always preserving the order of the line items. hence iterating over this
302
303
  transaction.lines.forEach((line) => {
304
+ persistedLineIds.add(line.id);
303
305
  if (line.type === 'transaction_with_account_and_class_line' ||
304
306
  line.type === 'transaction_with_product_or_service_line' ||
305
307
  line.type === 'journal_entry_transaction_line') {
@@ -430,6 +432,7 @@ export const toUpdateLineItemsOriginalCategoryClass = (transaction, transactionD
430
432
  }
431
433
  });
432
434
  }
435
+ preserveLocalLines(newLineItems, transactionDetailLocalData.lineItemById, persistedLineIds);
433
436
  const newLocalData = {
434
437
  ...initialSupportedTransactionDetail.transactionDetailLocalData,
435
438
  memo: transactionDetailLocalData.memo,
@@ -450,11 +453,13 @@ export const toUpdateLineItemsOriginalCategoryClass = (transaction, transactionD
450
453
  };
451
454
  export const toSetAllLineItemsToCategoryClass = (transaction, transactionDetailLocalData, isUpdateAll, lineEntity, chosenAccount, chosenClass) => {
452
455
  const newLineItems = {};
456
+ const persistedLineIds = new Set();
453
457
  const updateAllLines = isVendorTransaction(transaction) === true ||
454
458
  isCustomerTransaction(transaction) === true;
455
459
  if (transaction.lines != null) {
456
460
  // always preserving the order of the line items. hence iterating over this
457
461
  transaction.lines.forEach((line) => {
462
+ persistedLineIds.add(line.id);
458
463
  if (line.type === 'transaction_with_account_and_class_line' ||
459
464
  line.type === 'transaction_with_product_or_service_line' ||
460
465
  line.type === 'journal_entry_transaction_line') {
@@ -535,6 +540,7 @@ export const toSetAllLineItemsToCategoryClass = (transaction, transactionDetailL
535
540
  }
536
541
  });
537
542
  }
543
+ preserveLocalLines(newLineItems, transactionDetailLocalData.lineItemById, persistedLineIds);
538
544
  const newLocalData = {
539
545
  ...initialSupportedTransactionDetail.transactionDetailLocalData,
540
546
  memo: transactionDetailLocalData.memo,
@@ -555,11 +561,13 @@ export const toSetAllLineItemsToCategoryClass = (transaction, transactionDetailL
555
561
  };
556
562
  export const toSetAllLineItemsLocalDataIsUpdateAllChecked = (transaction, transactionDetailLocalData, isUpdateAll, entity) => {
557
563
  const newLineItems = {};
564
+ const persistedLineIds = new Set();
558
565
  const updateAllLines = isVendorTransaction(transaction) === true ||
559
566
  isCustomerTransaction(transaction) === true;
560
567
  if (transaction.lines != null) {
561
568
  // always preserving the order of the line items. hence iterating over this
562
569
  transaction.lines.forEach((line) => {
570
+ persistedLineIds.add(line.id);
563
571
  const lineId = line.id;
564
572
  if (line.type === 'transaction_with_account_and_class_line' ||
565
573
  line.type === 'transaction_with_product_or_service_line' ||
@@ -581,6 +589,7 @@ export const toSetAllLineItemsLocalDataIsUpdateAllChecked = (transaction, transa
581
589
  }
582
590
  });
583
591
  }
592
+ preserveLocalLines(newLineItems, transactionDetailLocalData.lineItemById, persistedLineIds);
584
593
  const newLocalData = {
585
594
  ...initialSupportedTransactionDetail.transactionDetailLocalData,
586
595
  memo: transactionDetailLocalData.memo,
@@ -599,14 +608,23 @@ export const toSetAllLineItemsLocalDataIsUpdateAllChecked = (transaction, transa
599
608
  };
600
609
  return newLocalData;
601
610
  };
611
+ const preserveLocalLines = (target, source, persistedLineIds) => {
612
+ Object.keys(source).forEach((lineId) => {
613
+ if (!persistedLineIds.has(lineId)) {
614
+ target[lineId] = { ...source[lineId] };
615
+ }
616
+ });
617
+ };
602
618
  export const setEntityRecommendationForLineIdInLocalData = (transaction, transactionDetailLocalData, entity, recommendationLineIds, uncategorizedIncomeExpense, recommendationWithCOTByLineId) => {
603
619
  const newLineItems = {};
604
620
  let matchingEntityLineId = undefined;
605
621
  const checkIfNotJEAndDeposit = isVendorTransaction(transaction) === true ||
606
622
  isCustomerTransaction(transaction) === true;
623
+ const persistedLineIds = new Set();
607
624
  if (transaction.lines != null) {
608
625
  // always preserving the order of the line items. hence iterating over this
609
626
  transaction.lines.forEach((line) => {
627
+ persistedLineIds.add(line.id);
610
628
  const lineId = line.id;
611
629
  const oldRecord = transactionDetailLocalData.lineItemById[lineId];
612
630
  // check if any line already has this entity
@@ -718,6 +736,7 @@ export const setEntityRecommendationForLineIdInLocalData = (transaction, transac
718
736
  }
719
737
  });
720
738
  }
739
+ preserveLocalLines(newLineItems, transactionDetailLocalData.lineItemById, persistedLineIds);
721
740
  // if we have found a matching entity
722
741
  if (matchingEntityLineId != null) {
723
742
  const matchingRecord = transactionDetailLocalData.lineItemById[matchingEntityLineId];
@@ -761,9 +780,11 @@ export const setEntityRecommendationForLineIdInLocalData = (transaction, transac
761
780
  };
762
781
  export const removeEntityRecommendationForLineIdInLocalData = (transaction, transactionDetailLocalData, recommendationLineIds) => {
763
782
  const newLineItems = {};
783
+ const persistedLineIds = new Set();
764
784
  if (transaction.lines != null) {
765
785
  // always preserving the order of the line items. hence iterating over this
766
786
  transaction.lines.forEach((line) => {
787
+ persistedLineIds.add(line.id);
767
788
  const lineId = line.id;
768
789
  const oldRecord = transactionDetailLocalData.lineItemById[lineId];
769
790
  // check if any line already has this entity
@@ -794,6 +815,7 @@ export const removeEntityRecommendationForLineIdInLocalData = (transaction, tran
794
815
  }
795
816
  });
796
817
  }
818
+ preserveLocalLines(newLineItems, transactionDetailLocalData.lineItemById, persistedLineIds);
797
819
  const newLocalData = {
798
820
  ...initialSupportedTransactionDetail.transactionDetailLocalData,
799
821
  memo: transactionDetailLocalData.memo,
@@ -859,9 +881,11 @@ const toLineCustomerOrVendor = (entity) => {
859
881
  };
860
882
  export const toSetAllLineItemsToVendor = (transaction, transactionDetailLocalData, entity) => {
861
883
  const newLineItems = {};
884
+ const persistedLineIds = new Set();
862
885
  if (transaction.lines != null) {
863
886
  // always preserving the order of the line items. hence iterating over this
864
887
  transaction.lines.forEach((line) => {
888
+ persistedLineIds.add(line.id);
865
889
  if (line.type === 'transaction_with_account_and_class_line' ||
866
890
  line.type === 'transaction_with_product_or_service_line' ||
867
891
  line.type === 'journal_entry_transaction_line') {
@@ -906,6 +930,7 @@ export const toSetAllLineItemsToVendor = (transaction, transactionDetailLocalDat
906
930
  }
907
931
  });
908
932
  }
933
+ preserveLocalLines(newLineItems, transactionDetailLocalData.lineItemById, persistedLineIds);
909
934
  const newLocalData = {
910
935
  ...transactionDetailLocalData,
911
936
  lineItemById: newLineItems,
@@ -916,9 +941,11 @@ export const toSetAllLineItemsToVendor = (transaction, transactionDetailLocalDat
916
941
  export const toUpdateLineItemsToOriginalVendor = (transaction, transactionDetailLocalData, lineIdToRetainVendorSelection) => {
917
942
  const newLineItems = {};
918
943
  const transactionWithCOT = getTransactionWithCOT(transaction);
944
+ const persistedLineIds = new Set();
919
945
  if (transaction.lines != null) {
920
946
  // always preserving the order of the line items. hence iterating over this
921
947
  transaction.lines.forEach((line) => {
948
+ persistedLineIds.add(line.id);
922
949
  if (line.type === 'transaction_with_account_and_class_line' ||
923
950
  line.type === 'transaction_with_product_or_service_line' ||
924
951
  line.type === 'journal_entry_transaction_line') {
@@ -1019,6 +1046,7 @@ export const toUpdateLineItemsToOriginalVendor = (transaction, transactionDetail
1019
1046
  }
1020
1047
  });
1021
1048
  }
1049
+ preserveLocalLines(newLineItems, transactionDetailLocalData.lineItemById, persistedLineIds);
1022
1050
  const newLocalData = {
1023
1051
  ...initialSupportedTransactionDetail.transactionDetailLocalData,
1024
1052
  memo: transactionDetailLocalData.memo,