@zeniai/client-epic-state 5.2.41 → 5.2.42-betaAK0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/entity/actualMatching/actualMatchingPayload.d.ts +31 -0
- package/lib/entity/actualMatching/actualMatchingPayload.js +52 -0
- package/lib/entity/actualMatching/actualMatchingReducer.d.ts +9 -0
- package/lib/entity/actualMatching/actualMatchingReducer.js +33 -0
- package/lib/entity/actualMatching/actualMatchingSelector.d.ts +3 -0
- package/lib/entity/actualMatching/actualMatchingSelector.js +6 -0
- package/lib/entity/actualMatching/actualMatchingState.d.ts +23 -0
- package/lib/entity/actualMatching/actualMatchingState.js +2 -0
- package/lib/entity/actualMatching/actualMatchingTypes.d.ts +1 -0
- package/lib/entity/actualMatching/actualMatchingTypes.js +2 -0
- package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +31 -0
- package/lib/entity/jeSchedules/jeSchedulesPayload.js +53 -0
- package/lib/entity/jeSchedules/jeSchedulesState.d.ts +33 -0
- package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
- package/lib/entity/snackbar/snackbarTypes.js +2 -0
- package/lib/epic.d.ts +8 -1
- package/lib/epic.js +14 -0
- package/lib/esm/entity/actualMatching/actualMatchingPayload.js +48 -0
- package/lib/esm/entity/actualMatching/actualMatchingReducer.js +30 -0
- package/lib/esm/entity/actualMatching/actualMatchingSelector.js +3 -0
- package/lib/esm/entity/actualMatching/actualMatchingState.js +1 -0
- package/lib/esm/entity/actualMatching/actualMatchingTypes.js +1 -0
- package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +53 -0
- package/lib/esm/entity/snackbar/snackbarTypes.js +2 -0
- package/lib/esm/epic.js +14 -0
- package/lib/esm/index.js +7 -3
- package/lib/esm/reducer.js +6 -0
- package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +25 -12
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingEpic.js +46 -0
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.js +36 -0
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingPageEpic.js +7 -0
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.js +108 -0
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/refreshActualMatchingList.js +16 -0
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchAccrualsEpic.js +60 -0
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchTransactionsEpic.js +74 -0
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/undoReversalAccrualsEpic.js +78 -0
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +13 -3
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/prefetchOtherJeSchedulesTabEpic.js +40 -15
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +19 -8
- package/lib/esm/view/expenseAutomationView/expenseAutomationViewReducer.js +2 -1
- package/lib/esm/view/expenseAutomationView/expenseAutomationViewSelector.js +24 -6
- package/lib/esm/view/expenseAutomationView/expenseAutomationViewState.js +4 -2
- package/lib/esm/view/expenseAutomationView/payload/actualMatchingPayload.js +68 -0
- package/lib/esm/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +462 -0
- package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +2 -1
- package/lib/esm/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.js +1 -0
- package/lib/esm/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +426 -0
- package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +4 -0
- package/lib/esm/view/expenseAutomationView/types/actualMatchingViewState.js +38 -0
- package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +8 -1
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +39 -30
- package/lib/index.d.ts +14 -5
- package/lib/index.js +82 -48
- package/lib/reducer.d.ts +2 -0
- package/lib/reducer.js +6 -0
- package/lib/rootStateTypes.d.ts +4 -0
- package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +25 -12
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingEpic.d.ts +9 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingEpic.js +50 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.d.ts +12 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.js +40 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingPageEpic.d.ts +5 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingPageEpic.js +11 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.d.ts +9 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.js +112 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/refreshActualMatchingList.d.ts +3 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/refreshActualMatchingList.js +19 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchAccrualsEpic.d.ts +9 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchAccrualsEpic.js +64 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchTransactionsEpic.d.ts +8 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchTransactionsEpic.js +78 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/undoReversalAccrualsEpic.d.ts +9 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/undoReversalAccrualsEpic.js +82 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.d.ts +2 -1
- package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +13 -3
- package/lib/view/expenseAutomationView/epics/jeSchedule/prefetchOtherJeSchedulesTabEpic.d.ts +5 -1
- package/lib/view/expenseAutomationView/epics/jeSchedule/prefetchOtherJeSchedulesTabEpic.js +39 -14
- package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +18 -7
- package/lib/view/expenseAutomationView/expenseAutomationViewReducer.d.ts +2 -1
- package/lib/view/expenseAutomationView/expenseAutomationViewReducer.js +2 -1
- package/lib/view/expenseAutomationView/expenseAutomationViewSelector.js +24 -6
- package/lib/view/expenseAutomationView/expenseAutomationViewState.d.ts +2 -1
- package/lib/view/expenseAutomationView/expenseAutomationViewState.js +6 -3
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
- package/lib/view/expenseAutomationView/payload/actualMatchingPayload.d.ts +85 -0
- package/lib/view/expenseAutomationView/payload/actualMatchingPayload.js +74 -0
- package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.d.ts +79 -0
- package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +466 -0
- package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +6 -5
- package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +2 -1
- package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.d.ts +87 -0
- package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.js +2 -0
- package/lib/view/expenseAutomationView/selectorTypes/expenseAutomationViewSelectorTypes.d.ts +11 -0
- package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.d.ts +38 -0
- package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +445 -0
- package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +4 -0
- package/lib/view/expenseAutomationView/types/actualMatchingViewState.d.ts +106 -0
- package/lib/view/expenseAutomationView/types/actualMatchingViewState.js +46 -0
- package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +1 -1
- package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +8 -1
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.d.ts +30 -5
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +39 -30
- package/package.json +1 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Amount } from '../../../commonStateTypes/amount';
|
|
2
|
+
import { FetchStateAndError, ID } from '../../../commonStateTypes/common';
|
|
3
|
+
import { SelectorView } from '../../../commonStateTypes/viewAndReport/viewAndReport';
|
|
4
|
+
import { JEOneTimeAccrual } from '../../../entity/jeSchedules/jeSchedulesSelector';
|
|
5
|
+
import { ZeniDate } from '../../../zeniDayJS';
|
|
6
|
+
import { ActualMatchingTransactionSearchResult, ActualMatchingViewUIState, MatchAndReverseResult } from '../types/actualMatchingViewState';
|
|
7
|
+
export type ActualMatchingRowKind = 'auto_reversed' | 'pending_review' | 'manually_reversed';
|
|
8
|
+
export type ActualMatchingGroupedAccrual = {
|
|
9
|
+
accrualId: ID;
|
|
10
|
+
estimatedAmount?: Amount;
|
|
11
|
+
jeDebitAccountName?: string;
|
|
12
|
+
memo?: string;
|
|
13
|
+
serviceMonth?: string;
|
|
14
|
+
};
|
|
15
|
+
export interface ActualMatchingRow extends JEOneTimeAccrual {
|
|
16
|
+
accruedAmount: Amount;
|
|
17
|
+
actualAmount: Amount;
|
|
18
|
+
kind: ActualMatchingRowKind;
|
|
19
|
+
matchId: string;
|
|
20
|
+
groupedAccrualIds?: ID[];
|
|
21
|
+
groupedMembers?: ActualMatchingGroupedAccrual[];
|
|
22
|
+
intendedAccrualIds?: ID[];
|
|
23
|
+
leftovers?: ActualMatchingGroupedAccrual[];
|
|
24
|
+
matchShape?: string;
|
|
25
|
+
matchTier?: string;
|
|
26
|
+
reversalDate?: ZeniDate;
|
|
27
|
+
transactionDate?: string;
|
|
28
|
+
transactionType?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ActualMatchingKpiSummary {
|
|
31
|
+
actualsReceived: {
|
|
32
|
+
count: number;
|
|
33
|
+
expectedCount: number;
|
|
34
|
+
vendorsPending: number;
|
|
35
|
+
};
|
|
36
|
+
autoReversed: {
|
|
37
|
+
clearedAmount: number;
|
|
38
|
+
count: number;
|
|
39
|
+
percent: number;
|
|
40
|
+
};
|
|
41
|
+
pendingReview: {
|
|
42
|
+
amount: number;
|
|
43
|
+
count: number;
|
|
44
|
+
estimatedMinutesToClear: number;
|
|
45
|
+
};
|
|
46
|
+
variance: {
|
|
47
|
+
averagePercentPerMatch: number;
|
|
48
|
+
netAmount: number;
|
|
49
|
+
percent: number;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export interface ActualMatchingMatchModalView {
|
|
53
|
+
accrualSearch: {
|
|
54
|
+
fetchState: FetchStateAndError;
|
|
55
|
+
isLoadingMore: boolean;
|
|
56
|
+
nextPageToken: string | null;
|
|
57
|
+
query: string;
|
|
58
|
+
results: JEOneTimeAccrual[];
|
|
59
|
+
};
|
|
60
|
+
confirmStatus: FetchStateAndError;
|
|
61
|
+
isOpen: boolean;
|
|
62
|
+
transactionSearch: {
|
|
63
|
+
fetchState: FetchStateAndError;
|
|
64
|
+
isLoadingMore: boolean;
|
|
65
|
+
nextPageToken: string | null;
|
|
66
|
+
query: string;
|
|
67
|
+
results: ActualMatchingTransactionSearchResult[];
|
|
68
|
+
};
|
|
69
|
+
lastBatchResults?: MatchAndReverseResult[];
|
|
70
|
+
openedFromMatchId?: string;
|
|
71
|
+
prefill?: {
|
|
72
|
+
selectedAccrualIds: ID[];
|
|
73
|
+
actualAmount?: number;
|
|
74
|
+
consumedLineIds?: ID[];
|
|
75
|
+
matchedLineId?: string;
|
|
76
|
+
matchedTransactionId?: string;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export interface ExpenseAutomationActualMatchingViewSelector extends SelectorView {
|
|
80
|
+
hasLoadedForSelectedPeriod: boolean;
|
|
81
|
+
kpiSummary: ActualMatchingKpiSummary;
|
|
82
|
+
matchModal: ActualMatchingMatchModalView;
|
|
83
|
+
pendingReview: ActualMatchingRow[];
|
|
84
|
+
refreshStatus: FetchStateAndError;
|
|
85
|
+
reversed: ActualMatchingRow[];
|
|
86
|
+
uiState: ActualMatchingViewUIState;
|
|
87
|
+
}
|
package/lib/view/expenseAutomationView/selectorTypes/expenseAutomationViewSelectorTypes.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { MonthEndCloseChecksView } from '../../../view/monthEndCloseChecksView/m
|
|
|
6
6
|
import { CompanyMonthEndReportSelectorView } from '../../companyMonthEndReportView/companyMonthEndReportViewSelector';
|
|
7
7
|
import { ExpenseAutomationViewType } from '../expenseAutomationViewState';
|
|
8
8
|
import { TransactionsTab } from '../types/transactionsViewState';
|
|
9
|
+
import { ExpenseAutomationActualMatchingViewSelector } from './actualMatchingViewSelectorTypes';
|
|
9
10
|
import { ExpenseAutomationFluxAnalysisViewSelector } from './fluxAnalysisViewSelectorTypes';
|
|
10
11
|
import { ExpenseAutomationJESchedulesViewSelector } from './jeSchedulesSelectorTypes';
|
|
11
12
|
import { ExpenseAutomationMissingReceiptsViewSelector } from './missingReceiptsSelectorTypes';
|
|
@@ -21,6 +22,16 @@ export interface ExpenseAutomationStepDetails {
|
|
|
21
22
|
title: string;
|
|
22
23
|
}
|
|
23
24
|
export interface ExpenseAutomationViewSelector extends SelectorView {
|
|
25
|
+
/**
|
|
26
|
+
* Sibling of `jeSchedules`, not nested under it. The Journal Entries navbar
|
|
27
|
+
* hosts Actual Matching (`selectedPageTab === 'actual_matching'`), but AM is
|
|
28
|
+
* a different GET, entity map (`byMatchId`), and period cache
|
|
29
|
+
* (`matchIdsByPeriod`) than Review / Existing. Nesting it on `jeSchedules`
|
|
30
|
+
* would hide a second store inside the schedules selector. Chrome coupling
|
|
31
|
+
* stays `jeSchedules.uiState.selectedPageTab`; AM rows, Match New, and undo
|
|
32
|
+
* live here.
|
|
33
|
+
*/
|
|
34
|
+
actualMatching: ExpenseAutomationActualMatchingViewSelector;
|
|
24
35
|
allSteps: ExpenseAutomationStepDetails[];
|
|
25
36
|
completionStatus: CompletionStatusType;
|
|
26
37
|
currentSelectedView: ExpenseAutomationViewType;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { FetchStateAndError } from '../../../commonStateTypes/common';
|
|
2
|
+
import { MonthYearPeriod } from '../../../commonStateTypes/timePeriod';
|
|
3
|
+
import { DisplayCurrencyFallback } from '../../../entity/actualMatching/actualMatchingPayload';
|
|
4
|
+
import { ActualMatchingMatch } from '../../../entity/actualMatching/actualMatchingState';
|
|
5
|
+
import { ActualMatchingMatchId } from '../../../entity/actualMatching/actualMatchingTypes';
|
|
6
|
+
import { JEOneTimeAccrual } from '../../../entity/jeSchedules/jeSchedulesSelector';
|
|
7
|
+
import { JEOneTimeAccrualMatchSuggestion } from '../../../entity/jeSchedules/jeSchedulesState';
|
|
8
|
+
import { RootState } from '../../../rootStateTypes';
|
|
9
|
+
import { ZeniDate } from '../../../zeniDayJS';
|
|
10
|
+
import { ActualMatchingKpiSummary, ActualMatchingRow, ActualMatchingRowKind, ExpenseAutomationActualMatchingViewSelector } from '../selectorTypes/actualMatchingViewSelectorTypes';
|
|
11
|
+
import { MatchAndReverseResult, UndoReversalResult } from '../types/actualMatchingViewState';
|
|
12
|
+
export declare function getSelectedMonthYearForCurrentTenant(state: RootState): MonthYearPeriod | undefined;
|
|
13
|
+
export declare function getTenantDisplayCurrency(state: RootState): DisplayCurrencyFallback | undefined;
|
|
14
|
+
export declare function parseActualMatchingMatchId(matchId: string): {
|
|
15
|
+
transactionIntegrationId: string;
|
|
16
|
+
transactionType: string;
|
|
17
|
+
} | null;
|
|
18
|
+
export declare function isAutoReversedAccrual(accrual: JEOneTimeAccrual): boolean;
|
|
19
|
+
export declare function isManuallyReversedAccrual(accrual: JEOneTimeAccrual): boolean;
|
|
20
|
+
export declare function isPendingReviewAccrual(accrual: JEOneTimeAccrual): accrual is JEOneTimeAccrual & {
|
|
21
|
+
matchSuggestion: JEOneTimeAccrualMatchSuggestion;
|
|
22
|
+
};
|
|
23
|
+
export declare function isReversedMatchKind(kind: ActualMatchingRowKind): boolean;
|
|
24
|
+
export declare function getClearedMatchedAmount(accrual: JEOneTimeAccrual): number | undefined;
|
|
25
|
+
export declare function getActualMatchingAmount(row: ActualMatchingRow): number;
|
|
26
|
+
export declare function getActualMatchingReversalDate(accrual: JEOneTimeAccrual, matchTransactionDate?: string): ZeniDate | undefined;
|
|
27
|
+
export declare function buildActualMatchingKpiSummary(rows: ActualMatchingRow[], displayCurrencyCode?: string): ActualMatchingKpiSummary;
|
|
28
|
+
export interface ExpenseAutomationActualMatchingMatchView {
|
|
29
|
+
detailFetchState: FetchStateAndError;
|
|
30
|
+
refreshStatus: FetchStateAndError;
|
|
31
|
+
undoReversalStatus: FetchStateAndError;
|
|
32
|
+
lastMatchResults?: MatchAndReverseResult[];
|
|
33
|
+
lastUndoResults?: UndoReversalResult[];
|
|
34
|
+
match?: ActualMatchingMatch;
|
|
35
|
+
}
|
|
36
|
+
export declare function getExpenseAutomationActualMatchingMatchView(state: RootState, matchId: ActualMatchingMatchId): ExpenseAutomationActualMatchingMatchView;
|
|
37
|
+
export declare function getCloseMatchAfterUndo(state: RootState): boolean;
|
|
38
|
+
export declare function getExpenseAutomationActualMatchingView(state: RootState): ExpenseAutomationActualMatchingViewSelector;
|
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getSelectedMonthYearForCurrentTenant = getSelectedMonthYearForCurrentTenant;
|
|
7
|
+
exports.getTenantDisplayCurrency = getTenantDisplayCurrency;
|
|
8
|
+
exports.parseActualMatchingMatchId = parseActualMatchingMatchId;
|
|
9
|
+
exports.isAutoReversedAccrual = isAutoReversedAccrual;
|
|
10
|
+
exports.isManuallyReversedAccrual = isManuallyReversedAccrual;
|
|
11
|
+
exports.isPendingReviewAccrual = isPendingReviewAccrual;
|
|
12
|
+
exports.isReversedMatchKind = isReversedMatchKind;
|
|
13
|
+
exports.getClearedMatchedAmount = getClearedMatchedAmount;
|
|
14
|
+
exports.getActualMatchingAmount = getActualMatchingAmount;
|
|
15
|
+
exports.getActualMatchingReversalDate = getActualMatchingReversalDate;
|
|
16
|
+
exports.buildActualMatchingKpiSummary = buildActualMatchingKpiSummary;
|
|
17
|
+
exports.getExpenseAutomationActualMatchingMatchView = getExpenseAutomationActualMatchingMatchView;
|
|
18
|
+
exports.getCloseMatchAfterUndo = getCloseMatchAfterUndo;
|
|
19
|
+
exports.getExpenseAutomationActualMatchingView = getExpenseAutomationActualMatchingView;
|
|
20
|
+
const orderBy_1 = __importDefault(require("lodash/orderBy"));
|
|
21
|
+
const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
|
|
22
|
+
const actualMatchingSelector_1 = require("../../../entity/actualMatching/actualMatchingSelector");
|
|
23
|
+
const jeScheduleHelper_1 = require("../../../entity/jeSchedules/jeScheduleHelper");
|
|
24
|
+
const jeSchedulesSelector_1 = require("../../../entity/jeSchedules/jeSchedulesSelector");
|
|
25
|
+
const tenantSelector_1 = require("../../../entity/tenant/tenantSelector");
|
|
26
|
+
const zeniDayJS_1 = require("../../../zeniDayJS");
|
|
27
|
+
const actualMatchingViewState_1 = require("../types/actualMatchingViewState");
|
|
28
|
+
function getSelectedMonthYearForCurrentTenant(state) {
|
|
29
|
+
const tenantId = (0, tenantSelector_1.getCurrentTenant)(state)?.tenantId;
|
|
30
|
+
if (tenantId == null) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
return state.expenseAutomationViewState.selectedPeriodByTenantId[tenantId];
|
|
34
|
+
}
|
|
35
|
+
function getTenantDisplayCurrency(state) {
|
|
36
|
+
const locale = (0, tenantSelector_1.getCurrentTenant)(state)?.company?.companyLocaleInfo;
|
|
37
|
+
if (locale?.currencyCode == null || locale.currencyCode === '') {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
currencyCode: locale.currencyCode,
|
|
42
|
+
currencySymbol: locale.currencySymbol != null && locale.currencySymbol !== ''
|
|
43
|
+
? locale.currencySymbol
|
|
44
|
+
: locale.currencyCode,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function toMatchModalAccrual(member) {
|
|
48
|
+
if ('jeOneTimeAccrualKey' in member && member.jeOneTimeAccrualKey != null) {
|
|
49
|
+
return member;
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
...member,
|
|
53
|
+
jeOneTimeAccrualKey: (0, jeScheduleHelper_1.generateJEOneTimeAccrualKey)(member.accrualId),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function uniqueMatchModalAccruals(pinned, searched) {
|
|
57
|
+
const byId = new Map();
|
|
58
|
+
pinned.forEach((row) => byId.set(row.accrualId, row));
|
|
59
|
+
searched.forEach((row) => {
|
|
60
|
+
if (!byId.has(row.accrualId)) {
|
|
61
|
+
byId.set(row.accrualId, row);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return Array.from(byId.values());
|
|
65
|
+
}
|
|
66
|
+
function uniqueTransactionSearchResults(pinned, searched) {
|
|
67
|
+
const byKey = new Map();
|
|
68
|
+
pinned.forEach((row) => byKey.set((0, actualMatchingViewState_1.actualMatchingTransactionLineKey)(row.transactionType, row.transactionIntegrationId, row.lineId), row));
|
|
69
|
+
searched.forEach((row) => {
|
|
70
|
+
const key = (0, actualMatchingViewState_1.actualMatchingTransactionLineKey)(row.transactionType, row.transactionIntegrationId, row.lineId);
|
|
71
|
+
if (!byKey.has(key)) {
|
|
72
|
+
byKey.set(key, row);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return Array.from(byKey.values());
|
|
76
|
+
}
|
|
77
|
+
function parseActualMatchingMatchId(matchId) {
|
|
78
|
+
const separator = matchId.indexOf(':');
|
|
79
|
+
if (separator <= 0 || separator === matchId.length - 1) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
transactionType: matchId.slice(0, separator).toLowerCase(),
|
|
84
|
+
transactionIntegrationId: matchId.slice(separator + 1),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const NOT_STARTED = {
|
|
88
|
+
fetchState: 'Not-Started',
|
|
89
|
+
error: undefined,
|
|
90
|
+
};
|
|
91
|
+
function isAutoReversedAccrual(accrual) {
|
|
92
|
+
return (accrual.accrualStatus === 'reversed' &&
|
|
93
|
+
accrual.reversalTrigger === 'bill_match');
|
|
94
|
+
}
|
|
95
|
+
function isManuallyReversedAccrual(accrual) {
|
|
96
|
+
return (accrual.accrualStatus === 'reversed' &&
|
|
97
|
+
accrual.reversalTrigger === 'manual_reverse');
|
|
98
|
+
}
|
|
99
|
+
function isPendingReviewAccrual(accrual) {
|
|
100
|
+
if (accrual.accrualStatus !== 'posted' || accrual.matchSuggestion == null) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
const resolution = accrual.matchSuggestion.resolution;
|
|
104
|
+
return resolution == null || resolution.length === 0;
|
|
105
|
+
}
|
|
106
|
+
function isReversedMatchKind(kind) {
|
|
107
|
+
return kind === 'auto_reversed' || kind === 'manually_reversed';
|
|
108
|
+
}
|
|
109
|
+
function getClearedMatchedAmount(accrual) {
|
|
110
|
+
return accrual.cleared?.matchedAmount?.amount;
|
|
111
|
+
}
|
|
112
|
+
function getActualMatchingAmount(row) {
|
|
113
|
+
return row.actualAmount?.amount ?? row.estimatedAmount.amount;
|
|
114
|
+
}
|
|
115
|
+
function parseMatchTransactionDate(transactionDate) {
|
|
116
|
+
if (transactionDate == null || transactionDate === '') {
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
const parsed = (0, zeniDayJS_1.date)(transactionDate);
|
|
120
|
+
return Number.isFinite(parsed.valueOf()) ? parsed : undefined;
|
|
121
|
+
}
|
|
122
|
+
function getActualMatchingReversalDate(accrual, matchTransactionDate) {
|
|
123
|
+
const matchedDate = isPendingReviewAccrual(accrual)
|
|
124
|
+
? accrual.matchSuggestion.matchedTransactionDate
|
|
125
|
+
: accrual.cleared?.matchedTransactionDate;
|
|
126
|
+
return matchedDate ?? parseMatchTransactionDate(matchTransactionDate);
|
|
127
|
+
}
|
|
128
|
+
function collectGroupedMembers(members) {
|
|
129
|
+
if (members.length <= 1) {
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
return members.map((member) => ({
|
|
133
|
+
accrualId: member.accrualId,
|
|
134
|
+
estimatedAmount: member.estimatedAmount,
|
|
135
|
+
jeDebitAccountName: member.jeDebitAccountName,
|
|
136
|
+
memo: member.memo,
|
|
137
|
+
serviceMonth: member.serviceMonth,
|
|
138
|
+
}));
|
|
139
|
+
}
|
|
140
|
+
function collectLeftoverMembers(leftovers) {
|
|
141
|
+
if (leftovers == null || leftovers.length === 0) {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
return leftovers.map((member) => ({
|
|
145
|
+
accrualId: member.accrualId,
|
|
146
|
+
estimatedAmount: member.estimatedAmount,
|
|
147
|
+
jeDebitAccountName: member.jeDebitAccountName,
|
|
148
|
+
memo: member.memo,
|
|
149
|
+
serviceMonth: member.serviceMonth,
|
|
150
|
+
}));
|
|
151
|
+
}
|
|
152
|
+
function toActualMatchingRow(match) {
|
|
153
|
+
const firstMember = match.members[0];
|
|
154
|
+
if (firstMember == null) {
|
|
155
|
+
throw new Error('Actual matching row requires at least one member');
|
|
156
|
+
}
|
|
157
|
+
const first = toMatchModalAccrual(firstMember);
|
|
158
|
+
const leftoverMembers = match.leftovers ?? [];
|
|
159
|
+
const fromCleared = firstMember.cleared?.intendedAccrualIds;
|
|
160
|
+
const intendedAccrualIds = fromCleared != null && fromCleared.length > 0
|
|
161
|
+
? fromCleared
|
|
162
|
+
: [
|
|
163
|
+
...match.members.map((member) => member.accrualId),
|
|
164
|
+
...leftoverMembers.map((leftover) => leftover.accrualId),
|
|
165
|
+
];
|
|
166
|
+
return {
|
|
167
|
+
...first,
|
|
168
|
+
matchId: match.matchId,
|
|
169
|
+
kind: match.kind,
|
|
170
|
+
accruedAmount: match.accruedAmount,
|
|
171
|
+
actualAmount: match.actualAmount,
|
|
172
|
+
matchTier: match.matchTier,
|
|
173
|
+
matchShape: match.matchShape,
|
|
174
|
+
transactionType: match.transactionType,
|
|
175
|
+
transactionDate: match.transactionDate,
|
|
176
|
+
groupedAccrualIds: match.members.map((member) => member.accrualId),
|
|
177
|
+
groupedMembers: collectGroupedMembers(match.members),
|
|
178
|
+
intendedAccrualIds,
|
|
179
|
+
leftovers: collectLeftoverMembers(match.leftovers),
|
|
180
|
+
reversalDate: getActualMatchingReversalDate(first, match.transactionDate),
|
|
181
|
+
vendorName: match.vendorName != null && match.vendorName !== ''
|
|
182
|
+
? match.vendorName
|
|
183
|
+
: first.vendorName,
|
|
184
|
+
estimatedAmount: match.accruedAmount,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function matchesSearch(row, searchString) {
|
|
188
|
+
const trimmed = searchString.trim().toLowerCase();
|
|
189
|
+
if (trimmed.length === 0) {
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
if ((row.vendorName ?? '').toLowerCase().includes(trimmed)) {
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
if ((row.memo ?? '').toLowerCase().includes(trimmed)) {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
return (row.groupedMembers ?? []).some((member) => (member.memo ?? '').toLowerCase().includes(trimmed));
|
|
199
|
+
}
|
|
200
|
+
function getActualMatchingSortValue(row, sortKey) {
|
|
201
|
+
switch (sortKey) {
|
|
202
|
+
case 'vendor':
|
|
203
|
+
return (row.vendorName ?? '').toLowerCase();
|
|
204
|
+
case 'date': {
|
|
205
|
+
const millis = row.reversalDate?.valueOf() ??
|
|
206
|
+
(row.transactionDate != null && row.transactionDate !== ''
|
|
207
|
+
? (0, zeniDayJS_1.date)(row.transactionDate).valueOf()
|
|
208
|
+
: 0);
|
|
209
|
+
return Number.isFinite(millis) ? millis : 0;
|
|
210
|
+
}
|
|
211
|
+
case 'amount':
|
|
212
|
+
return getActualMatchingAmount(row);
|
|
213
|
+
case 'category':
|
|
214
|
+
return row.jeDebitAccountName?.toLowerCase();
|
|
215
|
+
case 'class':
|
|
216
|
+
return row.jeDebitAccountingClassName?.toLowerCase();
|
|
217
|
+
case 'type':
|
|
218
|
+
return row.transactionType?.toLowerCase();
|
|
219
|
+
case 'lifecycle':
|
|
220
|
+
return row.kind;
|
|
221
|
+
case 'service':
|
|
222
|
+
return row.serviceMonth;
|
|
223
|
+
case 'accrued':
|
|
224
|
+
return row.accruedAmount?.amount ?? row.estimatedAmount.amount;
|
|
225
|
+
case 'actual':
|
|
226
|
+
return row.actualAmount?.amount;
|
|
227
|
+
case 'variance': {
|
|
228
|
+
const accrued = row.accruedAmount?.amount ?? row.estimatedAmount.amount;
|
|
229
|
+
const actual = row.actualAmount?.amount;
|
|
230
|
+
if (actual == null || accrued === 0) {
|
|
231
|
+
return undefined;
|
|
232
|
+
}
|
|
233
|
+
return ((actual - accrued) / Math.abs(accrued)) * 100;
|
|
234
|
+
}
|
|
235
|
+
default:
|
|
236
|
+
return undefined;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function sortActualMatchingRows(rows, uiState) {
|
|
240
|
+
const lodashOrder = uiState.sortOrder === 'ascending' ? 'asc' : 'desc';
|
|
241
|
+
return (0, orderBy_1.default)(rows, [(row) => getActualMatchingSortValue(row, uiState.sortKey)], [lodashOrder]);
|
|
242
|
+
}
|
|
243
|
+
const ESTIMATED_MINUTES_PER_PENDING_MATCH = 4;
|
|
244
|
+
function emptyKpiSummary() {
|
|
245
|
+
return {
|
|
246
|
+
actualsReceived: { count: 0, expectedCount: 0, vendorsPending: 0 },
|
|
247
|
+
autoReversed: { count: 0, percent: 0, clearedAmount: 0 },
|
|
248
|
+
pendingReview: { count: 0, amount: 0, estimatedMinutesToClear: 0 },
|
|
249
|
+
variance: { percent: 0, averagePercentPerMatch: 0, netAmount: 0 },
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function sumRowAmounts(rows, displayCurrencyCode) {
|
|
253
|
+
return rows.reduce((sum, row) => {
|
|
254
|
+
if (displayCurrencyCode != null &&
|
|
255
|
+
row.accruedAmount.currencyCode !== displayCurrencyCode) {
|
|
256
|
+
return sum;
|
|
257
|
+
}
|
|
258
|
+
return sum + getActualMatchingAmount(row);
|
|
259
|
+
}, 0);
|
|
260
|
+
}
|
|
261
|
+
function isKnownKpiKind(kind) {
|
|
262
|
+
return (kind === 'auto_reversed' ||
|
|
263
|
+
kind === 'pending_review' ||
|
|
264
|
+
kind === 'manually_reversed');
|
|
265
|
+
}
|
|
266
|
+
function rowMatchesDisplayCurrency(row, displayCurrencyCode) {
|
|
267
|
+
if (displayCurrencyCode == null) {
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
const rowCurrency = row.accruedAmount?.currencyCode ?? row.estimatedAmount.currencyCode;
|
|
271
|
+
return rowCurrency === displayCurrencyCode;
|
|
272
|
+
}
|
|
273
|
+
function uniqueVendorCount(rows) {
|
|
274
|
+
const ids = new Set();
|
|
275
|
+
rows.forEach((row) => {
|
|
276
|
+
if (row.vendorId != null && row.vendorId !== '') {
|
|
277
|
+
ids.add(row.vendorId);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (row.vendorName != null && row.vendorName !== '') {
|
|
281
|
+
ids.add(row.vendorName);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
return ids.size;
|
|
285
|
+
}
|
|
286
|
+
function rowVariancePercent(row) {
|
|
287
|
+
const accrued = row.accruedAmount?.amount ?? row.estimatedAmount.amount;
|
|
288
|
+
const actual = row.actualAmount?.amount;
|
|
289
|
+
if (actual == null || accrued === 0) {
|
|
290
|
+
return undefined;
|
|
291
|
+
}
|
|
292
|
+
return ((actual - accrued) / Math.abs(accrued)) * 100;
|
|
293
|
+
}
|
|
294
|
+
function buildActualMatchingKpiSummary(rows, displayCurrencyCode) {
|
|
295
|
+
// Strip counts and amounts share this set: known kinds only, and (when a
|
|
296
|
+
// display currency is set) that currency only. Lists still render every row.
|
|
297
|
+
const kpiRows = rows.filter((row) => isKnownKpiKind(row.kind) &&
|
|
298
|
+
rowMatchesDisplayCurrency(row, displayCurrencyCode));
|
|
299
|
+
if (kpiRows.length === 0) {
|
|
300
|
+
return emptyKpiSummary();
|
|
301
|
+
}
|
|
302
|
+
const autoReversed = kpiRows.filter((row) => row.kind === 'auto_reversed');
|
|
303
|
+
const pendingReview = kpiRows.filter((row) => row.kind === 'pending_review');
|
|
304
|
+
const receivedCount = kpiRows.length;
|
|
305
|
+
const rowsWithActual = kpiRows.filter((row) => row.actualAmount?.amount != null);
|
|
306
|
+
const accruedTotal = rowsWithActual.reduce((sum, row) => sum + (row.accruedAmount?.amount ?? row.estimatedAmount.amount), 0);
|
|
307
|
+
const actualTotal = rowsWithActual.reduce((sum, row) => sum + (row.actualAmount?.amount ?? 0), 0);
|
|
308
|
+
const variancePercents = kpiRows
|
|
309
|
+
.map(rowVariancePercent)
|
|
310
|
+
.filter((percent) => percent != null);
|
|
311
|
+
return {
|
|
312
|
+
actualsReceived: {
|
|
313
|
+
count: receivedCount,
|
|
314
|
+
// List API does not return still-expected accruals; hide "of N expected"
|
|
315
|
+
// in the strip until expectedCount is greater than received.
|
|
316
|
+
expectedCount: receivedCount,
|
|
317
|
+
vendorsPending: uniqueVendorCount(pendingReview),
|
|
318
|
+
},
|
|
319
|
+
autoReversed: {
|
|
320
|
+
count: autoReversed.length,
|
|
321
|
+
percent: Math.round((autoReversed.length / receivedCount) * 100),
|
|
322
|
+
clearedAmount: sumRowAmounts(autoReversed, displayCurrencyCode),
|
|
323
|
+
},
|
|
324
|
+
pendingReview: {
|
|
325
|
+
count: pendingReview.length,
|
|
326
|
+
amount: sumRowAmounts(pendingReview, displayCurrencyCode),
|
|
327
|
+
estimatedMinutesToClear: pendingReview.length * ESTIMATED_MINUTES_PER_PENDING_MATCH,
|
|
328
|
+
},
|
|
329
|
+
variance: {
|
|
330
|
+
percent: accruedTotal === 0
|
|
331
|
+
? 0
|
|
332
|
+
: ((actualTotal - accruedTotal) / Math.abs(accruedTotal)) * 100,
|
|
333
|
+
averagePercentPerMatch: variancePercents.length === 0
|
|
334
|
+
? 0
|
|
335
|
+
: variancePercents.reduce((sum, percent) => sum + percent, 0) /
|
|
336
|
+
variancePercents.length,
|
|
337
|
+
netAmount: actualTotal - accruedTotal,
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
function getExpenseAutomationActualMatchingMatchView(state, matchId) {
|
|
342
|
+
const view = state.expenseAutomationActualMatchingViewState;
|
|
343
|
+
return {
|
|
344
|
+
match: (0, actualMatchingSelector_1.getActualMatchingMatchById)(state.actualMatchingState, matchId),
|
|
345
|
+
detailFetchState: view.detailFetchStateByMatchId[matchId] ?? NOT_STARTED,
|
|
346
|
+
refreshStatus: view.detailRefreshStatusByMatchId[matchId] ?? NOT_STARTED,
|
|
347
|
+
undoReversalStatus: view.undoReversalStatusByMatchId[matchId] ?? NOT_STARTED,
|
|
348
|
+
lastMatchResults: view.lastMatchResultsByMatchId?.[matchId],
|
|
349
|
+
lastUndoResults: view.lastUndoResultsByMatchId?.[matchId],
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function getCloseMatchAfterUndo(state) {
|
|
353
|
+
return state.expenseAutomationActualMatchingViewState.closeMatchAfterUndo;
|
|
354
|
+
}
|
|
355
|
+
function getExpenseAutomationActualMatchingView(state) {
|
|
356
|
+
const { expenseAutomationActualMatchingViewState } = state;
|
|
357
|
+
const { matchIdsByPeriod, fetchState, error, refreshStatus, uiState, matchModal, } = expenseAutomationActualMatchingViewState;
|
|
358
|
+
const selectedPeriod = getSelectedMonthYearForCurrentTenant(state);
|
|
359
|
+
const monthYearPeriodId = selectedPeriod != null ? (0, timePeriod_1.toMonthYearPeriodId)(selectedPeriod) : undefined;
|
|
360
|
+
const matchIds = monthYearPeriodId != null ? matchIdsByPeriod[monthYearPeriodId] : undefined;
|
|
361
|
+
const allRows = (matchIds ?? [])
|
|
362
|
+
.map((matchId) => (0, actualMatchingSelector_1.getActualMatchingMatchById)(state.actualMatchingState, matchId))
|
|
363
|
+
.filter((match) => match != null)
|
|
364
|
+
.filter((match) => match.members.length > 0)
|
|
365
|
+
.map(toActualMatchingRow);
|
|
366
|
+
const rows = allRows.filter((row) => matchesSearch(row, uiState.searchString));
|
|
367
|
+
const reversed = sortActualMatchingRows(rows.filter((row) => isReversedMatchKind(row.kind)), uiState);
|
|
368
|
+
const pendingReview = sortActualMatchingRows(rows.filter((row) => row.kind === 'pending_review'), uiState);
|
|
369
|
+
const kpiSummary = buildActualMatchingKpiSummary(allRows, getTenantDisplayCurrency(state)?.currencyCode);
|
|
370
|
+
const searchedAccruals = matchModal.accrualSearch.results
|
|
371
|
+
.map((key) => (0, jeSchedulesSelector_1.getJEOneTimeAccrualByKey)(key, state.jeSchedulesState))
|
|
372
|
+
.filter((accrual) => accrual != null);
|
|
373
|
+
const openedMatch = matchModal.openedFromMatchId != null
|
|
374
|
+
? (0, actualMatchingSelector_1.getActualMatchingMatchById)(state.actualMatchingState, matchModal.openedFromMatchId)
|
|
375
|
+
: undefined;
|
|
376
|
+
const pinnedAccruals = [
|
|
377
|
+
...(openedMatch?.members ?? []),
|
|
378
|
+
...(openedMatch?.leftovers ?? []),
|
|
379
|
+
].map(toMatchModalAccrual);
|
|
380
|
+
const firstMember = openedMatch?.members[0];
|
|
381
|
+
const cleared = firstMember?.cleared;
|
|
382
|
+
const suggestion = firstMember?.matchSuggestion;
|
|
383
|
+
const stamp = cleared ?? suggestion;
|
|
384
|
+
const consumedLineIds = cleared?.consumedLineIds;
|
|
385
|
+
const prefill = openedMatch == null
|
|
386
|
+
? undefined
|
|
387
|
+
: {
|
|
388
|
+
selectedAccrualIds: [
|
|
389
|
+
...openedMatch.members.map((member) => member.accrualId),
|
|
390
|
+
...(openedMatch.leftovers ?? []).map((leftover) => leftover.accrualId),
|
|
391
|
+
],
|
|
392
|
+
actualAmount: openedMatch.actualAmount.amount,
|
|
393
|
+
matchedTransactionId: stamp?.matchedTransactionId,
|
|
394
|
+
matchedLineId: cleared == null ? suggestion?.matchedLineId : undefined,
|
|
395
|
+
...(consumedLineIds != null && consumedLineIds.length > 0
|
|
396
|
+
? { consumedLineIds }
|
|
397
|
+
: {}),
|
|
398
|
+
};
|
|
399
|
+
// `fetchState` is a flat slice field that survives a period switch. Until this
|
|
400
|
+
// month's ids land, leftover Completed/Error is the previous month. Report
|
|
401
|
+
// Not-Started so chrome matches Review's "cache slot missing" skeleton, not
|
|
402
|
+
// empty-complete or a stale error. In-Progress is this month's fetch.
|
|
403
|
+
const fetchStatus = matchIds == null &&
|
|
404
|
+
fetchState !== 'In-Progress' &&
|
|
405
|
+
fetchState !== 'Not-Started'
|
|
406
|
+
? { fetchState: 'Not-Started', error: undefined }
|
|
407
|
+
: { fetchState, error };
|
|
408
|
+
return {
|
|
409
|
+
fetchState: fetchStatus.fetchState,
|
|
410
|
+
error: fetchStatus.error,
|
|
411
|
+
reversed,
|
|
412
|
+
pendingReview,
|
|
413
|
+
kpiSummary,
|
|
414
|
+
uiState,
|
|
415
|
+
refreshStatus,
|
|
416
|
+
hasLoadedForSelectedPeriod: matchIds != null,
|
|
417
|
+
matchModal: {
|
|
418
|
+
isOpen: matchModal.isOpen,
|
|
419
|
+
openedFromMatchId: matchModal.openedFromMatchId,
|
|
420
|
+
prefill,
|
|
421
|
+
confirmStatus: matchModal.confirmStatus,
|
|
422
|
+
lastBatchResults: matchModal.lastBatchResults,
|
|
423
|
+
transactionSearch: {
|
|
424
|
+
query: matchModal.transactionSearch.query,
|
|
425
|
+
results: uniqueTransactionSearchResults(matchModal.pinnedTransactionResults, matchModal.transactionSearch.results),
|
|
426
|
+
fetchState: {
|
|
427
|
+
fetchState: matchModal.transactionSearch.fetchState,
|
|
428
|
+
error: matchModal.transactionSearch.error,
|
|
429
|
+
},
|
|
430
|
+
nextPageToken: matchModal.transactionSearch.nextPageToken,
|
|
431
|
+
isLoadingMore: matchModal.transactionSearch.isLoadingMore,
|
|
432
|
+
},
|
|
433
|
+
accrualSearch: {
|
|
434
|
+
query: matchModal.accrualSearch.query,
|
|
435
|
+
results: uniqueMatchModalAccruals(pinnedAccruals, searchedAccruals),
|
|
436
|
+
fetchState: {
|
|
437
|
+
fetchState: matchModal.accrualSearch.fetchState,
|
|
438
|
+
error: matchModal.accrualSearch.error,
|
|
439
|
+
},
|
|
440
|
+
nextPageToken: matchModal.accrualSearch.nextPageToken,
|
|
441
|
+
isLoadingMore: matchModal.accrualSearch.isLoadingMore,
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
};
|
|
445
|
+
}
|
|
@@ -381,6 +381,10 @@ function getExpenseAutomationJESchedulesView(state) {
|
|
|
381
381
|
// reports undefined rather than 0, so the UI can hide the badge instead of asserting "none".
|
|
382
382
|
const scheduleCountsByTab = {};
|
|
383
383
|
jeSchedulesViewState_1.ALL_JE_PAGE_TABS.forEach((pageTab) => {
|
|
384
|
+
// AM's badge is `actualMatching.kpiSummary`, not schedule row keys.
|
|
385
|
+
if (pageTab === 'actual_matching') {
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
384
388
|
const periodTabKey = monthYearPeriodId != null
|
|
385
389
|
? (0, jeSchedulesViewState_1.getJESchedulePeriodTabKey)(pageTab, monthYearPeriodId)
|
|
386
390
|
: null;
|