@zeniai/client-epic-state 5.2.62 → 5.2.64

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 (42) hide show
  1. package/lib/entity/actualMatching/actualMatchingReducer.d.ts +3 -1
  2. package/lib/entity/actualMatching/actualMatchingReducer.js +11 -2
  3. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +1 -0
  4. package/lib/entity/jeSchedules/jeSchedulesPayload.js +1 -0
  5. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +1 -0
  6. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  7. package/lib/entity/snackbar/snackbarTypes.js +1 -0
  8. package/lib/epic.d.ts +2 -1
  9. package/lib/epic.js +2 -0
  10. package/lib/esm/entity/actualMatching/actualMatchingReducer.js +9 -1
  11. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +1 -0
  12. package/lib/esm/entity/snackbar/snackbarTypes.js +1 -0
  13. package/lib/esm/epic.js +2 -0
  14. package/lib/esm/index.js +5 -5
  15. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.js +4 -2
  16. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.js +50 -0
  17. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.js +26 -13
  18. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchTransactionsEpic.js +2 -23
  19. package/lib/esm/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +89 -38
  20. package/lib/esm/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +66 -64
  21. package/lib/esm/view/expenseAutomationView/types/actualMatchingViewState.js +15 -0
  22. package/lib/esm/view/spendManagement/billPay/editBillView/editBillViewSelector.js +4 -30
  23. package/lib/index.d.ts +6 -6
  24. package/lib/index.js +57 -49
  25. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.d.ts +2 -2
  26. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.js +3 -1
  27. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.d.ts +10 -0
  28. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.js +54 -0
  29. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.js +24 -11
  30. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchTransactionsEpic.js +1 -22
  31. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  32. package/lib/view/expenseAutomationView/payload/actualMatchingPayload.d.ts +12 -1
  33. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.d.ts +19 -8
  34. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +90 -39
  35. package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.d.ts +20 -8
  36. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.d.ts +7 -4
  37. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +69 -64
  38. package/lib/view/expenseAutomationView/types/actualMatchingViewState.d.ts +20 -4
  39. package/lib/view/expenseAutomationView/types/actualMatchingViewState.js +18 -1
  40. package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.d.ts +1 -1
  41. package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.js +4 -30
  42. package/package.json +1 -1
@@ -0,0 +1,10 @@
1
+ import { ActionsObservable, StateObservable } from 'redux-observable';
2
+ import { Observable } from 'rxjs';
3
+ import { removeActualMatchingMatch } from '../../../../../entity/actualMatching/actualMatchingReducer';
4
+ import { openSnackbar } from '../../../../../entity/snackbar/snackbarReducer';
5
+ import { clearAll } from '../../../../../rootActions';
6
+ import { RootState } from '../../../../../rootStateTypes';
7
+ import { ZeniAPI } from '../../../../../zeniAPI';
8
+ import { fetchActualMatching, ignoreActualMatchingSuggestion, ignoreActualMatchingSuggestionFailure, ignoreActualMatchingSuggestionSuccess } from '../../../reducers/actualMatchingViewReducer';
9
+ export type ActionType = ReturnType<typeof clearAll> | ReturnType<typeof fetchActualMatching> | ReturnType<typeof ignoreActualMatchingSuggestion> | ReturnType<typeof ignoreActualMatchingSuggestionFailure> | ReturnType<typeof ignoreActualMatchingSuggestionSuccess> | ReturnType<typeof openSnackbar> | ReturnType<typeof removeActualMatchingMatch>;
10
+ export declare const ignoreActualMatchingSuggestionEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ignoreActualMatchingSuggestionEpic = void 0;
4
+ const rxjs_1 = require("rxjs");
5
+ const operators_1 = require("rxjs/operators");
6
+ const actualMatchingReducer_1 = require("../../../../../entity/actualMatching/actualMatchingReducer");
7
+ const actualMatchingSelector_1 = require("../../../../../entity/actualMatching/actualMatchingSelector");
8
+ const snackbarReducer_1 = require("../../../../../entity/snackbar/snackbarReducer");
9
+ const responsePayload_1 = require("../../../../../responsePayload");
10
+ const rootActions_1 = require("../../../../../rootActions");
11
+ const actualMatchingViewReducer_1 = require("../../../reducers/actualMatchingViewReducer");
12
+ const refreshActualMatchingList_1 = require("./refreshActualMatchingList");
13
+ function matchVendorName(state, matchId) {
14
+ return ((0, actualMatchingSelector_1.getActualMatchingMatchById)(state.actualMatchingState, matchId)?.vendorName ??
15
+ '');
16
+ }
17
+ function ignoreSuggestionSnackbar(vendorName, succeeded) {
18
+ return (0, snackbarReducer_1.openSnackbar)({
19
+ messageSection: 'actual_matching_ignore_suggestion',
20
+ messageText: succeeded ? 'success' : 'failed',
21
+ type: succeeded ? 'success' : 'error',
22
+ variables: [{ variableName: '_vendor_name_', variableValue: vendorName }],
23
+ });
24
+ }
25
+ const ignoreActualMatchingSuggestionEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(actualMatchingViewReducer_1.ignoreActualMatchingSuggestion.match), (0, operators_1.groupBy)((action) => action.payload.matchId), (0, operators_1.mergeMap)((perMatch$) => perMatch$.pipe((0, operators_1.exhaustMap)((action) => {
26
+ const { matchId, reason, note } = action.payload;
27
+ const body = {
28
+ reason,
29
+ ...(note != null && note !== '' ? { note } : {}),
30
+ };
31
+ const vendorName = matchVendorName(state$.value, matchId);
32
+ return zeniAPI
33
+ .putAndGetJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals/actual-matching/${encodeURIComponent(matchId)}/ignore`, body)
34
+ .pipe((0, operators_1.mergeMap)((response) => {
35
+ if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
36
+ const successActions = [
37
+ (0, actualMatchingReducer_1.removeActualMatchingMatch)(matchId),
38
+ (0, actualMatchingViewReducer_1.ignoreActualMatchingSuggestionSuccess)({ matchId }),
39
+ ...(0, refreshActualMatchingList_1.refreshActualMatchingList)(state$.value),
40
+ ignoreSuggestionSnackbar(vendorName, true),
41
+ ];
42
+ return (0, rxjs_1.from)(successActions);
43
+ }
44
+ return (0, rxjs_1.of)((0, actualMatchingViewReducer_1.ignoreActualMatchingSuggestionFailure)({
45
+ matchId,
46
+ status: response.status,
47
+ }), ignoreSuggestionSnackbar(vendorName, false));
48
+ }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, actualMatchingViewReducer_1.ignoreActualMatchingSuggestionFailure)({
49
+ matchId,
50
+ status: (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Ignore actual matching suggestion REST API call errored out' +
51
+ JSON.stringify(error)),
52
+ }), ignoreSuggestionSnackbar(vendorName, false))), (0, operators_1.takeUntil)(actions$.pipe((0, operators_1.filter)(rootActions_1.clearAll.match))));
53
+ }))));
54
+ exports.ignoreActualMatchingSuggestionEpic = ignoreActualMatchingSuggestionEpic;
@@ -12,7 +12,7 @@ const actualMatchingViewReducer_1 = require("../../../reducers/actualMatchingVie
12
12
  const actualMatchingViewState_1 = require("../../../types/actualMatchingViewState");
13
13
  const refreshActualMatchingList_1 = require("./refreshActualMatchingList");
14
14
  function isMatchFailedStatus(status) {
15
- return (status === 'conflict' || status === 'claim_lost' || status === 'error');
15
+ return status === 'conflict' || status === 'claim_lost' || status === 'error';
16
16
  }
17
17
  function matchAndReverseSnackbar(results, vendorName) {
18
18
  const reversedCount = results.filter((result) => result.status === 'reversed').length;
@@ -59,12 +59,15 @@ function matchAndReverseHttpFailSnackbar(vendorName) {
59
59
  });
60
60
  }
61
61
  function matchVendorName(state, matchId) {
62
- return (0, actualMatchingSelector_1.getActualMatchingMatchById)(state.actualMatchingState, matchId)?.vendorName ?? '';
62
+ return ((0, actualMatchingSelector_1.getActualMatchingMatchById)(state.actualMatchingState, matchId)
63
+ ?.vendorName ?? '');
63
64
  }
64
65
  const matchAndReverseAccrualsEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(actualMatchingViewReducer_1.matchAndReverseAccruals.match),
65
- // Posts reversing JEs; drop duplicate clicks while a request is in flight.
66
- (0, operators_1.exhaustMap)((action) => {
67
- const { transactionId, transactionIntegrationId, transactionType, lineIds, accrualIds, transactionSyncToken, } = action.payload;
66
+ // Per-match exhaust: a second click on the same match drops while HTTP is in
67
+ // flight. A different match must still run — a global exhaustMap left the
68
+ // other match's reducer In-Progress with no request.
69
+ (0, operators_1.groupBy)((action) => `${action.payload.transactionType.toLowerCase()}:${action.payload.transactionIntegrationId}`), (0, operators_1.mergeMap)((perMatch$) => perMatch$.pipe((0, operators_1.exhaustMap)((action) => {
70
+ const { transactionId, transactionIntegrationId, transactionType, lineIds, accrualIds, transactionSyncToken, forMatchModal, } = action.payload;
68
71
  const body = {
69
72
  transaction_id: transactionId,
70
73
  transaction_integration_id: transactionIntegrationId,
@@ -83,30 +86,40 @@ const matchAndReverseAccrualsEpic = (actions$, state$, zeniAPI) => actions$.pipe
83
86
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
84
87
  const results = response.data.results.map(actualMatchingPayload_1.toMatchAndReverseResult);
85
88
  const successActions = [
86
- (0, actualMatchingViewReducer_1.matchAndReverseAccrualsSuccess)({ matchId, results }),
89
+ (0, actualMatchingViewReducer_1.matchAndReverseAccrualsSuccess)({
90
+ matchId,
91
+ results,
92
+ ...(forMatchModal === true ? { forMatchModal: true } : {}),
93
+ }),
87
94
  ];
88
95
  const occupancyChanged = results.some((result) => (0, actualMatchingViewState_1.isMatchAndReverseCompleteStatus)(result.status));
89
96
  const allComplete = results.length > 0 &&
90
97
  results.every((result) => (0, actualMatchingViewState_1.isMatchAndReverseCompleteStatus)(result.status));
91
98
  if (occupancyChanged) {
92
99
  // List + detail: list can omit leftovers; detail GET always
93
- // writes intended occupancy so Continue match prefills the
94
- // remaining leftover set instead of a stale cached row.
100
+ // writes intended occupancy so leftover retry can join C
101
+ // onto the occupied bill instead of a stale cached row.
95
102
  successActions.push(...(0, refreshActualMatchingList_1.refreshActualMatchingList)(state$.value), (0, actualMatchingViewReducer_1.fetchActualMatchingMatch)(matchId, true));
96
103
  }
97
104
  const snackbar = matchAndReverseSnackbar(results, vendorName);
98
105
  if (snackbar != null) {
99
106
  successActions.push(snackbar);
100
107
  }
101
- if (allComplete) {
108
+ if (allComplete && forMatchModal === true) {
102
109
  successActions.push((0, actualMatchingViewReducer_1.clearMatchNewModal)());
103
110
  }
104
111
  return (0, rxjs_1.from)(successActions);
105
112
  }
106
- return (0, rxjs_1.of)((0, actualMatchingViewReducer_1.matchAndReverseAccrualsFailure)({ status: response.status }), matchAndReverseHttpFailSnackbar(vendorName));
113
+ return (0, rxjs_1.of)((0, actualMatchingViewReducer_1.matchAndReverseAccrualsFailure)({
114
+ status: response.status,
115
+ matchId,
116
+ ...(forMatchModal === true ? { forMatchModal: true } : {}),
117
+ }), matchAndReverseHttpFailSnackbar(vendorName));
107
118
  }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, actualMatchingViewReducer_1.matchAndReverseAccrualsFailure)({
119
+ matchId,
120
+ ...(forMatchModal === true ? { forMatchModal: true } : {}),
108
121
  status: (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Match and reverse accruals REST API call errored out' +
109
122
  JSON.stringify(error)),
110
123
  }), matchAndReverseHttpFailSnackbar(vendorName))), (0, operators_1.takeUntil)(actions$.pipe((0, operators_1.filter)(rootActions_1.clearAll.match))));
111
- }));
124
+ }))));
112
125
  exports.matchAndReverseAccrualsEpic = matchAndReverseAccrualsEpic;
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.searchMatchTransactionsEpic = void 0;
4
4
  const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
- const actualMatchingSelector_1 = require("../../../../../entity/actualMatching/actualMatchingSelector");
7
6
  const responsePayload_1 = require("../../../../../responsePayload");
8
7
  const rootActions_1 = require("../../../../../rootActions");
9
8
  const actualMatchingPayload_1 = require("../../../payload/actualMatchingPayload");
@@ -11,27 +10,7 @@ const actualMatchingViewReducer_1 = require("../../../reducers/actualMatchingVie
11
10
  const actualMatchingViewSelector_1 = require("../../../selectors/actualMatchingViewSelector");
12
11
  const actualMatchingViewState_1 = require("../../../types/actualMatchingViewState");
13
12
  const searchMatchTransactionsEpic = (actions$, state$, zeniAPI) => {
14
- const openModal$ = actions$.pipe((0, operators_1.filter)(actualMatchingViewReducer_1.openMatchNewModal.match), (0, operators_1.mergeMap)((action) => {
15
- const matchId = action.payload.matchId;
16
- if (matchId == null || matchId === '') {
17
- return (0, rxjs_1.from)([
18
- (0, actualMatchingViewReducer_1.searchMatchTransactions)(''),
19
- (0, actualMatchingViewReducer_1.searchMatchAccruals)(''),
20
- ]);
21
- }
22
- const match = (0, actualMatchingSelector_1.getActualMatchingMatchById)(state$.value.actualMatchingState, matchId);
23
- const parsed = (0, actualMatchingViewSelector_1.parseActualMatchingMatchId)(matchId);
24
- const transactionType = match?.transactionType != null && match.transactionType !== ''
25
- ? match.transactionType
26
- : parsed?.transactionType;
27
- const transactionIntegrationId = match?.transactionIntegrationId != null &&
28
- match.transactionIntegrationId !== ''
29
- ? match.transactionIntegrationId
30
- : parsed?.transactionIntegrationId;
31
- return (0, rxjs_1.from)([
32
- (0, actualMatchingViewReducer_1.searchMatchTransactions)('', undefined, transactionType, transactionIntegrationId),
33
- ]);
34
- }));
13
+ const openModal$ = actions$.pipe((0, operators_1.filter)(actualMatchingViewReducer_1.openMatchNewModal.match), (0, operators_1.mergeMap)(() => (0, rxjs_1.from)([(0, actualMatchingViewReducer_1.searchMatchTransactions)(''), (0, actualMatchingViewReducer_1.searchMatchAccruals)('')])));
35
14
  const searchActions$ = actions$.pipe((0, operators_1.filter)(actualMatchingViewReducer_1.searchMatchTransactions.match));
36
15
  const pagination$ = searchActions$.pipe((0, operators_1.filter)((action) => action.payload.pageToken != null));
37
16
  const newSearchDebounced$ = searchActions$.pipe((0, operators_1.filter)((action) => action.payload.pageToken == null), (0, operators_1.debounceTime)(actualMatchingViewState_1.MATCH_SEARCH_DEBOUNCE_MS));
@@ -39,7 +39,7 @@ export declare const getLineItemsByTransactionsIdsFromResponse: (transactions: S
39
39
  export declare const getLineItemsByTransactionIdsFromLocalData: (transactionLocalData: TransactionReviewLocalDataSelectorView[], selectedTab: TransactionsTab) => Record<ID, string[]>;
40
40
  export declare const mergeTabSpecificLineItems: (currentTabSpecificLineItems: TabSpecificLineItems, selectedTab: TransactionsTab, newLineItems: TabSpecificLineItems) => TabSpecificLineItems;
41
41
  export declare const getSnackbarMessageForTransactionReview: (updatedCount: number, failedCount: number, categorizedCount: number) => {
42
- messageSection: "common" | "recommendation_feedback" | "transactionDetails_updatingPastTransactions" | "transactionDetails_transactionUpdated" | "cockpit_month_end_email_sent" | "cockpit_month_end_email_save" | "cockpit_month_end_email_attachment_upload" | "je_bill_link" | "je_posted" | "actual_matching_match_and_reverse" | "actual_matching_undo_reversal" | "audit_score_updated" | "people_invite_people" | "people_invite_multiple_people" | "people_delete_person" | "people_update_person" | "reimbursement_updated" | "reimbursement_deleted" | "reimbursement_cancelled_deleted" | "reimbursement_cancelled" | "reimbursement_approved" | "reimbursement_rejected" | "reimbursement_sent_for_approval" | "account_added" | "business_verification_save" | "business_verification_submit" | "business_verification_from_bills_submit" | "plaid_connection" | "unlink_deposit_account" | "reimbursement_setup" | "reimbursement_approval_create" | "reimbursement_duplicate_approval_create" | "reimbursement_approval_update" | "reimbursement_duplicate_approval_update" | "reimbursement_approval_delete" | "reimbursement_approval_reorder" | "reimbursement_create_mileage" | "reimbursement_update_mileage" | "reimbursement_accept_term" | "reimbursement_accept_employee_term" | "reimbursement_bulk_submit" | "reimbursement_bulk_processed" | "bill_pay_setup" | "zeni_accounts_setup" | "bill_pay_approval_create" | "bill_pay_duplicate_approval_create" | "bill_pay_approval_update" | "bill_pay_duplicate_approval_update" | "bill_pay_approval_delete" | "bill_pay_approval_reorder" | "bill_pay_updated" | "bill_pay_deleted" | "bill_pay_cancelled_deleted" | "bill_pay_cancelled" | "bill_pay_approved" | "real_time_approver_added" | "bill_pay_rejected" | "bill_pay_sent_for_approval" | "bill_pay_accept_term" | "bill_pay_bulk_submit" | "bill_pay_bulk_processed" | "bill_pay_refund" | "bill_pay_retry" | "bill_pay_marked_as_paid" | "zeni_account_accept_term" | "update_vendor" | "data_refresh_update" | "delete_bank_account" | "create_bank_account" | "create_bank_account_ach" | "create_bank_account_wire" | "create_bank_account_international" | "transfer_money" | "update_zeni_account_nickname" | "create_checking_account" | "deposit_check" | "create_vendor" | "onboarding_customer_view" | "onboarding_customer_view_complete" | "onboarding_customer_identity_verification_save" | "onboarding_customer_identity_verification_submit" | "onboarding_customer_business_verification_save" | "onboarding_customer_business_verification_submit" | "retry_bank_account_connection" | "dashboard_invite_sent" | "onboarding_info_saved" | "approve_original_merchant" | "approve_global_merchant" | "reject_global_merchant" | "create_global_merchant" | "fetch_global_merchant_no_recommendation" | "save_vendor_renamed" | "save_vendor_sent_for_review" | "save_vendor_marked_as_employee" | "save_vendor_marked_as_local_contractor" | "charge_card_setup" | "charge_card_accept_term" | "charge_card_receipt_upload" | "charge_card_resend_invite" | "charge_card_revoke_invite" | "card_policy_created" | "card_policy_updated" | "card_policy_deleted" | "charge_card_update_limit" | "charge_cards_update_limit" | "close_charge_card" | "lock_charge_card" | "lock_charge_card_card_user" | "lock_charge_cards" | "unlock_charge_card" | "unlock_charge_card_card_user" | "unlock_charge_cards" | "close_charge_cards" | "revoke_invite_charge_cards" | "charge_card_express_interest" | "create_schedule" | "save_schedule" | "delete_schedule" | "ignore_schedule" | "revert_schedule" | "ignore_accrual" | "revert_accrual" | "save_task_detail" | "fetch_task_detail" | "delete_task" | "archive_task" | "snooze_task" | "unsnooze_task" | "create_tag" | "delete_tag" | "update_charge_card" | "update_charge_card_name" | "update_charge_card_name_card_user" | "issue_charge_card" | "issue_charge_cards" | "notification_settings_saved" | "referral_invite_sent" | "notification_mark_as_read" | "mark_as_complete_schedule" | "cancel_journal_entry" | "settings_accounting_accounts_updated" | "create_card_setup" | "confirm_card_setup" | "add_card_payment_source" | "fetch_payment_sources" | "task_assigned_toast_notification" | "task_due_tomorrow_toast_notification" | "task_deleted_toast_notification" | "task_archived_toast_notification" | "task_overdue_toast_notification" | "task_overdue_toast_notification_creator" | "task_notification_count" | "task_activities_toast_notification" | "task_created_toast_notification" | "task_group_creation_success" | "task_group_deletion_success" | "task_group_update_success" | "primary_funding_account_updated" | "task_time_spent_validation" | "missing_receipts_attachment" | "flux_analysis_unreviewed" | "flux_analysis_reviewed" | "receipt_match" | "receipts_upload" | "receipts_bulk_match" | "billing_address_view" | "express_pay_submit" | "exclude_transaction" | "reconcile" | "save_reconcile_for_later" | "recon_transaction_categorize" | "recon_transaction_match" | "update_debit_card_pin_attempt" | "set_debit_card_pin" | "ai_cfo_create_session_and_submit" | "ai_cfo_chat_session_deleted" | "charge_card_auto_pay_enable" | "charge_card_auto_pay_disable" | "treasury_setup" | "treasury_accept_term" | "treasury_transfer_money" | "treasury_transfer_money_failed" | "auto_transfer_rule_create" | "auto_transfer_rule_update" | "auto_transfer_rule_delete" | "auto_transfer_rule_pause" | "auto_transfer_rule_resume" | "treasury_update_portfolio_allocation" | "send_email_magic_link_to_user" | "complete_profile_done" | "create_transfer_entry" | "reports_resync" | "invalid_phone_number" | "transactions_categorized_updated_failed" | "transaction_categorized_updated_failed" | "transactionsCategorized_transactionsUpdated" | "transactionsCategorized_transactionUpdated" | "transactionCategorized_transactionsUpdated" | "transactionCategorized_transactionUpdated" | "transactionsCategorized_transactionsFailed" | "transactionsCategorized_transactionFailed" | "transactionCategorized_transactionsFailed" | "transactionCategorized_transactionFailed" | "transactionsUpdated_transactionsFailed" | "transactionsUpdated_transactionFailed" | "transactionUpdated_transactionsFailed" | "transactionUpdated_transactionFailed" | "transactionsCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionsUpdated_transactionFailed" | "transactionsCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionUpdated_transactionFailed" | "transactionCategorized_transactionsUpdated_transactionFailed" | "transactionCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionUpdated_transactionFailed" | "accounting_classes_enabled_update" | "accounting_projects_enabled_update" | "accounting_projects_qbo_not_enabled" | "capitalization_threshold_update" | "account_excluded_from_reconciliation" | "account_included_in_reconciliation" | "confirm_statement_mapping" | "statement_parsing_in_progress" | "statement_parsing_complete" | "ai_accountant_trigger_job" | "oauth_consent_approve" | "oauth_consent_invalid_request" | "credit_agent_update_profile" | "credit_agent_save_macro" | "credit_agent_schedule_cron" | "create_sub_task" | "qbo_connection_already_linked" | "qbo_connection_failed" | "accounting_projects_qbo_reconnect_failed" | "product_services_update" | "qbo_realm_id_update" | "invoicing_dunning_case_resolved" | "invoicing_dunning_retry" | "invoicing_dunning_cancel" | "invoicing_dunning_settings_save" | "invoicing_qbo_backfill" | "invoicing_qbo_sync_health_retry" | "invoicing_qbo_settings_save" | "invoicing_branding_save" | "invoicing_discount_archive" | "invoicing_discount_unarchive" | "invoicing_discount_delete" | "invoicing_invoice_reminder_sent" | "invoicing_invoice_regenerated" | "invoicing_invoice_voided" | "invoicing_catalog_item_saved" | "invoicing_customer_saved" | "invoicing_subscription_saved" | "invoicing_coupon_saved" | "invoicing_invoice_saved" | "invoicing_credit_note_saved" | "invoicing_payment_recorded" | "invoicing_subscription_activated" | "invoicing_subscription_cancellation_removed" | "invoicing_subscription_cancelled" | "invoicing_subscription_non_renewing" | "invoicing_subscription_paused" | "invoicing_subscription_reactivated" | "invoicing_subscription_resumed" | "invoicing_subscription_term_end_changed" | "invoicing_data_import_download";
42
+ messageSection: "common" | "recommendation_feedback" | "transactionDetails_updatingPastTransactions" | "transactionDetails_transactionUpdated" | "cockpit_month_end_email_sent" | "cockpit_month_end_email_save" | "cockpit_month_end_email_attachment_upload" | "je_bill_link" | "je_posted" | "actual_matching_match_and_reverse" | "actual_matching_undo_reversal" | "actual_matching_ignore_suggestion" | "audit_score_updated" | "people_invite_people" | "people_invite_multiple_people" | "people_delete_person" | "people_update_person" | "reimbursement_updated" | "reimbursement_deleted" | "reimbursement_cancelled_deleted" | "reimbursement_cancelled" | "reimbursement_approved" | "reimbursement_rejected" | "reimbursement_sent_for_approval" | "account_added" | "business_verification_save" | "business_verification_submit" | "business_verification_from_bills_submit" | "plaid_connection" | "unlink_deposit_account" | "reimbursement_setup" | "reimbursement_approval_create" | "reimbursement_duplicate_approval_create" | "reimbursement_approval_update" | "reimbursement_duplicate_approval_update" | "reimbursement_approval_delete" | "reimbursement_approval_reorder" | "reimbursement_create_mileage" | "reimbursement_update_mileage" | "reimbursement_accept_term" | "reimbursement_accept_employee_term" | "reimbursement_bulk_submit" | "reimbursement_bulk_processed" | "bill_pay_setup" | "zeni_accounts_setup" | "bill_pay_approval_create" | "bill_pay_duplicate_approval_create" | "bill_pay_approval_update" | "bill_pay_duplicate_approval_update" | "bill_pay_approval_delete" | "bill_pay_approval_reorder" | "bill_pay_updated" | "bill_pay_deleted" | "bill_pay_cancelled_deleted" | "bill_pay_cancelled" | "bill_pay_approved" | "real_time_approver_added" | "bill_pay_rejected" | "bill_pay_sent_for_approval" | "bill_pay_accept_term" | "bill_pay_bulk_submit" | "bill_pay_bulk_processed" | "bill_pay_refund" | "bill_pay_retry" | "bill_pay_marked_as_paid" | "zeni_account_accept_term" | "update_vendor" | "data_refresh_update" | "delete_bank_account" | "create_bank_account" | "create_bank_account_ach" | "create_bank_account_wire" | "create_bank_account_international" | "transfer_money" | "update_zeni_account_nickname" | "create_checking_account" | "deposit_check" | "create_vendor" | "onboarding_customer_view" | "onboarding_customer_view_complete" | "onboarding_customer_identity_verification_save" | "onboarding_customer_identity_verification_submit" | "onboarding_customer_business_verification_save" | "onboarding_customer_business_verification_submit" | "retry_bank_account_connection" | "dashboard_invite_sent" | "onboarding_info_saved" | "approve_original_merchant" | "approve_global_merchant" | "reject_global_merchant" | "create_global_merchant" | "fetch_global_merchant_no_recommendation" | "save_vendor_renamed" | "save_vendor_sent_for_review" | "save_vendor_marked_as_employee" | "save_vendor_marked_as_local_contractor" | "charge_card_setup" | "charge_card_accept_term" | "charge_card_receipt_upload" | "charge_card_resend_invite" | "charge_card_revoke_invite" | "card_policy_created" | "card_policy_updated" | "card_policy_deleted" | "charge_card_update_limit" | "charge_cards_update_limit" | "close_charge_card" | "lock_charge_card" | "lock_charge_card_card_user" | "lock_charge_cards" | "unlock_charge_card" | "unlock_charge_card_card_user" | "unlock_charge_cards" | "close_charge_cards" | "revoke_invite_charge_cards" | "charge_card_express_interest" | "create_schedule" | "save_schedule" | "delete_schedule" | "ignore_schedule" | "revert_schedule" | "ignore_accrual" | "revert_accrual" | "save_task_detail" | "fetch_task_detail" | "delete_task" | "archive_task" | "snooze_task" | "unsnooze_task" | "create_tag" | "delete_tag" | "update_charge_card" | "update_charge_card_name" | "update_charge_card_name_card_user" | "issue_charge_card" | "issue_charge_cards" | "notification_settings_saved" | "referral_invite_sent" | "notification_mark_as_read" | "mark_as_complete_schedule" | "cancel_journal_entry" | "settings_accounting_accounts_updated" | "create_card_setup" | "confirm_card_setup" | "add_card_payment_source" | "fetch_payment_sources" | "task_assigned_toast_notification" | "task_due_tomorrow_toast_notification" | "task_deleted_toast_notification" | "task_archived_toast_notification" | "task_overdue_toast_notification" | "task_overdue_toast_notification_creator" | "task_notification_count" | "task_activities_toast_notification" | "task_created_toast_notification" | "task_group_creation_success" | "task_group_deletion_success" | "task_group_update_success" | "primary_funding_account_updated" | "task_time_spent_validation" | "missing_receipts_attachment" | "flux_analysis_unreviewed" | "flux_analysis_reviewed" | "receipt_match" | "receipts_upload" | "receipts_bulk_match" | "billing_address_view" | "express_pay_submit" | "exclude_transaction" | "reconcile" | "save_reconcile_for_later" | "recon_transaction_categorize" | "recon_transaction_match" | "update_debit_card_pin_attempt" | "set_debit_card_pin" | "ai_cfo_create_session_and_submit" | "ai_cfo_chat_session_deleted" | "charge_card_auto_pay_enable" | "charge_card_auto_pay_disable" | "treasury_setup" | "treasury_accept_term" | "treasury_transfer_money" | "treasury_transfer_money_failed" | "auto_transfer_rule_create" | "auto_transfer_rule_update" | "auto_transfer_rule_delete" | "auto_transfer_rule_pause" | "auto_transfer_rule_resume" | "treasury_update_portfolio_allocation" | "send_email_magic_link_to_user" | "complete_profile_done" | "create_transfer_entry" | "reports_resync" | "invalid_phone_number" | "transactions_categorized_updated_failed" | "transaction_categorized_updated_failed" | "transactionsCategorized_transactionsUpdated" | "transactionsCategorized_transactionUpdated" | "transactionCategorized_transactionsUpdated" | "transactionCategorized_transactionUpdated" | "transactionsCategorized_transactionsFailed" | "transactionsCategorized_transactionFailed" | "transactionCategorized_transactionsFailed" | "transactionCategorized_transactionFailed" | "transactionsUpdated_transactionsFailed" | "transactionsUpdated_transactionFailed" | "transactionUpdated_transactionsFailed" | "transactionUpdated_transactionFailed" | "transactionsCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionsUpdated_transactionFailed" | "transactionsCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionUpdated_transactionFailed" | "transactionCategorized_transactionsUpdated_transactionFailed" | "transactionCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionUpdated_transactionFailed" | "accounting_classes_enabled_update" | "accounting_projects_enabled_update" | "accounting_projects_qbo_not_enabled" | "capitalization_threshold_update" | "account_excluded_from_reconciliation" | "account_included_in_reconciliation" | "confirm_statement_mapping" | "statement_parsing_in_progress" | "statement_parsing_complete" | "ai_accountant_trigger_job" | "oauth_consent_approve" | "oauth_consent_invalid_request" | "credit_agent_update_profile" | "credit_agent_save_macro" | "credit_agent_schedule_cron" | "create_sub_task" | "qbo_connection_already_linked" | "qbo_connection_failed" | "accounting_projects_qbo_reconnect_failed" | "product_services_update" | "qbo_realm_id_update" | "invoicing_dunning_case_resolved" | "invoicing_dunning_retry" | "invoicing_dunning_cancel" | "invoicing_dunning_settings_save" | "invoicing_qbo_backfill" | "invoicing_qbo_sync_health_retry" | "invoicing_qbo_settings_save" | "invoicing_branding_save" | "invoicing_discount_archive" | "invoicing_discount_unarchive" | "invoicing_discount_delete" | "invoicing_invoice_reminder_sent" | "invoicing_invoice_regenerated" | "invoicing_invoice_voided" | "invoicing_catalog_item_saved" | "invoicing_customer_saved" | "invoicing_subscription_saved" | "invoicing_coupon_saved" | "invoicing_invoice_saved" | "invoicing_credit_note_saved" | "invoicing_payment_recorded" | "invoicing_subscription_activated" | "invoicing_subscription_cancellation_removed" | "invoicing_subscription_cancelled" | "invoicing_subscription_non_renewing" | "invoicing_subscription_paused" | "invoicing_subscription_reactivated" | "invoicing_subscription_resumed" | "invoicing_subscription_term_end_changed" | "invoicing_data_import_download";
43
43
  messageText: "notification" | "failed" | "success";
44
44
  type: "error" | "success" | "info";
45
45
  variables: {
@@ -3,7 +3,7 @@ import { TimePeriod } from '../../../commonStateTypes/timePeriod';
3
3
  import { ActualMatchingListResponsePayload, DisplayCurrencyFallback } from '../../../entity/actualMatching/actualMatchingPayload';
4
4
  import { JEOneTimeAccrualPayload } from '../../../entity/jeSchedules/jeSchedulesPayload';
5
5
  import { ZeniAPIResponse } from '../../../responsePayload';
6
- import { ActualMatchingTransactionSearchResult, MatchAndReverseResult, UndoReversalResult } from '../types/actualMatchingViewState';
6
+ import { ActualMatchingIgnoreReasonType, ActualMatchingTransactionSearchResult, MatchAndReverseResult, UndoReversalResult } from '../types/actualMatchingViewState';
7
7
  export declare function toServiceMonthFromPeriod(period: TimePeriod): string;
8
8
  export type ActualMatchingListResponse = ZeniAPIResponse<ActualMatchingListResponsePayload>;
9
9
  export interface ActualMatchingAccrualSearchResponsePayload {
@@ -72,6 +72,17 @@ export declare function toMatchAndReverseResult(payload: MatchAndReverseResultPa
72
72
  export interface UndoReversalRequestPayload {
73
73
  accrual_ids: ID[];
74
74
  }
75
+ export interface IgnoreActualMatchingSuggestionRequestPayload {
76
+ reason: ActualMatchingIgnoreReasonType;
77
+ note?: string;
78
+ }
79
+ export interface IgnoreActualMatchingSuggestionResponsePayload {
80
+ already_dismissed_accrual_ids?: string[];
81
+ dismissed_accrual_ids?: string[];
82
+ match_id?: string;
83
+ no_longer_eligible_accrual_ids?: string[];
84
+ }
85
+ export type IgnoreActualMatchingSuggestionResponse = ZeniAPIResponse<IgnoreActualMatchingSuggestionResponsePayload>;
75
86
  export interface UndoReversalResultPayload {
76
87
  accrual_id: ID;
77
88
  status: string;
@@ -7,7 +7,7 @@ export declare const initialTransactionSearchState: ActualMatchingTransactionSea
7
7
  export declare const initialAccrualSearchState: ActualMatchingAccrualSearchState;
8
8
  export declare const initialMatchModalState: ActualMatchingMatchModalState;
9
9
  export declare const initialState: ActualMatchingViewState;
10
- export declare const ackCloseMatchAfterUndo: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationActualMatchingView/ackCloseMatchAfterUndo">, clearActualMatchingView: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationActualMatchingView/clearActualMatchingView">, clearMatchNewModal: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationActualMatchingView/clearMatchNewModal">, closeMatchNewModal: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationActualMatchingView/closeMatchNewModal">, fetchActualMatching: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[period: TimePeriod, refreshViewInBackground?: any], {
10
+ export declare const ackCloseMatchAfterIgnore: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationActualMatchingView/ackCloseMatchAfterIgnore">, ackCloseMatchAfterUndo: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationActualMatchingView/ackCloseMatchAfterUndo">, clearActualMatchingView: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationActualMatchingView/clearActualMatchingView">, clearMatchNewModal: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationActualMatchingView/clearMatchNewModal">, closeMatchNewModal: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationActualMatchingView/closeMatchNewModal">, fetchActualMatching: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[period: TimePeriod, refreshViewInBackground?: any], {
11
11
  period: TimePeriod;
12
12
  refreshViewInBackground: any;
13
13
  }, "expenseAutomationActualMatchingView/fetchActualMatching", never, never>, fetchActualMatchingFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
@@ -31,21 +31,32 @@ export declare const ackCloseMatchAfterUndo: import("@reduxjs/toolkit").ActionCr
31
31
  matchIds: ActualMatchingMatchId[];
32
32
  refreshViewInBackground: boolean;
33
33
  selectedPeriod: MonthYearPeriod;
34
- }, "expenseAutomationActualMatchingView/fetchActualMatchingSuccess">, matchAndReverseAccruals: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionId: string, transactionIntegrationId: string, transactionType: string, lineIds: string[], transactionSyncToken: string, accrualIds: string[]], {
34
+ }, "expenseAutomationActualMatchingView/fetchActualMatchingSuccess">, ignoreActualMatchingSuggestion: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[matchId: string, reason: "other_ignore" | "already_handled" | "amount_off" | "wrong_period" | "wrong_bill", note?: string | undefined], {
35
+ matchId: string;
36
+ reason: "other_ignore" | "already_handled" | "amount_off" | "wrong_period" | "wrong_bill";
37
+ note: string | undefined;
38
+ }, "expenseAutomationActualMatchingView/ignoreActualMatchingSuggestion", never, never>, ignoreActualMatchingSuggestionFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
39
+ matchId: ActualMatchingMatchId;
40
+ status: ZeniAPIStatus;
41
+ }, "expenseAutomationActualMatchingView/ignoreActualMatchingSuggestionFailure">, ignoreActualMatchingSuggestionSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
42
+ matchId: ActualMatchingMatchId;
43
+ }, "expenseAutomationActualMatchingView/ignoreActualMatchingSuggestionSuccess">, matchAndReverseAccruals: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[transactionId: string, transactionIntegrationId: string, transactionType: string, lineIds: string[], transactionSyncToken: string, accrualIds: string[], forMatchModal?: boolean | undefined], {
44
+ accrualIds: string[];
45
+ lineIds: string[];
35
46
  transactionId: string;
36
47
  transactionIntegrationId: string;
37
- transactionType: string;
38
- lineIds: string[];
39
48
  transactionSyncToken: string;
40
- accrualIds: string[];
49
+ transactionType: string;
50
+ forMatchModal: boolean | undefined;
41
51
  }, "expenseAutomationActualMatchingView/matchAndReverseAccruals", never, never>, matchAndReverseAccrualsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
42
52
  status: ZeniAPIStatus;
53
+ forMatchModal?: boolean;
54
+ matchId?: ActualMatchingMatchId;
43
55
  }, "expenseAutomationActualMatchingView/matchAndReverseAccrualsFailure">, matchAndReverseAccrualsSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
44
56
  results: MatchAndReverseResult[];
57
+ forMatchModal?: boolean;
45
58
  matchId?: ActualMatchingMatchId;
46
- }, "expenseAutomationActualMatchingView/matchAndReverseAccrualsSuccess">, openMatchNewModal: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[matchId?: string | undefined], {
47
- matchId: string | undefined;
48
- }, "expenseAutomationActualMatchingView/openMatchNewModal", never, never>, searchMatchAccruals: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[query: string, pageToken?: string | null | undefined], {
59
+ }, "expenseAutomationActualMatchingView/matchAndReverseAccrualsSuccess">, openMatchNewModal: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationActualMatchingView/openMatchNewModal">, searchMatchAccruals: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[query: string, pageToken?: string | null | undefined], {
49
60
  query: string;
50
61
  pageToken: string | undefined;
51
62
  }, "expenseAutomationActualMatchingView/searchMatchAccruals", never, never>, searchMatchAccrualsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.updateActualMatchingUIState = exports.undoReversalAccrualsSuccess = exports.undoReversalAccrualsFailure = exports.undoReversalAccruals = exports.searchMatchTransactionsSuccess = exports.searchMatchTransactionsFailure = exports.searchMatchTransactions = exports.searchMatchAccrualsSuccess = exports.searchMatchAccrualsFailure = exports.searchMatchAccruals = exports.openMatchNewModal = exports.matchAndReverseAccrualsSuccess = exports.matchAndReverseAccrualsFailure = exports.matchAndReverseAccruals = exports.fetchActualMatchingSuccess = exports.fetchActualMatchingPage = exports.fetchActualMatchingMatchSuccess = exports.fetchActualMatchingMatchFailure = exports.fetchActualMatchingMatch = exports.fetchActualMatchingFailure = exports.fetchActualMatching = exports.closeMatchNewModal = exports.clearMatchNewModal = exports.clearActualMatchingView = exports.ackCloseMatchAfterUndo = exports.initialState = exports.initialMatchModalState = exports.initialAccrualSearchState = exports.initialTransactionSearchState = void 0;
4
+ exports.updateActualMatchingUIState = exports.undoReversalAccrualsSuccess = exports.undoReversalAccrualsFailure = exports.undoReversalAccruals = exports.searchMatchTransactionsSuccess = exports.searchMatchTransactionsFailure = exports.searchMatchTransactions = exports.searchMatchAccrualsSuccess = exports.searchMatchAccrualsFailure = exports.searchMatchAccruals = exports.openMatchNewModal = exports.matchAndReverseAccrualsSuccess = exports.matchAndReverseAccrualsFailure = exports.matchAndReverseAccruals = exports.ignoreActualMatchingSuggestionSuccess = exports.ignoreActualMatchingSuggestionFailure = exports.ignoreActualMatchingSuggestion = exports.fetchActualMatchingSuccess = exports.fetchActualMatchingPage = exports.fetchActualMatchingMatchSuccess = exports.fetchActualMatchingMatchFailure = exports.fetchActualMatchingMatch = exports.fetchActualMatchingFailure = exports.fetchActualMatching = exports.closeMatchNewModal = exports.clearMatchNewModal = exports.clearActualMatchingView = exports.ackCloseMatchAfterUndo = exports.ackCloseMatchAfterIgnore = exports.initialState = exports.initialMatchModalState = exports.initialAccrualSearchState = exports.initialTransactionSearchState = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
7
7
  const jeScheduleHelper_1 = require("../../../entity/jeSchedules/jeScheduleHelper");
@@ -26,9 +26,6 @@ exports.initialAccrualSearchState = {
26
26
  };
27
27
  exports.initialMatchModalState = {
28
28
  isOpen: false,
29
- openedFromMatchId: undefined,
30
- didPinPrefillTransactions: false,
31
- pinnedTransactionResults: [],
32
29
  transactionSearch: exports.initialTransactionSearchState,
33
30
  accrualSearch: exports.initialAccrualSearchState,
34
31
  confirmStatus: { fetchState: 'Not-Started', error: undefined },
@@ -48,16 +45,28 @@ exports.initialState = {
48
45
  sortOrder: 'descending',
49
46
  searchString: '',
50
47
  scrollPosition: { scrollTop: 0, scrollLeft: undefined },
48
+ statusFilter: 'all',
51
49
  },
52
50
  matchModal: exports.initialMatchModalState,
53
51
  undoReversalStatusByMatchId: {},
54
- closeMatchAfterUndo: false,
52
+ ignoreStatusByMatchId: {},
53
+ confirmStatusByMatchId: {},
54
+ closeMatchAfterUndoMatchIds: [],
55
+ closeMatchAfterIgnoreMatchIds: [],
55
56
  lastMatchResultsByMatchId: {},
56
57
  lastUndoResultsByMatchId: {},
57
58
  hasValidState() {
58
59
  return this.fetchState == 'Completed';
59
60
  },
60
61
  };
62
+ function enqueueCloseMatchId(ids, matchId) {
63
+ if (!ids.includes(matchId)) {
64
+ ids.push(matchId);
65
+ }
66
+ }
67
+ function dropCloseMatchId(ids, matchId) {
68
+ return ids.filter((id) => id !== matchId);
69
+ }
61
70
  function pruneLastMatchResultsForUndone(draft, matchId, results) {
62
71
  const undoneIds = new Set(results
63
72
  .filter((result) => result.status === 'undone')
@@ -100,9 +109,6 @@ function resetMatchModalSearches(draft) {
100
109
  error: undefined,
101
110
  };
102
111
  draft.matchModal.lastBatchResults = undefined;
103
- draft.matchModal.openedFromMatchId = undefined;
104
- draft.matchModal.didPinPrefillTransactions = false;
105
- draft.matchModal.pinnedTransactionResults = [];
106
112
  }
107
113
  const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
108
114
  name: 'expenseAutomationActualMatchingView',
@@ -243,21 +249,13 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
243
249
  if (action.payload.scrollPosition != null) {
244
250
  draft.uiState.scrollPosition = action.payload.scrollPosition;
245
251
  }
252
+ if (action.payload.statusFilter != null) {
253
+ draft.uiState.statusFilter = action.payload.statusFilter;
254
+ }
246
255
  },
247
- openMatchNewModal: {
248
- prepare(matchId) {
249
- return { payload: { matchId } };
250
- },
251
- reducer(draft, action) {
252
- resetMatchModalSearches(draft);
253
- draft.matchModal.isOpen = true;
254
- const matchId = action.payload.matchId;
255
- draft.matchModal.openedFromMatchId =
256
- matchId != null && matchId !== '' ? matchId : undefined;
257
- if (draft.matchModal.openedFromMatchId != null) {
258
- draft.matchModal.accrualSearch.fetchState = 'Completed';
259
- }
260
- },
256
+ openMatchNewModal(draft) {
257
+ resetMatchModalSearches(draft);
258
+ draft.matchModal.isOpen = true;
261
259
  },
262
260
  // Dismiss (Cancel / overlay). Store reset matches `clearMatchNewModal`;
263
261
  // the actions stay distinct so confirm-success vs user-dismiss stay observable.
@@ -312,11 +310,6 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
312
310
  }
313
311
  else {
314
312
  draft.matchModal.transactionSearch.results = results;
315
- if (draft.matchModal.openedFromMatchId != null &&
316
- !draft.matchModal.didPinPrefillTransactions) {
317
- draft.matchModal.didPinPrefillTransactions = true;
318
- draft.matchModal.pinnedTransactionResults = results;
319
- }
320
313
  }
321
314
  draft.matchModal.transactionSearch.nextPageToken = nextPageToken;
322
315
  draft.matchModal.transactionSearch.isLoadingMore = false;
@@ -369,21 +362,27 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
369
362
  draft.matchModal.accrualSearch.error = action.payload.error;
370
363
  },
371
364
  matchAndReverseAccruals: {
372
- reducer(draft) {
373
- draft.matchModal.confirmStatus = {
365
+ reducer(draft, action) {
366
+ const inProgress = {
374
367
  fetchState: 'In-Progress',
375
368
  error: undefined,
376
369
  };
370
+ if (action.payload.forMatchModal === true) {
371
+ draft.matchModal.confirmStatus = inProgress;
372
+ }
373
+ const matchId = `${action.payload.transactionType.toLowerCase()}:${action.payload.transactionIntegrationId}`;
374
+ draft.confirmStatusByMatchId[matchId] = inProgress;
377
375
  },
378
- prepare(transactionId, transactionIntegrationId, transactionType, lineIds, transactionSyncToken, accrualIds) {
376
+ prepare(transactionId, transactionIntegrationId, transactionType, lineIds, transactionSyncToken, accrualIds, forMatchModal) {
379
377
  return {
380
378
  payload: {
379
+ accrualIds,
380
+ lineIds,
381
381
  transactionId,
382
382
  transactionIntegrationId,
383
- transactionType,
384
- lineIds,
385
383
  transactionSyncToken,
386
- accrualIds,
384
+ transactionType,
385
+ forMatchModal,
387
386
  },
388
387
  };
389
388
  },
@@ -392,23 +391,33 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
392
391
  const { results } = action.payload;
393
392
  const allComplete = results.length > 0 &&
394
393
  results.every((result) => (0, actualMatchingViewState_1.isMatchAndReverseCompleteStatus)(result.status));
395
- draft.matchModal.confirmStatus = allComplete
394
+ const confirmStatus = allComplete
396
395
  ? { fetchState: 'Completed', error: undefined }
397
396
  : {
398
397
  fetchState: 'Error',
399
398
  error: (0, responsePayload_1.createZeniAPIStatus)('Partial match-and-reverse', 'Some accruals were not reversed'),
400
399
  };
401
- draft.matchModal.lastBatchResults = results;
400
+ if (action.payload.forMatchModal === true) {
401
+ draft.matchModal.confirmStatus = confirmStatus;
402
+ draft.matchModal.lastBatchResults = results;
403
+ }
402
404
  if (action.payload.matchId != null) {
405
+ draft.confirmStatusByMatchId[action.payload.matchId] = confirmStatus;
403
406
  draft.lastMatchResultsByMatchId[action.payload.matchId] = results;
404
407
  pruneLastUndoResultsForMatched(draft, action.payload.matchId, action.payload.results);
405
408
  }
406
409
  },
407
410
  matchAndReverseAccrualsFailure(draft, action) {
408
- draft.matchModal.confirmStatus = {
411
+ const failed = {
409
412
  fetchState: 'Error',
410
413
  error: action.payload.status,
411
414
  };
415
+ if (action.payload.forMatchModal === true) {
416
+ draft.matchModal.confirmStatus = failed;
417
+ }
418
+ if (action.payload.matchId != null) {
419
+ draft.confirmStatusByMatchId[action.payload.matchId] = failed;
420
+ }
412
421
  },
413
422
  undoReversalAccruals: {
414
423
  reducer(draft, action) {
@@ -430,7 +439,12 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
430
439
  };
431
440
  const allUndone = results.length > 0 &&
432
441
  results.every((result) => result.status === 'undone');
433
- draft.closeMatchAfterUndo = allUndone;
442
+ if (allUndone) {
443
+ enqueueCloseMatchId(draft.closeMatchAfterUndoMatchIds, matchId);
444
+ }
445
+ else {
446
+ draft.closeMatchAfterUndoMatchIds = dropCloseMatchId(draft.closeMatchAfterUndoMatchIds, matchId);
447
+ }
434
448
  pruneLastMatchResultsForUndone(draft, matchId, results);
435
449
  if (allUndone) {
436
450
  delete draft.lastUndoResultsByMatchId[matchId];
@@ -444,7 +458,44 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
444
458
  },
445
459
  },
446
460
  ackCloseMatchAfterUndo(draft) {
447
- draft.closeMatchAfterUndo = false;
461
+ draft.closeMatchAfterUndoMatchIds.shift();
462
+ },
463
+ ignoreActualMatchingSuggestion: {
464
+ prepare(matchId, reason, note) {
465
+ return { payload: { matchId, reason, note } };
466
+ },
467
+ reducer(draft, action) {
468
+ draft.ignoreStatusByMatchId[action.payload.matchId] = {
469
+ fetchState: 'In-Progress',
470
+ error: undefined,
471
+ };
472
+ },
473
+ },
474
+ ignoreActualMatchingSuggestionSuccess(draft, action) {
475
+ const { matchId } = action.payload;
476
+ draft.ignoreStatusByMatchId[matchId] = {
477
+ fetchState: 'Completed',
478
+ error: undefined,
479
+ };
480
+ enqueueCloseMatchId(draft.closeMatchAfterIgnoreMatchIds, matchId);
481
+ delete draft.lastMatchResultsByMatchId[matchId];
482
+ delete draft.lastUndoResultsByMatchId[matchId];
483
+ delete draft.detailFetchStateByMatchId[matchId];
484
+ delete draft.detailRefreshStatusByMatchId[matchId];
485
+ delete draft.undoReversalStatusByMatchId[matchId];
486
+ delete draft.confirmStatusByMatchId[matchId];
487
+ Object.keys(draft.matchIdsByPeriod).forEach((periodId) => {
488
+ draft.matchIdsByPeriod[periodId] = draft.matchIdsByPeriod[periodId].filter((id) => id !== matchId);
489
+ });
490
+ },
491
+ ignoreActualMatchingSuggestionFailure(draft, action) {
492
+ draft.ignoreStatusByMatchId[action.payload.matchId] = {
493
+ fetchState: 'Error',
494
+ error: action.payload.status,
495
+ };
496
+ },
497
+ ackCloseMatchAfterIgnore(draft) {
498
+ draft.closeMatchAfterIgnoreMatchIds.shift();
448
499
  },
449
500
  undoReversalAccrualsFailure(draft, action) {
450
501
  draft.undoReversalStatusByMatchId[action.payload.matchId] = {
@@ -462,5 +513,5 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
462
513
  });
463
514
  },
464
515
  });
465
- _a = expenseAutomationActualMatchingView.actions, exports.ackCloseMatchAfterUndo = _a.ackCloseMatchAfterUndo, exports.clearActualMatchingView = _a.clearActualMatchingView, exports.clearMatchNewModal = _a.clearMatchNewModal, exports.closeMatchNewModal = _a.closeMatchNewModal, exports.fetchActualMatching = _a.fetchActualMatching, exports.fetchActualMatchingFailure = _a.fetchActualMatchingFailure, exports.fetchActualMatchingMatch = _a.fetchActualMatchingMatch, exports.fetchActualMatchingMatchFailure = _a.fetchActualMatchingMatchFailure, exports.fetchActualMatchingMatchSuccess = _a.fetchActualMatchingMatchSuccess, exports.fetchActualMatchingPage = _a.fetchActualMatchingPage, exports.fetchActualMatchingSuccess = _a.fetchActualMatchingSuccess, exports.matchAndReverseAccruals = _a.matchAndReverseAccruals, exports.matchAndReverseAccrualsFailure = _a.matchAndReverseAccrualsFailure, exports.matchAndReverseAccrualsSuccess = _a.matchAndReverseAccrualsSuccess, exports.openMatchNewModal = _a.openMatchNewModal, exports.searchMatchAccruals = _a.searchMatchAccruals, exports.searchMatchAccrualsFailure = _a.searchMatchAccrualsFailure, exports.searchMatchAccrualsSuccess = _a.searchMatchAccrualsSuccess, exports.searchMatchTransactions = _a.searchMatchTransactions, exports.searchMatchTransactionsFailure = _a.searchMatchTransactionsFailure, exports.searchMatchTransactionsSuccess = _a.searchMatchTransactionsSuccess, exports.undoReversalAccruals = _a.undoReversalAccruals, exports.undoReversalAccrualsFailure = _a.undoReversalAccrualsFailure, exports.undoReversalAccrualsSuccess = _a.undoReversalAccrualsSuccess, exports.updateActualMatchingUIState = _a.updateActualMatchingUIState;
516
+ _a = expenseAutomationActualMatchingView.actions, exports.ackCloseMatchAfterIgnore = _a.ackCloseMatchAfterIgnore, exports.ackCloseMatchAfterUndo = _a.ackCloseMatchAfterUndo, exports.clearActualMatchingView = _a.clearActualMatchingView, exports.clearMatchNewModal = _a.clearMatchNewModal, exports.closeMatchNewModal = _a.closeMatchNewModal, exports.fetchActualMatching = _a.fetchActualMatching, exports.fetchActualMatchingFailure = _a.fetchActualMatchingFailure, exports.fetchActualMatchingMatch = _a.fetchActualMatchingMatch, exports.fetchActualMatchingMatchFailure = _a.fetchActualMatchingMatchFailure, exports.fetchActualMatchingMatchSuccess = _a.fetchActualMatchingMatchSuccess, exports.fetchActualMatchingPage = _a.fetchActualMatchingPage, exports.fetchActualMatchingSuccess = _a.fetchActualMatchingSuccess, exports.ignoreActualMatchingSuggestion = _a.ignoreActualMatchingSuggestion, exports.ignoreActualMatchingSuggestionFailure = _a.ignoreActualMatchingSuggestionFailure, exports.ignoreActualMatchingSuggestionSuccess = _a.ignoreActualMatchingSuggestionSuccess, exports.matchAndReverseAccruals = _a.matchAndReverseAccruals, exports.matchAndReverseAccrualsFailure = _a.matchAndReverseAccrualsFailure, exports.matchAndReverseAccrualsSuccess = _a.matchAndReverseAccrualsSuccess, exports.openMatchNewModal = _a.openMatchNewModal, exports.searchMatchAccruals = _a.searchMatchAccruals, exports.searchMatchAccrualsFailure = _a.searchMatchAccrualsFailure, exports.searchMatchAccrualsSuccess = _a.searchMatchAccrualsSuccess, exports.searchMatchTransactions = _a.searchMatchTransactions, exports.searchMatchTransactionsFailure = _a.searchMatchTransactionsFailure, exports.searchMatchTransactionsSuccess = _a.searchMatchTransactionsSuccess, exports.undoReversalAccruals = _a.undoReversalAccruals, exports.undoReversalAccrualsFailure = _a.undoReversalAccrualsFailure, exports.undoReversalAccrualsSuccess = _a.undoReversalAccrualsSuccess, exports.updateActualMatchingUIState = _a.updateActualMatchingUIState;
466
517
  exports.default = expenseAutomationActualMatchingView.reducer;
@@ -43,6 +43,9 @@ export interface ActualMatchingKpiSummary {
43
43
  count: number;
44
44
  estimatedMinutesToClear: number;
45
45
  };
46
+ reversed: {
47
+ count: number;
48
+ };
46
49
  variance: {
47
50
  averagePercentPerMatch: number;
48
51
  netAmount: number;
@@ -67,21 +70,30 @@ export interface ActualMatchingMatchModalView {
67
70
  results: ActualMatchingTransactionSearchResult[];
68
71
  };
69
72
  lastBatchResults?: MatchAndReverseResult[];
70
- openedFromMatchId?: string;
71
- prefill?: {
72
- selectedAccrualIds: ID[];
73
- actualAmount?: number;
74
- consumedLineIds?: ID[];
75
- matchedLineId?: string;
76
- matchedTransactionId?: string;
77
- };
73
+ }
74
+ export interface ActualMatchingMatchView {
75
+ accruedAmount: Amount;
76
+ actualAmount: Amount;
77
+ kind: ActualMatchingRowKind;
78
+ matchId: string;
79
+ members: JEOneTimeAccrual[];
80
+ transactionIntegrationId: ID;
81
+ transactionType: string;
82
+ leftovers?: JEOneTimeAccrual[];
83
+ matchShape?: string;
84
+ matchTier?: string;
85
+ transactionDate?: string;
86
+ vendorId?: ID;
87
+ vendorName?: string;
78
88
  }
79
89
  export interface ExpenseAutomationActualMatchingViewSelector extends SelectorView {
80
90
  hasLoadedForSelectedPeriod: boolean;
91
+ ignoreStatusByMatchId: Record<string, FetchStateAndError>;
81
92
  kpiSummary: ActualMatchingKpiSummary;
82
93
  matchModal: ActualMatchingMatchModalView;
83
94
  pendingReview: ActualMatchingRow[];
84
95
  refreshStatus: FetchStateAndError;
85
96
  reversed: ActualMatchingRow[];
86
97
  uiState: ActualMatchingViewUIState;
98
+ undoReversalStatusByMatchId: Record<string, FetchStateAndError>;
87
99
  }