@zeniai/client-epic-state 5.1.8-betaAS1 → 5.1.8-betaSS1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonPayloadTypes/commonPayload.d.ts +4 -25
- package/lib/esm/index.js +3 -8
- package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +3 -3
- package/lib/esm/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.js +4 -3
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +12 -13
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/backgroundRefetchReviewTabEpic.js +19 -3
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +19 -9
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationViewEpic.js +2 -2
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/markTransactionAsNotMiscategorizedEpic.js +13 -2
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/saveTransactionCategorizationEpic.js +6 -2
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/triggerReviewTabRefetchEpic.js +2 -2
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/updateTransactionCategorizationEpic.js +6 -2
- package/lib/esm/view/expenseAutomationView/expenseAutomationViewReducer.js +20 -3
- package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +48 -8
- package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +5 -4
- package/lib/esm/view/spendManagement/billPay/internationalWireVerification/epics/fetchIntlVerificationFormEpic.js +3 -7
- package/lib/esm/view/spendManagement/billPay/internationalWireVerification/epics/initializeIntlVerificationFormEpic.js +34 -33
- package/lib/esm/view/spendManagement/billPay/internationalWireVerification/epics/submitIntlVerificationEpic.js +7 -2
- package/lib/esm/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationPayload.js +8 -55
- package/lib/esm/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationReducer.js +6 -5
- package/lib/esm/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSelector.js +15 -39
- package/lib/index.d.ts +4 -10
- package/lib/index.js +30 -47
- package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +3 -3
- package/lib/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.js +4 -3
- package/lib/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.d.ts +0 -6
- package/lib/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +13 -14
- package/lib/view/expenseAutomationView/epics/transactionCategorization/backgroundRefetchReviewTabEpic.js +19 -3
- package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +19 -9
- package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationViewEpic.js +2 -2
- package/lib/view/expenseAutomationView/epics/transactionCategorization/markTransactionAsNotMiscategorizedEpic.js +13 -2
- package/lib/view/expenseAutomationView/epics/transactionCategorization/saveTransactionCategorizationEpic.js +6 -2
- package/lib/view/expenseAutomationView/epics/transactionCategorization/triggerReviewTabRefetchEpic.js +2 -2
- package/lib/view/expenseAutomationView/epics/transactionCategorization/updateTransactionCategorizationEpic.js +6 -2
- package/lib/view/expenseAutomationView/expenseAutomationViewReducer.d.ts +6 -2
- package/lib/view/expenseAutomationView/expenseAutomationViewReducer.js +20 -3
- package/lib/view/expenseAutomationView/payload/transactionCategorizationPayload.d.ts +9 -20
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +17 -8
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +48 -8
- package/lib/view/expenseAutomationView/selectorTypes/transactionsViewSelectorTypes.d.ts +5 -4
- package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +5 -4
- package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +2 -1
- package/lib/view/spendManagement/billPay/internationalWireVerification/epics/fetchIntlVerificationFormEpic.d.ts +3 -3
- package/lib/view/spendManagement/billPay/internationalWireVerification/epics/fetchIntlVerificationFormEpic.js +2 -6
- package/lib/view/spendManagement/billPay/internationalWireVerification/epics/initializeIntlVerificationFormEpic.d.ts +1 -2
- package/lib/view/spendManagement/billPay/internationalWireVerification/epics/initializeIntlVerificationFormEpic.js +33 -32
- package/lib/view/spendManagement/billPay/internationalWireVerification/epics/submitIntlVerificationEpic.js +7 -2
- package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationPayload.d.ts +1 -24
- package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationPayload.js +9 -59
- package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationReducer.js +5 -4
- package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSelector.js +15 -39
- package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationState.d.ts +1 -20
- package/package.json +1 -1
- package/lib/esm/view/spendManagement/billPay/internationalWireVerification/internationalWireOnboardingDetailsToLocalData.js +0 -146
- package/lib/esm/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationFieldConstants.js +0 -40
- package/lib/esm/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationLocalDataHelpers.js +0 -86
- package/lib/esm/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSubmitPayload.js +0 -154
- package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireOnboardingDetailsToLocalData.d.ts +0 -4
- package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireOnboardingDetailsToLocalData.js +0 -150
- package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationFieldConstants.d.ts +0 -38
- package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationFieldConstants.js +0 -43
- package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationLocalDataHelpers.d.ts +0 -27
- package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationLocalDataHelpers.js +0 -96
- package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSubmitPayload.d.ts +0 -32
- package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSubmitPayload.js +0 -159
|
@@ -10,31 +10,10 @@ export interface AllowedValueWithCodeOptionalPayload {
|
|
|
10
10
|
export declare function isAllowedValueWithCodePayload(allowedValueWithCodePayload: any): allowedValueWithCodePayload is AllowedValueWithCodePayload;
|
|
11
11
|
export declare function isAllowedValueWithCodeOptionalPayload(allowedValueWithCodePayload: any): allowedValueWithCodePayload is AllowedValueWithCodeOptionalPayload;
|
|
12
12
|
export declare function toAllowedValueWithCode(allowedValueWithCodePayload: AllowedValueWithCodePayload): AllowedValueWithCode;
|
|
13
|
-
export interface LabelValueCodeDescriptionPayload {
|
|
14
|
-
code: string;
|
|
15
|
-
description: string;
|
|
16
|
-
}
|
|
17
|
-
export interface LabelValueFileOptionPayload {
|
|
18
|
-
file_id: string;
|
|
19
|
-
option?: string;
|
|
20
|
-
}
|
|
21
|
-
export interface LabelValuePersonNamePayload {
|
|
22
|
-
first_name?: string;
|
|
23
|
-
last_name?: string;
|
|
24
|
-
}
|
|
25
|
-
export interface LabelValuePersonPayload {
|
|
26
|
-
company_role?: string;
|
|
27
|
-
date_of_birth?: string;
|
|
28
|
-
email?: string;
|
|
29
|
-
name?: LabelValuePersonNamePayload;
|
|
30
|
-
nationality?: string;
|
|
31
|
-
ownership_percentage?: number;
|
|
32
|
-
proof_of_address?: LabelValueFileOptionPayload[];
|
|
33
|
-
proof_of_identity?: LabelValueFileOptionPayload[];
|
|
34
|
-
ssn?: string;
|
|
35
|
-
}
|
|
36
|
-
export type LabelValueCodesValuesPayload = string | string[] | LabelValueCodeDescriptionPayload | LabelValueCodeDescriptionPayload[] | LabelValueFileOptionPayload | LabelValueFileOptionPayload[] | LabelValuePersonPayload | LabelValuePersonPayload[];
|
|
37
13
|
export interface LabelValueCodesPayload {
|
|
38
14
|
label: string;
|
|
39
|
-
values:
|
|
15
|
+
values: {
|
|
16
|
+
code: string;
|
|
17
|
+
description: string;
|
|
18
|
+
}[] | string[];
|
|
40
19
|
}
|
package/lib/esm/index.js
CHANGED
|
@@ -73,7 +73,7 @@ import { getLastNotificationTime, getNotifications, } from './entity/toastNotifi
|
|
|
73
73
|
import { mapFileEntityToAttachment, toContentType, toContentTypeStrict, } from './entity/transaction/stateTypes/attachment';
|
|
74
74
|
import { isCustomerTransaction, } from './entity/transaction/stateTypes/customerTransaction';
|
|
75
75
|
import { isTransferTransaction, } from './entity/transaction/stateTypes/otherTransaction';
|
|
76
|
-
import { toPlatformLineDetailType, } from './entity/transaction/stateTypes/transactionLine';
|
|
76
|
+
import { toCategorizationStatusType, toPlatformLineDetailType, } from './entity/transaction/stateTypes/transactionLine';
|
|
77
77
|
import { toTransactionCategory, toTransactionType, toTransactionTypeStrict, } from './entity/transaction/stateTypes/transactionType';
|
|
78
78
|
import { isVendorTransaction, isVendorTransactionWithCustomer, } from './entity/transaction/stateTypes/vendorTransaction';
|
|
79
79
|
import { getSupportedTransactionById } from './entity/transaction/transactionSelector';
|
|
@@ -292,7 +292,6 @@ import { convertAmountToHomeCurrency, discardBillUpdatesInLocalStore, discardOut
|
|
|
292
292
|
import { checkIfCreatorIsApprover, getEditBillDetail, toPaymentToOption, } from './view/spendManagement/billPay/editBillView/editBillViewSelector';
|
|
293
293
|
import { clearInternationalWire, createPaymentInstrument, createPaymentInstrumentUpdateStatus, deletePaymentInstrument, fetchInternationalWireDynamicForm, initializeDynamicForm, initializeInternationalWireLocalData, updateInternationalWireLocalStoreData, } from './view/spendManagement/billPay/internationalWire/internationalWireReducer';
|
|
294
294
|
import { getInternationalWireView, } from './view/spendManagement/billPay/internationalWire/internationalWireSelector';
|
|
295
|
-
import { InternationalWireVerificationFormOrder, sortVerificationFormFields, } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationPayload';
|
|
296
295
|
import { fetchInternationalVerificationForm, submitInternationalVerificationForm, updateVerificationFormLocalData, } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationReducer';
|
|
297
296
|
import { getIntlWireVerificationView, } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSelector';
|
|
298
297
|
import { fetchBillAttachment, fetchMagicLinkBankNameByRouting, fetchMagicLinkBankNameBySwift, fetchMagicLinkTenant, saveBankAccount, saveMagicLinkAddressInLocalStore, updateMagicLinkBankAccountLocalStoreData, updateMagicLinkInternationalBankAccountLocalStoreData, } from './view/spendManagement/billPay/magicLinkView/magicLinkViewReducer';
|
|
@@ -507,7 +506,7 @@ export { toAttachment, } from './entity/transaction/payloadTypes/attachmentPaylo
|
|
|
507
506
|
export { defaultCustomerCurrency };
|
|
508
507
|
export { isCustomerTransaction };
|
|
509
508
|
export { toTransactionID, } from './entity/transaction/payloadTypes/transactionIDPayload';
|
|
510
|
-
export { toPlatformLineDetailType, };
|
|
509
|
+
export { toPlatformLineDetailType, toCategorizationStatusType, };
|
|
511
510
|
export { toTransactionType, toTransactionTypeStrict, toTransactionCategory, };
|
|
512
511
|
export { defaultVendorCurrency, updateVendors };
|
|
513
512
|
export { isVendorTransaction, isVendorTransactionWithCustomer, };
|
|
@@ -645,11 +644,7 @@ export { pushToastNotification, getLastNotificationTime, getNotifications, };
|
|
|
645
644
|
export { getReferralListView, getInviteFormView, toReferralListViewSortKeyType, StatusTypes, AmountStatusTypes, fetchReferrals, sendReferralInvite, clearReferrals, saveReferralFormDataInLocalStore, updateReferralListSortUiState, resendReferralInvite, fetchRewardsPlan, getRewardsPlanCard, updateReferViewed, };
|
|
646
645
|
export { ALL_WEEK_DAYS, SEMI_WEEKLY_REQUIRED_DAYS_COUNT, getMinAllowedEndDate, getRecurringEndDateFromCount, toDayOfWeek, toRecurringFrequency, };
|
|
647
646
|
export { fetchCockpitContext, fetchCompanyTaskManagerView, fetchTaskManagerMetrics, getCompanyTaskManagerView, createTaskFromTaskGroupTemplate, };
|
|
648
|
-
export {
|
|
649
|
-
export { InternationalWireVerificationBooleanWithSubfieldsFieldNameList, InternationalWireVerificationBooleanWithSubfieldsFieldNames, InternationalWireVerificationControllingPersonFieldName, InternationalWireVerificationFormFieldNames, InternationalWireVerificationStakeHolderFieldName, InternationalWireVerificationSubfieldNames, } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationFieldConstants';
|
|
650
|
-
export { IntlWireVerificationLocalDataSuffix, toIntlWireVerificationFormDetails, toIntlWireVerificationSubmitPayload, } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSubmitPayload';
|
|
651
|
-
export { getStakeHolderOwnerIndicesFromLocalData, } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationLocalDataHelpers';
|
|
652
|
-
export { toVerificationFormLocalDataFromOnboardingDetails, } from './view/spendManagement/billPay/internationalWireVerification/internationalWireOnboardingDetailsToLocalData';
|
|
647
|
+
export { fetchInternationalVerificationForm, submitInternationalVerificationForm, updateVerificationFormLocalData, getIntlWireVerificationView, };
|
|
653
648
|
export { fetchExpressPayInitialDetails, updateExpressPayFormLocalData, submitExpressPay, resetExpressPayLocalData, getExpressPayView, };
|
|
654
649
|
export { acceptTreasuryTerms, fetchTreasurySetupView, clearTreasurySetupView, fetchTreasuryFunds, updatePortfolioAllocation, fetchPortfolioAllocation, updateFundAllocationLocalData, updateTreasuryPromoIntroClosedByOutsideClick, updateTreasuryPromoRemindMeLaterClicked, updateTreasuryVideoViewed, getTreasurySetupViewDetails, getTreasuryFundsMaximumYield, };
|
|
655
650
|
// ── AI Accountant Entity ──
|
package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js
CHANGED
|
@@ -9,7 +9,7 @@ import { fetchMissingReceipts } from '../../reducers/missingReceiptsViewReducer'
|
|
|
9
9
|
import { fetchReconciliation } from '../../reducers/reconciliationViewReducer';
|
|
10
10
|
import { fetchTransactionCategorizationView } from '../../reducers/transactionsViewReducer';
|
|
11
11
|
export const fetchAllExpenseAutomationTabsEpic = (actions$, state$) => actions$.pipe(filter(fetchAllExpenseAutomationTabs.match), switchMap((action) => {
|
|
12
|
-
const { cacheOverride, refreshViewInBackground, isUncategorizedExpenseCategoryEnabled, } = action.payload;
|
|
12
|
+
const { cacheOverride, refreshViewInBackground, isUncategorizedExpenseCategoryEnabled, statuses, countOnlyStatuses, } = action.payload;
|
|
13
13
|
const state = state$.value;
|
|
14
14
|
const { monthEndCloseChecksState } = state;
|
|
15
15
|
const { monthEndCloseChecksByTenantId } = monthEndCloseChecksState;
|
|
@@ -30,7 +30,7 @@ export const fetchAllExpenseAutomationTabsEpic = (actions$, state$) => actions$.
|
|
|
30
30
|
}
|
|
31
31
|
if (cacheOverride === true) {
|
|
32
32
|
const actions = [];
|
|
33
|
-
actions.push(fetchTransactionCategorizationView(selectedTransactionCategorizationTab, { start: timePeriodStart, end: timePeriodEnd }, cacheOverride, false, undefined, undefined, refreshViewInBackground, false, isUncategorizedExpenseCategoryEnabled), fetchMissingReceipts({ start: timePeriodStart, end: timePeriodEnd }, {
|
|
33
|
+
actions.push(fetchTransactionCategorizationView(selectedTransactionCategorizationTab, { start: timePeriodStart, end: timePeriodEnd }, cacheOverride, false, undefined, undefined, refreshViewInBackground, false, isUncategorizedExpenseCategoryEnabled, statuses, countOnlyStatuses), fetchMissingReceipts({ start: timePeriodStart, end: timePeriodEnd }, {
|
|
34
34
|
amount: 75.0,
|
|
35
35
|
currencyCode: 'USD',
|
|
36
36
|
currencySymbol: '$',
|
|
@@ -83,7 +83,7 @@ export const fetchAllExpenseAutomationTabsEpic = (actions$, state$) => actions$.
|
|
|
83
83
|
(state.expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTransactionCategorizationTab].hasValidState() === false ||
|
|
84
84
|
state.expenseAutomationTransactionsViewState
|
|
85
85
|
.transactionCategorizationView[selectedTransactionCategorizationTab].transactionIdsBySelectedPeriod[monthYearPeriodId] == null)) {
|
|
86
|
-
fetchActions.push(fetchTransactionCategorizationView(selectedTransactionCategorizationTab, { start: timePeriodStart, end: timePeriodEnd }, cacheOverride, false, undefined, undefined, refreshViewInBackground, false, isUncategorizedExpenseCategoryEnabled));
|
|
86
|
+
fetchActions.push(fetchTransactionCategorizationView(selectedTransactionCategorizationTab, { start: timePeriodStart, end: timePeriodEnd }, cacheOverride, false, undefined, undefined, refreshViewInBackground, false, isUncategorizedExpenseCategoryEnabled, statuses, countOnlyStatuses));
|
|
87
87
|
}
|
|
88
88
|
return from(fetchActions);
|
|
89
89
|
}
|
package/lib/esm/view/expenseAutomationView/epics/common/refreshExpenseAutomationCurrentTabEpic.js
CHANGED
|
@@ -10,7 +10,7 @@ import { fetchMissingReceipts } from '../../reducers/missingReceiptsViewReducer'
|
|
|
10
10
|
import { fetchReconciliation } from '../../reducers/reconciliationViewReducer';
|
|
11
11
|
import { fetchTransactionCategorizationView } from '../../reducers/transactionsViewReducer';
|
|
12
12
|
export const refreshExpenseAutomationCurrentTabEpic = (actions$, state$) => actions$.pipe(filter(refreshExpenseAutomationCurrentTab.match), switchMap((action) => {
|
|
13
|
-
const { isUncategorizedExpenseCategoryEnabled } = action.payload;
|
|
13
|
+
const { countOnlyStatuses, isUncategorizedExpenseCategoryEnabled, statuses, } = action.payload;
|
|
14
14
|
const state = state$.value;
|
|
15
15
|
const currentTenant = getCurrentTenant(state);
|
|
16
16
|
const companyId = currentTenant.companyId;
|
|
@@ -61,9 +61,10 @@ export const refreshExpenseAutomationCurrentTabEpic = (actions$, state$) => acti
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
case 'transaction_categorization':
|
|
64
|
-
default:
|
|
64
|
+
default: {
|
|
65
65
|
return from([
|
|
66
|
-
fetchTransactionCategorizationView(selectedTransactionCategorizationTab, { start: timePeriodStart, end: timePeriodEnd }, true, false, undefined, undefined, true, undefined, isUncategorizedExpenseCategoryEnabled),
|
|
66
|
+
fetchTransactionCategorizationView(selectedTransactionCategorizationTab, { start: timePeriodStart, end: timePeriodEnd }, true, false, undefined, undefined, true, undefined, isUncategorizedExpenseCategoryEnabled, statuses, countOnlyStatuses),
|
|
67
67
|
]);
|
|
68
|
+
}
|
|
68
69
|
}
|
|
69
70
|
}));
|
|
@@ -5,14 +5,9 @@ import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePay
|
|
|
5
5
|
import { rollingCalendarDateRangeInclusive } from '../../helpers/rollingCalendarDateRangeInclusive';
|
|
6
6
|
import { supportedTransactionPayloadToManualSearchResult } from '../../payload/missingReceiptsPayload';
|
|
7
7
|
import { searchTransactionsForManualMatch, searchTransactionsForManualMatchFailure, searchTransactionsForManualMatchSuccess, } from '../../reducers/missingReceiptsViewReducer';
|
|
8
|
-
import { DEFAULT_COMPLETED_SUB_TAB } from '../../types/completedSubTab';
|
|
9
8
|
import { toTransactionsSortKey } from '../../types/transactionsViewState';
|
|
10
9
|
/**
|
|
11
|
-
|
|
12
|
-
* Backend contract TBD — align with `fetchTransactionCategorizationEpic` (`selectedTab === 'autoCategorized'`)
|
|
13
|
-
* when the expense-automation API documents the intended filter for this flow.
|
|
14
|
-
*/
|
|
15
|
-
export const MANUAL_TRANSACTION_SEARCH_AUTO_CATEGORIZED = false;
|
|
10
|
+
|
|
16
11
|
/** Inclusive rolling window for manual match search (ignores accounting period picker). */
|
|
17
12
|
const MANUAL_SEARCH_TRANSACTION_DATE_RANGE_DAYS = 90;
|
|
18
13
|
export const searchTransactionsForManualMatchEpic = (actions$, state$, zeniAPI) => {
|
|
@@ -41,20 +36,24 @@ export const searchTransactionsForManualMatchEpic = (actions$, state$, zeniAPI)
|
|
|
41
36
|
const queryParam = {
|
|
42
37
|
start_date: start,
|
|
43
38
|
end_date: end,
|
|
44
|
-
auto_categorized: MANUAL_TRANSACTION_SEARCH_AUTO_CATEGORIZED,
|
|
45
39
|
sort_by: toTransactionsSortKey(manualSearchSortKey),
|
|
46
40
|
sort_order: manualSearchSortOrder === 'ascending' ? 'asc' : 'desc',
|
|
47
41
|
page_token: pageToken ?? null,
|
|
48
42
|
page_size: manualSearch.pageSize,
|
|
49
43
|
search_text: query,
|
|
50
|
-
// Manual search ignores the Completed sub-tab axis — always span the
|
|
51
|
-
// default sentinel so the receipt-matching UX returns results
|
|
52
|
-
// regardless of where the transaction would otherwise be bucketed on
|
|
53
|
-
// the Completed tab.
|
|
54
|
-
sub_tab: DEFAULT_COMPLETED_SUB_TAB,
|
|
55
44
|
};
|
|
45
|
+
// BETA TEST — Shubham dev namespace for transaction-categorization
|
|
46
|
+
// `statuses` / `count_only_statuses` rollout. Revert before merge by
|
|
47
|
+
// restoring `${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}` in
|
|
48
|
+
// place of the hardcoded base. Mirrored in
|
|
49
|
+
// `fetchTransactionCategorizationEpic.ts` and
|
|
50
|
+
// `backgroundRefetchReviewTabEpic.ts` — grep `BETA TEST` to find
|
|
51
|
+
// every override site.
|
|
52
|
+
// #region agent log
|
|
53
|
+
fetch('http://127.0.0.1:7755/ingest/4e987812-899d-4b9b-8ed6-a799cd019b33', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Debug-Session-Id': 'f3bde0' }, body: JSON.stringify({ sessionId: 'f3bde0', hypothesisId: 'D', location: 'searchTransactionsForManualMatchEpic.ts:117', message: 'searchTransactionsForManualMatchEpic firing API', data: { query, pageToken, start: queryParam.start_date, end: queryParam.end_date, stack: (new Error().stack || '').split('\n').slice(1, 10).join(' | ') }, timestamp: Date.now() }) }).catch(() => { });
|
|
54
|
+
// #endregion
|
|
56
55
|
return zeniAPI
|
|
57
|
-
.getJSON(
|
|
56
|
+
.getJSON(`https://dev.api.zeni.ai/version/accounting/shubham/1.0/expense-automation/transactions?query=${encodeURIComponent(JSON.stringify(queryParam))}`)
|
|
58
57
|
.pipe(mergeMap((response) => {
|
|
59
58
|
if (isSuccessResponse(response) && response.data != null) {
|
|
60
59
|
const { transactions, next_page_token, total_count } = response.data;
|
|
@@ -10,8 +10,14 @@ import { toTransactionsSortKey } from '../../types/transactionsViewState';
|
|
|
10
10
|
const SELECTED_TAB = 'review';
|
|
11
11
|
const PAGE_SIZE = 25;
|
|
12
12
|
export const backgroundRefetchReviewTabEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(backgroundRefetchReviewTab.match), switchMap((action) => {
|
|
13
|
-
const { period, isUncategorizedExpenseCategoryEnabled } = action.payload;
|
|
13
|
+
const { period, isUncategorizedExpenseCategoryEnabled, reviewStatuses } = action.payload;
|
|
14
14
|
const state = state$.value;
|
|
15
|
+
// Background refetch must never widen the listing to "all statuses".
|
|
16
|
+
// Dispatchers that have access to the Statsig-resolved Review-tab
|
|
17
|
+
// status set (e.g. the EA-screen save chain) pass it through on the
|
|
18
|
+
// action; everyone else falls back to the hardcoded sentinel so the
|
|
19
|
+
// refetch matches what the user sees on the Review tab.
|
|
20
|
+
const effectiveReviewStatuses = reviewStatuses ?? ['pending_review'];
|
|
15
21
|
const currentTenant = getCurrentTenant(state);
|
|
16
22
|
const selectedPeriod = state.expenseAutomationViewState.selectedPeriodByTenantId[currentTenant.tenantId];
|
|
17
23
|
const reviewUiState = state.expenseAutomationTransactionsViewState
|
|
@@ -21,14 +27,24 @@ export const backgroundRefetchReviewTabEpic = (actions$, state$, zeniAPI) => act
|
|
|
21
27
|
const queryParam = {
|
|
22
28
|
start_date: toString(period.start),
|
|
23
29
|
end_date: toString(period.end),
|
|
24
|
-
auto_categorized: false,
|
|
25
30
|
sort_by: toTransactionsSortKey(reviewUiState.sortKey),
|
|
26
31
|
sort_order: reviewUiState.sortOrder === 'ascending' ? 'asc' : 'desc',
|
|
27
32
|
page_token: pageToken,
|
|
28
33
|
page_size: PAGE_SIZE,
|
|
29
34
|
search_text: reviewUiState.searchString,
|
|
35
|
+
statuses: effectiveReviewStatuses,
|
|
30
36
|
};
|
|
31
|
-
|
|
37
|
+
// BETA TEST — Shubham dev namespace for transaction-categorization
|
|
38
|
+
// `statuses` / `count_only_statuses` rollout. Revert before merge by
|
|
39
|
+
// restoring `${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}` in
|
|
40
|
+
// place of the hardcoded base. Mirrored in
|
|
41
|
+
// `fetchTransactionCategorizationEpic.ts` and
|
|
42
|
+
// `searchTransactionsForManualMatchEpic.ts` — grep `BETA TEST` to
|
|
43
|
+
// find every override site.
|
|
44
|
+
// #region agent log
|
|
45
|
+
fetch('http://127.0.0.1:7755/ingest/4e987812-899d-4b9b-8ed6-a799cd019b33', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Debug-Session-Id': 'f3bde0' }, body: JSON.stringify({ sessionId: 'f3bde0', hypothesisId: 'E', location: 'backgroundRefetchReviewTabEpic.ts:112', message: 'backgroundRefetchReviewTabEpic firing API', data: { pageToken, effectiveReviewStatuses, start: queryParam.start_date, end: queryParam.end_date, stack: (new Error().stack || '').split('\n').slice(1, 10).join(' | ') }, timestamp: Date.now() }) }).catch(() => { });
|
|
46
|
+
// #endregion
|
|
47
|
+
return zeniAPI.getJSON(`https://dev.api.zeni.ai/version/accounting/shubham/1.0/expense-automation/transactions?query=${encodeURIComponent(JSON.stringify(queryParam))}`);
|
|
32
48
|
};
|
|
33
49
|
return fetchPage(null).pipe(expand((response) => {
|
|
34
50
|
if (!isSuccessResponse(response) || response.data == null) {
|
|
@@ -6,11 +6,10 @@ import { updateTransactions } from '../../../../entity/transaction/transactionRe
|
|
|
6
6
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
7
7
|
import { getLineItemsByTransactionsIdsFromResponse } from '../../helpers/transactionCategorizationLocalDataHelper';
|
|
8
8
|
import { fetchTransactionCategorization, fetchTransactionCategorizationFailure, fetchTransactionCategorizationSuccess, initializeTransactionCategorizationViewLocalData, resetOtherTabsFetchState, updateParentTotalCountForTab, updateTotalCountForTransactionCategorization, updateTransactionCategorizationUIState, } from '../../reducers/transactionsViewReducer';
|
|
9
|
-
import { DEFAULT_COMPLETED_SUB_TAB } from '../../types/completedSubTab';
|
|
10
9
|
import { TRANSACTIONS_TABS, toTransactionsSortKey, } from '../../types/transactionsViewState';
|
|
11
10
|
export const fetchTransactionCategorizationEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchTransactionCategorization.match), switchMap((action) => {
|
|
12
11
|
const { expenseAutomationViewState: { selectedPeriodByTenantId }, expenseAutomationTransactionsViewState, } = state$.value;
|
|
13
|
-
const { period, keepExistingListItems, selectedTab, refreshViewInBackground, } = action.payload;
|
|
12
|
+
const { period, keepExistingListItems, selectedTab, refreshViewInBackground, statuses, countOnlyStatuses, } = action.payload;
|
|
14
13
|
const uiState = expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTab].uiState;
|
|
15
14
|
const { pageToken, sortOrder, sortKey } = uiState;
|
|
16
15
|
const currentTenant = getCurrentTenant(state$.value);
|
|
@@ -18,18 +17,26 @@ export const fetchTransactionCategorizationEpic = (actions$, state$, zeniAPI) =>
|
|
|
18
17
|
const queryParam = {
|
|
19
18
|
start_date: toString(period.start),
|
|
20
19
|
end_date: toString(period.end),
|
|
21
|
-
auto_categorized: selectedTab === 'autoCategorized',
|
|
22
20
|
sort_by: toTransactionsSortKey(sortKey),
|
|
23
21
|
sort_order: sortOrder === 'ascending' ? 'asc' : 'desc',
|
|
24
22
|
page_token: pageToken,
|
|
25
23
|
page_size: 25,
|
|
26
24
|
search_text: uiState.searchString,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
: DEFAULT_COMPLETED_SUB_TAB,
|
|
25
|
+
statuses,
|
|
26
|
+
count_only_statuses: countOnlyStatuses,
|
|
30
27
|
};
|
|
28
|
+
// #region agent log
|
|
29
|
+
fetch('http://127.0.0.1:7755/ingest/4e987812-899d-4b9b-8ed6-a799cd019b33', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Debug-Session-Id': 'f3bde0' }, body: JSON.stringify({ sessionId: 'f3bde0', hypothesisId: 'A/B/C', location: 'fetchTransactionCategorizationEpic.ts:84', message: 'fetchTransactionCategorizationEpic firing API', data: { selectedTab, incomingStatuses: statuses, incomingCountOnlyStatuses: countOnlyStatuses, refreshViewInBackground, keepExistingListItems, searchString: uiState.searchString, pageToken, start: toString(period.start), end: toString(period.end), statusesIsUndefined: statuses === undefined, stack: (new Error().stack || '').split('\n').slice(1, 10).join(' | ') }, timestamp: Date.now() }) }).catch(() => { });
|
|
30
|
+
// #endregion
|
|
31
|
+
// BETA TEST — Shubham dev namespace for transaction-categorization
|
|
32
|
+
// `statuses` / `count_only_statuses` rollout. Revert before merge by
|
|
33
|
+
// restoring `${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}` in
|
|
34
|
+
// place of the hardcoded base. Mirrored in
|
|
35
|
+
// `backgroundRefetchReviewTabEpic.ts` and
|
|
36
|
+
// `searchTransactionsForManualMatchEpic.ts` — grep `BETA TEST` to
|
|
37
|
+
// find every override site.
|
|
31
38
|
return zeniAPI
|
|
32
|
-
.getJSON(
|
|
39
|
+
.getJSON(`https://dev.api.zeni.ai/version/accounting/shubham/1.0/expense-automation/transactions?query=${encodeURIComponent(JSON.stringify(queryParam))}`)
|
|
33
40
|
.pipe(mergeMap((response) => {
|
|
34
41
|
if (isSuccessResponse(response) && response.data != null) {
|
|
35
42
|
const updateActions = [];
|
|
@@ -52,8 +59,11 @@ export const fetchTransactionCategorizationEpic = (actions$, state$, zeniAPI) =>
|
|
|
52
59
|
updateActions.push(updateParentTotalCountForTab({
|
|
53
60
|
selectedPeriod,
|
|
54
61
|
selectedTab,
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
// Optional — present only when the request supplied
|
|
63
|
+
// `count_only_statuses`. The reducer no-ops on undefined so
|
|
64
|
+
// any cached parent badge stays intact across scoped
|
|
65
|
+
// fetches (sort changes, pagination, etc.).
|
|
66
|
+
parentTotalCount: response.data.count_only_total,
|
|
57
67
|
}));
|
|
58
68
|
updateActions.push(resetOtherTabsFetchState({
|
|
59
69
|
refreshViewInBackground,
|
|
@@ -8,7 +8,7 @@ import { fetchOwnerList } from '../../../ownerList/ownerListReducer';
|
|
|
8
8
|
import { fetchProjectList } from '../../../projectList/projectListReducer';
|
|
9
9
|
import { fetchTransactionCategorization, fetchTransactionCategorizationView, } from '../../reducers/transactionsViewReducer';
|
|
10
10
|
export const fetchTransactionCategorizationViewEpic = (actions$, state$) => actions$.pipe(filter(fetchTransactionCategorizationView.match), mergeMap((action) => {
|
|
11
|
-
const { selectedTab, cacheOverride, keepExistingListItems, pageToken, period, refreshViewInBackground, searchString, resetListItems, isUncategorizedExpenseCategoryEnabled, } = action.payload;
|
|
11
|
+
const { selectedTab, cacheOverride, keepExistingListItems, pageToken, period, refreshViewInBackground, searchString, resetListItems, isUncategorizedExpenseCategoryEnabled, statuses, countOnlyStatuses, } = action.payload;
|
|
12
12
|
const updateActions = [];
|
|
13
13
|
const { expenseAutomationTransactionsViewState } = state$.value;
|
|
14
14
|
const { fetchState, transactionIdsBySelectedPeriod } = expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTab];
|
|
@@ -42,7 +42,7 @@ export const fetchTransactionCategorizationViewEpic = (actions$, state$) => acti
|
|
|
42
42
|
if (cacheOverride === true ||
|
|
43
43
|
fetchState === 'Not-Started' ||
|
|
44
44
|
transactionIds.length === 0) {
|
|
45
|
-
updateActions.push(fetchTransactionCategorization(selectedTab, period, cacheOverride, keepExistingListItems, searchString, pageToken, refreshViewInBackground, resetListItems, isUncategorizedExpenseCategoryEnabled));
|
|
45
|
+
updateActions.push(fetchTransactionCategorization(selectedTab, period, cacheOverride, keepExistingListItems, searchString, pageToken, refreshViewInBackground, resetListItems, isUncategorizedExpenseCategoryEnabled, statuses, countOnlyStatuses));
|
|
46
46
|
}
|
|
47
47
|
return from(updateActions);
|
|
48
48
|
}));
|
|
@@ -10,7 +10,7 @@ import { getSnackbarMessageForTransactionReview } from '../../helpers/transactio
|
|
|
10
10
|
import { fetchTransactionCategorizationView, markTransactionAsNotMiscategorized, updateStatusForTransactionNotMiscategorizedUpdateForCategorization, updateTotalCountForTransactionCategorization, } from '../../reducers/transactionsViewReducer';
|
|
11
11
|
export const markTransactionAsNotMiscategorizedEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(markTransactionAsNotMiscategorized.match), mergeMap((action) => {
|
|
12
12
|
const { expenseAutomationViewState, expenseAutomationTransactionsViewState, } = state$.value;
|
|
13
|
-
const { transactionsInReview, selectedTab, isUncategorizedExpenseCategoryEnabled, } = action.payload;
|
|
13
|
+
const { transactionsInReview, selectedTab, isUncategorizedExpenseCategoryEnabled, reviewStatuses: reviewStatusesFromAction, } = action.payload;
|
|
14
14
|
const transactionsSuccess = transactionsInReview.transactions_update_success;
|
|
15
15
|
const transactionsFailed = transactionsInReview.transactions_update_failed;
|
|
16
16
|
const currentTenant = getCurrentTenant(state$.value);
|
|
@@ -105,9 +105,20 @@ export const markTransactionAsNotMiscategorizedEpic = (actions$, state$, zeniAPI
|
|
|
105
105
|
const timePeriodStart = toAbsoluteDay(period.start);
|
|
106
106
|
const timePeriodEnd = toAbsoluteDay(period.end);
|
|
107
107
|
if (timePeriodStart != null && timePeriodEnd != null) {
|
|
108
|
+
// Statsig-resolved Review-tab statuses are threaded
|
|
109
|
+
// through the EA save chain by `ExpenseAutomationScreen`
|
|
110
|
+
// (resolves via `useDynamicConfig` +
|
|
111
|
+
// `resolveTransactionCategorizationStatuses`). The
|
|
112
|
+
// hardcoded `['pending_review']` last-resort prevents
|
|
113
|
+
// accidental "all statuses" widening if the chain ever
|
|
114
|
+
// delivers `undefined` (defensive — every live caller
|
|
115
|
+
// should be passing this through).
|
|
116
|
+
const reviewStatuses = reviewStatusesFromAction ?? [
|
|
117
|
+
'pending_review',
|
|
118
|
+
];
|
|
108
119
|
actions.push(fetchTransactionCategorizationView('review', { start: timePeriodStart, end: timePeriodEnd }, true, // cacheOverride = true to force refresh
|
|
109
120
|
false, undefined, undefined, true, // refreshViewInBackground
|
|
110
|
-
false, isUncategorizedExpenseCategoryEnabled));
|
|
121
|
+
false, isUncategorizedExpenseCategoryEnabled, reviewStatuses));
|
|
111
122
|
}
|
|
112
123
|
}
|
|
113
124
|
actions.push(updateTotalCountForTransactionCategorization({
|
|
@@ -6,7 +6,7 @@ import { getUncategorizedAccounts } from '../../../accountList/accountListSelect
|
|
|
6
6
|
import { toTransactionUpdatesFromTransactionCategorizationLocalData } from '../../helpers/saveTransactionHelper';
|
|
7
7
|
import { saveTransactionCategorization, updateTransactionCategorization, } from '../../reducers/transactionsViewReducer';
|
|
8
8
|
export const saveTransactionCategorizationEpic = (actions$, state$) => actions$.pipe(filter(saveTransactionCategorization.match), mergeMap((action) => {
|
|
9
|
-
const { transactionIds, cotTrackingByTransactionId, selectedTab, isUncategorizedExpenseCategoryEnabled, } = action.payload;
|
|
9
|
+
const { transactionIds, cotTrackingByTransactionId, selectedTab, isUncategorizedExpenseCategoryEnabled, reviewStatuses, } = action.payload;
|
|
10
10
|
const fetchActions = [];
|
|
11
11
|
const { transactionState, expenseAutomationTransactionsViewState } = state$.value;
|
|
12
12
|
const transactionSaveUpdates = [];
|
|
@@ -19,6 +19,10 @@ export const saveTransactionCategorizationEpic = (actions$, state$) => actions$.
|
|
|
19
19
|
transactionSaveUpdates.push(toTransactionUpdatesFromTransactionCategorizationLocalData(localData, transaction, uncategorizedIncomeExpense));
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
|
-
|
|
22
|
+
// Forward `reviewStatuses` so the downstream
|
|
23
|
+
// `updateTransactionCategorizationEpic` -> `markTransactionAsNotMiscategorized`
|
|
24
|
+
// chain receives the Statsig-resolved Review-tab statuses end-to-end
|
|
25
|
+
// without reading Statsig from epic-land.
|
|
26
|
+
fetchActions.push(updateTransactionCategorization(selectedTab, transactionIds, transactionSaveUpdates, cotTrackingByTransactionId, isUncategorizedExpenseCategoryEnabled, reviewStatuses));
|
|
23
27
|
return from(fetchActions);
|
|
24
28
|
}));
|
|
@@ -4,7 +4,7 @@ import { convertToPeriod, toAbsoluteDay, } from '../../../../commonStateTypes/ti
|
|
|
4
4
|
import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
|
|
5
5
|
import { backgroundRefetchReviewTab, syncTransactionCategorizationFromDetailSave, } from '../../reducers/transactionsViewReducer';
|
|
6
6
|
export const triggerReviewTabRefetchEpic = (actions$, state$) => actions$.pipe(filter(syncTransactionCategorizationFromDetailSave.match), mergeMap((action) => {
|
|
7
|
-
const { pendingReviewLineIds, transactionId, isUncategorizedExpenseCategoryEnabled, } = action.payload;
|
|
7
|
+
const { pendingReviewLineIds, transactionId, isUncategorizedExpenseCategoryEnabled, reviewStatuses, } = action.payload;
|
|
8
8
|
if (pendingReviewLineIds.length === 0) {
|
|
9
9
|
return EMPTY;
|
|
10
10
|
}
|
|
@@ -23,5 +23,5 @@ export const triggerReviewTabRefetchEpic = (actions$, state$) => actions$.pipe(f
|
|
|
23
23
|
if (timePeriodStart == null || timePeriodEnd == null) {
|
|
24
24
|
return EMPTY;
|
|
25
25
|
}
|
|
26
|
-
return of(backgroundRefetchReviewTab({ start: timePeriodStart, end: timePeriodEnd }, isUncategorizedExpenseCategoryEnabled));
|
|
26
|
+
return of(backgroundRefetchReviewTab({ start: timePeriodStart, end: timePeriodEnd }, isUncategorizedExpenseCategoryEnabled, reviewStatuses));
|
|
27
27
|
}));
|
|
@@ -15,7 +15,7 @@ import { getVendorByVendorId } from '../../../../entity/vendor/vendorSelector';
|
|
|
15
15
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
16
16
|
import { markTransactionAsNotMiscategorized, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, } from '../../reducers/transactionsViewReducer';
|
|
17
17
|
export const updateTransactionCategorizationEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(updateTransactionCategorization.match), mergeMap((action) => {
|
|
18
|
-
const { selectedTab, transactionIds, transactionSaveUpdates, cotTrackingByTransactionId, isUncategorizedExpenseCategoryEnabled, } = action.payload;
|
|
18
|
+
const { selectedTab, transactionIds, transactionSaveUpdates, cotTrackingByTransactionId, isUncategorizedExpenseCategoryEnabled, reviewStatuses, } = action.payload;
|
|
19
19
|
const { transactionState, vendorState, expenseAutomationTransactionsViewState, } = state$.value;
|
|
20
20
|
const payloadArray = preparePayload(selectedTab, transactionState, vendorState, expenseAutomationTransactionsViewState, transactionIds, transactionSaveUpdates, cotTrackingByTransactionId).filter((payload) => payload != null);
|
|
21
21
|
return zeniAPI
|
|
@@ -24,7 +24,11 @@ export const updateTransactionCategorizationEpic = (actions$, state$, zeniAPI) =
|
|
|
24
24
|
if (isSuccessResponse(response) && response.data != null) {
|
|
25
25
|
const transactionsInReview = response.data;
|
|
26
26
|
const actions = [];
|
|
27
|
-
|
|
27
|
+
// Forward `reviewStatuses` so the downstream
|
|
28
|
+
// `markTransactionAsNotMiscategorizedEpic` can request the
|
|
29
|
+
// Statsig-resolved Review-tab statuses for its conditional
|
|
30
|
+
// background refetch via `fetchTransactionCategorizationView`.
|
|
31
|
+
actions.push(markTransactionAsNotMiscategorized(selectedTab, transactionsInReview, isUncategorizedExpenseCategoryEnabled, reviewStatuses), updateTransactionCategorizationSaveStatus(selectedTab, 'Completed', createZeniAPIStatus('Completed', 'Transaction categorization updated successfully')));
|
|
28
32
|
return from(actions);
|
|
29
33
|
}
|
|
30
34
|
else {
|
|
@@ -18,20 +18,37 @@ const expenseAutomationView = createSlice({
|
|
|
18
18
|
reducer() {
|
|
19
19
|
//do nothing
|
|
20
20
|
},
|
|
21
|
-
|
|
21
|
+
/**
|
|
22
|
+
* `statuses` / `countOnlyStatuses` carry the Statsig-resolved values
|
|
23
|
+
* for the currently selected transaction-categorization tab. The
|
|
24
|
+
* host (`ExpenseAutomationScreen`) resolves them via
|
|
25
|
+
* `useDynamicConfig` + `resolveTransactionCategorizationStatuses`
|
|
26
|
+
* and passes them in so the downstream bootstrap fetch hits the
|
|
27
|
+
* listing API with the correct status filter. Optional only as a
|
|
28
|
+
* defensive type concession for non-categorization callers (the
|
|
29
|
+
* action is also used to bootstrap the missing-receipts / reconciliation
|
|
30
|
+
* / month-end views, which don't consume these args).
|
|
31
|
+
*/
|
|
32
|
+
prepare(cacheOverride = false, refreshViewInBackground = false, isUncategorizedExpenseCategoryEnabled = false, statuses, countOnlyStatuses) {
|
|
22
33
|
return {
|
|
23
34
|
payload: {
|
|
24
35
|
cacheOverride,
|
|
25
36
|
refreshViewInBackground,
|
|
26
37
|
isUncategorizedExpenseCategoryEnabled,
|
|
38
|
+
statuses,
|
|
39
|
+
countOnlyStatuses,
|
|
27
40
|
},
|
|
28
41
|
};
|
|
29
42
|
},
|
|
30
43
|
},
|
|
31
44
|
refreshExpenseAutomationCurrentTab: {
|
|
32
|
-
prepare(isUncategorizedExpenseCategoryEnabled) {
|
|
45
|
+
prepare(isUncategorizedExpenseCategoryEnabled, statuses, countOnlyStatuses) {
|
|
33
46
|
return {
|
|
34
|
-
payload: {
|
|
47
|
+
payload: {
|
|
48
|
+
isUncategorizedExpenseCategoryEnabled,
|
|
49
|
+
statuses,
|
|
50
|
+
countOnlyStatuses,
|
|
51
|
+
},
|
|
35
52
|
};
|
|
36
53
|
},
|
|
37
54
|
reducer() {
|
|
@@ -121,7 +121,7 @@ const expenseAutomationTransactionsView = createSlice({
|
|
|
121
121
|
reducers: {
|
|
122
122
|
fetchTransactionCategorizationView: {
|
|
123
123
|
prepare(selectedTab, period, cacheOverride = false, keepExistingListItems = false, searchString, // when this is defined the output should go to search result IDs
|
|
124
|
-
pageToken, refreshViewInBackground = false, resetListItems = false, isUncategorizedExpenseCategoryEnabled) {
|
|
124
|
+
pageToken, refreshViewInBackground = false, resetListItems = false, isUncategorizedExpenseCategoryEnabled, statuses, countOnlyStatuses) {
|
|
125
125
|
return {
|
|
126
126
|
payload: {
|
|
127
127
|
selectedTab,
|
|
@@ -133,6 +133,8 @@ const expenseAutomationTransactionsView = createSlice({
|
|
|
133
133
|
refreshViewInBackground,
|
|
134
134
|
resetListItems,
|
|
135
135
|
isUncategorizedExpenseCategoryEnabled,
|
|
136
|
+
statuses,
|
|
137
|
+
countOnlyStatuses,
|
|
136
138
|
},
|
|
137
139
|
};
|
|
138
140
|
},
|
|
@@ -181,7 +183,7 @@ const expenseAutomationTransactionsView = createSlice({
|
|
|
181
183
|
}
|
|
182
184
|
},
|
|
183
185
|
prepare(selectedTab, period, cacheOverride = false, keepExistingListItems = false, searchString, // when this is defined the output should go to search result IDs
|
|
184
|
-
pageToken, refreshViewInBackground = false, resetListItems, isUncategorizedExpenseCategoryEnabled) {
|
|
186
|
+
pageToken, refreshViewInBackground = false, resetListItems, isUncategorizedExpenseCategoryEnabled, statuses, countOnlyStatuses) {
|
|
185
187
|
return {
|
|
186
188
|
payload: {
|
|
187
189
|
selectedTab,
|
|
@@ -193,6 +195,8 @@ const expenseAutomationTransactionsView = createSlice({
|
|
|
193
195
|
refreshViewInBackground,
|
|
194
196
|
resetListItems,
|
|
195
197
|
isUncategorizedExpenseCategoryEnabled,
|
|
198
|
+
statuses,
|
|
199
|
+
countOnlyStatuses,
|
|
196
200
|
},
|
|
197
201
|
};
|
|
198
202
|
},
|
|
@@ -311,13 +315,25 @@ const expenseAutomationTransactionsView = createSlice({
|
|
|
311
315
|
draft.transactionCategorizationView[selectedTab].filters = filters;
|
|
312
316
|
},
|
|
313
317
|
saveTransactionCategorization: {
|
|
314
|
-
|
|
318
|
+
/**
|
|
319
|
+
* `reviewStatuses` carries the Statsig-resolved Review-tab statuses
|
|
320
|
+
* forwarded by `ExpenseAutomationScreen`.
|
|
321
|
+
* `saveTransactionCategorizationEpic` threads them downstream into
|
|
322
|
+
* `updateTransactionCategorization` -> `markTransactionAsNotMiscategorized`
|
|
323
|
+
* so the conditional background Review-tab refetch in
|
|
324
|
+
* `markTransactionAsNotMiscategorizedEpic` can request the correct
|
|
325
|
+
* status set without reading Statsig from epic-land. Optional during
|
|
326
|
+
* the deprecation window so un-migrated callers continue to work via
|
|
327
|
+
* slice fallback.
|
|
328
|
+
*/
|
|
329
|
+
prepare(selectedTab, transactionIds, cotTrackingByTransactionId, isUncategorizedExpenseCategoryEnabled, reviewStatuses) {
|
|
315
330
|
return {
|
|
316
331
|
payload: {
|
|
317
332
|
selectedTab,
|
|
318
333
|
transactionIds,
|
|
319
334
|
cotTrackingByTransactionId,
|
|
320
335
|
isUncategorizedExpenseCategoryEnabled,
|
|
336
|
+
reviewStatuses,
|
|
321
337
|
},
|
|
322
338
|
};
|
|
323
339
|
},
|
|
@@ -391,9 +407,16 @@ const expenseAutomationTransactionsView = createSlice({
|
|
|
391
407
|
fetchState: 'In-Progress',
|
|
392
408
|
};
|
|
393
409
|
},
|
|
394
|
-
|
|
410
|
+
/**
|
|
411
|
+
* `reviewStatuses` carries the Statsig-resolved Review-tab statuses
|
|
412
|
+
* forwarded from `saveTransactionCategorization`.
|
|
413
|
+
* `updateTransactionCategorizationEpic` threads them downstream into
|
|
414
|
+
* `markTransactionAsNotMiscategorized`.
|
|
415
|
+
*/
|
|
416
|
+
prepare(selectedTab, transactionIds, transactionSaveUpdates, cotTrackingByTransactionId, isUncategorizedExpenseCategoryEnabled, reviewStatuses) {
|
|
395
417
|
return {
|
|
396
418
|
payload: {
|
|
419
|
+
reviewStatuses,
|
|
397
420
|
selectedTab,
|
|
398
421
|
transactionIds,
|
|
399
422
|
transactionSaveUpdates,
|
|
@@ -858,12 +881,20 @@ const expenseAutomationTransactionsView = createSlice({
|
|
|
858
881
|
error: undefined,
|
|
859
882
|
};
|
|
860
883
|
},
|
|
861
|
-
|
|
884
|
+
/**
|
|
885
|
+
* `reviewStatuses` carries the Statsig-resolved Review-tab statuses
|
|
886
|
+
* forwarded from the EA-screen save chain.
|
|
887
|
+
* `markTransactionAsNotMiscategorizedEpic` reads this payload value
|
|
888
|
+
* when dispatching the conditional background Review-tab refetch via
|
|
889
|
+
* `fetchTransactionCategorizationView`.
|
|
890
|
+
*/
|
|
891
|
+
prepare(selectedTab, transactionsInReview, isUncategorizedExpenseCategoryEnabled, reviewStatuses) {
|
|
862
892
|
return {
|
|
863
893
|
payload: {
|
|
864
894
|
selectedTab,
|
|
865
895
|
transactionsInReview,
|
|
866
896
|
isUncategorizedExpenseCategoryEnabled,
|
|
897
|
+
reviewStatuses,
|
|
867
898
|
},
|
|
868
899
|
};
|
|
869
900
|
},
|
|
@@ -921,10 +952,17 @@ const expenseAutomationTransactionsView = createSlice({
|
|
|
921
952
|
},
|
|
922
953
|
updateTotalCountForTransactionCategorization(draft, action) {
|
|
923
954
|
const { selectedTab, selectedPeriod, totalCount } = action.payload;
|
|
924
|
-
|
|
955
|
+
const periodId = toMonthYearPeriodId(selectedPeriod);
|
|
956
|
+
draft.transactionCategorizationView[selectedTab].uiState.totalCount[periodId] = totalCount;
|
|
957
|
+
if (selectedTab === 'review') {
|
|
958
|
+
draft.parentTotalCountByTab.review[periodId] = totalCount;
|
|
959
|
+
}
|
|
925
960
|
},
|
|
926
961
|
updateParentTotalCountForTab(draft, action) {
|
|
927
962
|
const { selectedTab, selectedPeriod, parentTotalCount } = action.payload;
|
|
963
|
+
if (parentTotalCount == null) {
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
928
966
|
draft.parentTotalCountByTab[selectedTab][toMonthYearPeriodId(selectedPeriod)] = parentTotalCount;
|
|
929
967
|
},
|
|
930
968
|
updateSelectedCheckboxTransactionIds(draft, action) {
|
|
@@ -973,7 +1011,7 @@ const expenseAutomationTransactionsView = createSlice({
|
|
|
973
1011
|
},
|
|
974
1012
|
},
|
|
975
1013
|
syncTransactionCategorizationFromDetailSave: {
|
|
976
|
-
prepare(transactionId, updatedTransaction, pendingReviewLineIds, uncategorizedIncomeExpense, isUncategorizedExpenseCategoryEnabled) {
|
|
1014
|
+
prepare(transactionId, updatedTransaction, pendingReviewLineIds, uncategorizedIncomeExpense, isUncategorizedExpenseCategoryEnabled, reviewStatuses) {
|
|
977
1015
|
return {
|
|
978
1016
|
payload: {
|
|
979
1017
|
transactionId,
|
|
@@ -981,6 +1019,7 @@ const expenseAutomationTransactionsView = createSlice({
|
|
|
981
1019
|
pendingReviewLineIds,
|
|
982
1020
|
uncategorizedIncomeExpense,
|
|
983
1021
|
isUncategorizedExpenseCategoryEnabled,
|
|
1022
|
+
reviewStatuses,
|
|
984
1023
|
},
|
|
985
1024
|
};
|
|
986
1025
|
},
|
|
@@ -1026,11 +1065,12 @@ const expenseAutomationTransactionsView = createSlice({
|
|
|
1026
1065
|
},
|
|
1027
1066
|
},
|
|
1028
1067
|
backgroundRefetchReviewTab: {
|
|
1029
|
-
prepare(period, isUncategorizedExpenseCategoryEnabled) {
|
|
1068
|
+
prepare(period, isUncategorizedExpenseCategoryEnabled, reviewStatuses) {
|
|
1030
1069
|
return {
|
|
1031
1070
|
payload: {
|
|
1032
1071
|
period,
|
|
1033
1072
|
isUncategorizedExpenseCategoryEnabled,
|
|
1073
|
+
reviewStatuses,
|
|
1034
1074
|
},
|
|
1035
1075
|
};
|
|
1036
1076
|
},
|
|
@@ -186,10 +186,11 @@ export function getExpenseAutomationTransactionView(state) {
|
|
|
186
186
|
review: monthYearPeriodId != null ? totalCountByReview[monthYearPeriodId] : 0,
|
|
187
187
|
autoCategorized: monthYearPeriodId != null ? totalCountByAutoCat[monthYearPeriodId] : 0,
|
|
188
188
|
};
|
|
189
|
-
// Parent-tab badge counts. Sourced from
|
|
190
|
-
//
|
|
191
|
-
//
|
|
192
|
-
//
|
|
189
|
+
// Parent-tab badge counts. Sourced from the listing response's optional
|
|
190
|
+
// `count_only_total` (only emitted when the request supplied
|
|
191
|
+
// `count_only_statuses`) and used exclusively by the navbar / tab strip
|
|
192
|
+
// badges. Independent of which Completed sub-tab is active so the badge
|
|
193
|
+
// stays stable across sub-tab switches.
|
|
193
194
|
const parentTotalCountByTab = expenseAutomationTransactionsViewState.parentTotalCountByTab;
|
|
194
195
|
const parentTabTotalCountByTab = {
|
|
195
196
|
review: monthYearPeriodId != null
|