@zeniai/client-epic-state 5.2.22-betaAM4 → 5.2.22-betaAM5
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 +25 -0
- package/lib/entity/actualMatching/actualMatchingPayload.js +42 -0
- package/lib/entity/actualMatching/actualMatchingReducer.d.ts +8 -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 +22 -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/epic.d.ts +2 -1
- package/lib/epic.js +2 -0
- package/lib/esm/entity/actualMatching/actualMatchingPayload.js +39 -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/epic.js +2 -0
- package/lib/esm/index.js +3 -3
- package/lib/esm/reducer.js +3 -0
- package/lib/esm/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingEpic.js +6 -6
- package/lib/esm/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingMatchEpic.js +35 -0
- package/lib/esm/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.js +35 -6
- package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +1 -1
- package/lib/esm/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +87 -8
- package/lib/esm/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +143 -98
- package/lib/esm/view/expenseAutomationView/types/actualMatchingViewState.js +4 -0
- package/lib/index.d.ts +6 -3
- package/lib/index.js +21 -18
- package/lib/reducer.d.ts +1 -0
- package/lib/reducer.js +3 -0
- package/lib/rootStateTypes.d.ts +2 -0
- package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingEpic.d.ts +2 -2
- package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingEpic.js +6 -6
- package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingMatchEpic.d.ts +12 -0
- package/lib/view/expenseAutomationView/epics/actualMatching/fetchActualMatchingMatchEpic.js +39 -0
- package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.d.ts +1 -1
- package/lib/view/expenseAutomationView/epics/actualMatching/searchMatchTransactionsEpic.js +35 -6
- package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +1 -1
- package/lib/view/expenseAutomationView/payload/actualMatchingPayload.d.ts +3 -6
- package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.d.ts +20 -3
- package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +88 -9
- package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.d.ts +15 -2
- package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.d.ts +16 -2
- package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +146 -98
- package/lib/view/expenseAutomationView/types/actualMatchingViewState.d.ts +7 -2
- package/lib/view/expenseAutomationView/types/actualMatchingViewState.js +4 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.updateActualMatchingUIState = exports.searchMatchTransactionsSuccess = exports.searchMatchTransactionsFailure = exports.searchMatchTransactions = exports.searchMatchAccrualsSuccess = exports.searchMatchAccrualsFailure = exports.searchMatchAccruals = exports.openMatchNewModal = exports.matchAndReverseAccrualsSuccess = exports.matchAndReverseAccrualsFailure = exports.matchAndReverseAccruals = exports.fetchActualMatchingSuccess = exports.fetchActualMatchingPage = exports.fetchActualMatchingFailure = exports.fetchActualMatching = exports.closeMatchNewModal = exports.clearMatchNewModal = exports.clearActualMatchingView = exports.initialState = exports.initialMatchModalState = exports.initialAccrualSearchState = exports.initialTransactionSearchState = void 0;
|
|
4
|
+
exports.updateActualMatchingUIState = exports.searchMatchTransactionsSuccess = exports.searchMatchTransactionsFailure = exports.searchMatchTransactions = exports.searchMatchAccrualsSuccess = exports.searchMatchAccrualsFailure = exports.searchMatchAccruals = exports.openMatchNewModal = exports.matchAndReverseAccrualsSuccess = exports.matchAndReverseAccrualsFailure = exports.matchAndReverseAccruals = exports.fetchActualMatchingSuccess = exports.fetchActualMatchingPage = exports.fetchActualMatchingMatchSuccess = exports.fetchActualMatchingMatchFailure = exports.fetchActualMatchingMatch = exports.fetchActualMatchingFailure = exports.fetchActualMatching = exports.closeMatchNewModal = exports.clearMatchNewModal = exports.clearActualMatchingView = exports.initialState = exports.initialMatchModalState = exports.initialAccrualSearchState = exports.initialTransactionSearchState = void 0;
|
|
5
5
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
6
6
|
const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
|
|
7
7
|
const jeScheduleHelper_1 = require("../../../entity/jeSchedules/jeScheduleHelper");
|
|
@@ -24,18 +24,22 @@ exports.initialAccrualSearchState = {
|
|
|
24
24
|
};
|
|
25
25
|
exports.initialMatchModalState = {
|
|
26
26
|
isOpen: false,
|
|
27
|
+
openedFromMatchId: undefined,
|
|
28
|
+
pinnedTransactionResults: [],
|
|
27
29
|
transactionSearch: exports.initialTransactionSearchState,
|
|
28
30
|
accrualSearch: exports.initialAccrualSearchState,
|
|
29
31
|
confirmStatus: { fetchState: 'Not-Started', error: undefined },
|
|
30
32
|
};
|
|
31
33
|
exports.initialState = {
|
|
32
|
-
|
|
34
|
+
matchIdsByPeriod: {},
|
|
33
35
|
fetchState: 'Not-Started',
|
|
34
36
|
error: undefined,
|
|
35
37
|
refreshStatus: {
|
|
36
38
|
fetchState: 'Not-Started',
|
|
37
39
|
error: undefined,
|
|
38
40
|
},
|
|
41
|
+
detailFetchStateByMatchId: {},
|
|
42
|
+
detailRefreshStatusByMatchId: {},
|
|
39
43
|
uiState: {
|
|
40
44
|
sortKey: 'date',
|
|
41
45
|
sortOrder: 'descending',
|
|
@@ -55,6 +59,8 @@ function resetMatchModalSearches(draft) {
|
|
|
55
59
|
error: undefined,
|
|
56
60
|
};
|
|
57
61
|
draft.matchModal.lastBatchResults = undefined;
|
|
62
|
+
draft.matchModal.openedFromMatchId = undefined;
|
|
63
|
+
draft.matchModal.pinnedTransactionResults = [];
|
|
58
64
|
}
|
|
59
65
|
const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
|
|
60
66
|
name: 'expenseAutomationActualMatchingView',
|
|
@@ -94,9 +100,9 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
|
|
|
94
100
|
},
|
|
95
101
|
},
|
|
96
102
|
fetchActualMatchingSuccess(draft, action) {
|
|
97
|
-
const {
|
|
103
|
+
const { matchIds, selectedPeriod, refreshViewInBackground } = action.payload;
|
|
98
104
|
const periodId = (0, timePeriod_1.toMonthYearPeriodId)(selectedPeriod);
|
|
99
|
-
draft.
|
|
105
|
+
draft.matchIdsByPeriod[periodId] = matchIds;
|
|
100
106
|
if (refreshViewInBackground) {
|
|
101
107
|
draft.refreshStatus = { fetchState: 'Completed', error: undefined };
|
|
102
108
|
}
|
|
@@ -115,6 +121,56 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
|
|
|
115
121
|
draft.error = status;
|
|
116
122
|
}
|
|
117
123
|
},
|
|
124
|
+
fetchActualMatchingMatch: {
|
|
125
|
+
prepare(matchId, refreshViewInBackground = false) {
|
|
126
|
+
return { payload: { matchId, refreshViewInBackground } };
|
|
127
|
+
},
|
|
128
|
+
reducer(draft, action) {
|
|
129
|
+
const { matchId, refreshViewInBackground } = action.payload;
|
|
130
|
+
if (refreshViewInBackground) {
|
|
131
|
+
draft.detailRefreshStatusByMatchId[matchId] = {
|
|
132
|
+
fetchState: 'In-Progress',
|
|
133
|
+
error: undefined,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
draft.detailFetchStateByMatchId[matchId] = {
|
|
138
|
+
fetchState: 'In-Progress',
|
|
139
|
+
error: undefined,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
fetchActualMatchingMatchSuccess(draft, action) {
|
|
145
|
+
const { matchId, refreshViewInBackground } = action.payload;
|
|
146
|
+
if (refreshViewInBackground) {
|
|
147
|
+
draft.detailRefreshStatusByMatchId[matchId] = {
|
|
148
|
+
fetchState: 'Completed',
|
|
149
|
+
error: undefined,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
draft.detailFetchStateByMatchId[matchId] = {
|
|
154
|
+
fetchState: 'Completed',
|
|
155
|
+
error: undefined,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
fetchActualMatchingMatchFailure(draft, action) {
|
|
160
|
+
const { matchId, refreshViewInBackground, status } = action.payload;
|
|
161
|
+
if (refreshViewInBackground) {
|
|
162
|
+
draft.detailRefreshStatusByMatchId[matchId] = {
|
|
163
|
+
fetchState: 'Error',
|
|
164
|
+
error: status,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
draft.detailFetchStateByMatchId[matchId] = {
|
|
169
|
+
fetchState: 'Error',
|
|
170
|
+
error: status,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
},
|
|
118
174
|
updateActualMatchingUIState(draft, action) {
|
|
119
175
|
if (action.payload.sortKey != null) {
|
|
120
176
|
draft.uiState.sortKey = action.payload.sortKey;
|
|
@@ -129,8 +185,20 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
|
|
|
129
185
|
draft.uiState.scrollPosition = action.payload.scrollPosition;
|
|
130
186
|
}
|
|
131
187
|
},
|
|
132
|
-
openMatchNewModal
|
|
133
|
-
|
|
188
|
+
openMatchNewModal: {
|
|
189
|
+
prepare(matchId) {
|
|
190
|
+
return { payload: { matchId } };
|
|
191
|
+
},
|
|
192
|
+
reducer(draft, action) {
|
|
193
|
+
resetMatchModalSearches(draft);
|
|
194
|
+
draft.matchModal.isOpen = true;
|
|
195
|
+
const matchId = action.payload.matchId;
|
|
196
|
+
draft.matchModal.openedFromMatchId =
|
|
197
|
+
matchId != null && matchId !== '' ? matchId : undefined;
|
|
198
|
+
if (draft.matchModal.openedFromMatchId != null) {
|
|
199
|
+
draft.matchModal.accrualSearch.fetchState = 'Completed';
|
|
200
|
+
}
|
|
201
|
+
},
|
|
134
202
|
},
|
|
135
203
|
closeMatchNewModal(draft) {
|
|
136
204
|
draft.matchModal.isOpen = false;
|
|
@@ -156,8 +224,15 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
|
|
|
156
224
|
draft.matchModal.transactionSearch.error = undefined;
|
|
157
225
|
}
|
|
158
226
|
},
|
|
159
|
-
prepare({ query, pageToken }) {
|
|
160
|
-
return {
|
|
227
|
+
prepare({ query, pageToken, transactionType, transactionIntegrationId, }) {
|
|
228
|
+
return {
|
|
229
|
+
payload: {
|
|
230
|
+
query,
|
|
231
|
+
pageToken: pageToken ?? undefined,
|
|
232
|
+
transactionType,
|
|
233
|
+
transactionIntegrationId,
|
|
234
|
+
},
|
|
235
|
+
};
|
|
161
236
|
},
|
|
162
237
|
},
|
|
163
238
|
searchMatchTransactionsSuccess(draft, action) {
|
|
@@ -175,6 +250,10 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
|
|
|
175
250
|
}
|
|
176
251
|
else {
|
|
177
252
|
draft.matchModal.transactionSearch.results = results;
|
|
253
|
+
if (draft.matchModal.openedFromMatchId != null &&
|
|
254
|
+
draft.matchModal.pinnedTransactionResults.length === 0) {
|
|
255
|
+
draft.matchModal.pinnedTransactionResults = results;
|
|
256
|
+
}
|
|
178
257
|
}
|
|
179
258
|
draft.matchModal.transactionSearch.nextPageToken = nextPageToken;
|
|
180
259
|
draft.matchModal.transactionSearch.isLoadingMore = false;
|
|
@@ -260,5 +339,5 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
|
|
|
260
339
|
});
|
|
261
340
|
},
|
|
262
341
|
});
|
|
263
|
-
_a = expenseAutomationActualMatchingView.actions, exports.clearActualMatchingView = _a.clearActualMatchingView, exports.clearMatchNewModal = _a.clearMatchNewModal, exports.closeMatchNewModal = _a.closeMatchNewModal, exports.fetchActualMatching = _a.fetchActualMatching, exports.fetchActualMatchingFailure = _a.fetchActualMatchingFailure, exports.fetchActualMatchingPage = _a.fetchActualMatchingPage, exports.fetchActualMatchingSuccess = _a.fetchActualMatchingSuccess, exports.matchAndReverseAccruals = _a.matchAndReverseAccruals, exports.matchAndReverseAccrualsFailure = _a.matchAndReverseAccrualsFailure, exports.matchAndReverseAccrualsSuccess = _a.matchAndReverseAccrualsSuccess, exports.openMatchNewModal = _a.openMatchNewModal, exports.searchMatchAccruals = _a.searchMatchAccruals, exports.searchMatchAccrualsFailure = _a.searchMatchAccrualsFailure, exports.searchMatchAccrualsSuccess = _a.searchMatchAccrualsSuccess, exports.searchMatchTransactions = _a.searchMatchTransactions, exports.searchMatchTransactionsFailure = _a.searchMatchTransactionsFailure, exports.searchMatchTransactionsSuccess = _a.searchMatchTransactionsSuccess, exports.updateActualMatchingUIState = _a.updateActualMatchingUIState;
|
|
342
|
+
_a = expenseAutomationActualMatchingView.actions, exports.clearActualMatchingView = _a.clearActualMatchingView, exports.clearMatchNewModal = _a.clearMatchNewModal, exports.closeMatchNewModal = _a.closeMatchNewModal, exports.fetchActualMatching = _a.fetchActualMatching, exports.fetchActualMatchingFailure = _a.fetchActualMatchingFailure, exports.fetchActualMatchingMatch = _a.fetchActualMatchingMatch, exports.fetchActualMatchingMatchFailure = _a.fetchActualMatchingMatchFailure, exports.fetchActualMatchingMatchSuccess = _a.fetchActualMatchingMatchSuccess, exports.fetchActualMatchingPage = _a.fetchActualMatchingPage, exports.fetchActualMatchingSuccess = _a.fetchActualMatchingSuccess, exports.matchAndReverseAccruals = _a.matchAndReverseAccruals, exports.matchAndReverseAccrualsFailure = _a.matchAndReverseAccrualsFailure, exports.matchAndReverseAccrualsSuccess = _a.matchAndReverseAccrualsSuccess, exports.openMatchNewModal = _a.openMatchNewModal, exports.searchMatchAccruals = _a.searchMatchAccruals, exports.searchMatchAccrualsFailure = _a.searchMatchAccrualsFailure, exports.searchMatchAccrualsSuccess = _a.searchMatchAccrualsSuccess, exports.searchMatchTransactions = _a.searchMatchTransactions, exports.searchMatchTransactionsFailure = _a.searchMatchTransactionsFailure, exports.searchMatchTransactionsSuccess = _a.searchMatchTransactionsSuccess, exports.updateActualMatchingUIState = _a.updateActualMatchingUIState;
|
|
264
343
|
exports.default = expenseAutomationActualMatchingView.reducer;
|
|
@@ -13,10 +13,17 @@ export type ActualMatchingGroupedAccrual = {
|
|
|
13
13
|
serviceMonth?: string;
|
|
14
14
|
};
|
|
15
15
|
export interface ActualMatchingRow extends JEOneTimeAccrual {
|
|
16
|
+
accruedAmount: Amount;
|
|
17
|
+
actualAmount: Amount;
|
|
16
18
|
kind: ActualMatchingRowKind;
|
|
19
|
+
matchId: string;
|
|
17
20
|
groupedAccrualIds?: ID[];
|
|
18
21
|
groupedMembers?: ActualMatchingGroupedAccrual[];
|
|
22
|
+
matchShape?: string;
|
|
23
|
+
matchTier?: string;
|
|
19
24
|
reversalDate?: ZeniDate;
|
|
25
|
+
transactionDate?: string;
|
|
26
|
+
transactionType?: string;
|
|
20
27
|
}
|
|
21
28
|
export interface ActualMatchingKpiSummary {
|
|
22
29
|
ai: {
|
|
@@ -56,14 +63,20 @@ export interface ActualMatchingMatchModalView {
|
|
|
56
63
|
results: ActualMatchingTransactionSearchResult[];
|
|
57
64
|
};
|
|
58
65
|
lastBatchResults?: MatchAndReverseResult[];
|
|
66
|
+
openedFromMatchId?: string;
|
|
67
|
+
prefill?: {
|
|
68
|
+
selectedAccrualIds: ID[];
|
|
69
|
+
actualAmount?: number;
|
|
70
|
+
matchedLineId?: string;
|
|
71
|
+
matchedTransactionId?: string;
|
|
72
|
+
};
|
|
59
73
|
}
|
|
60
74
|
export interface ExpenseAutomationActualMatchingViewSelector extends SelectorView {
|
|
61
|
-
autoReversed: ActualMatchingRow[];
|
|
62
75
|
hasLoadedForSelectedPeriod: boolean;
|
|
63
76
|
kpiSummary: ActualMatchingKpiSummary;
|
|
64
|
-
manuallyReversed: ActualMatchingRow[];
|
|
65
77
|
matchModal: ActualMatchingMatchModalView;
|
|
66
78
|
pendingReview: ActualMatchingRow[];
|
|
67
79
|
refreshStatus: FetchStateAndError;
|
|
80
|
+
reversed: ActualMatchingRow[];
|
|
68
81
|
uiState: ActualMatchingViewUIState;
|
|
69
82
|
}
|
|
@@ -1,11 +1,25 @@
|
|
|
1
|
+
import { FetchStateAndError } from '../../../commonStateTypes/common';
|
|
2
|
+
import { ActualMatchingMatch } from '../../../entity/actualMatching/actualMatchingState';
|
|
3
|
+
import { ActualMatchingMatchId } from '../../../entity/actualMatching/actualMatchingTypes';
|
|
1
4
|
import { JEOneTimeAccrual } from '../../../entity/jeSchedules/jeSchedulesSelector';
|
|
2
5
|
import { RootState } from '../../../rootStateTypes';
|
|
3
6
|
import { ZeniDate } from '../../../zeniDayJS';
|
|
4
|
-
import { ExpenseAutomationActualMatchingViewSelector } from '../selectorTypes/actualMatchingViewSelectorTypes';
|
|
7
|
+
import { ActualMatchingRow, ActualMatchingRowKind, ExpenseAutomationActualMatchingViewSelector } from '../selectorTypes/actualMatchingViewSelectorTypes';
|
|
8
|
+
export declare function parseActualMatchingMatchId(matchId: string): {
|
|
9
|
+
transactionIntegrationId: string;
|
|
10
|
+
transactionType: string;
|
|
11
|
+
} | null;
|
|
5
12
|
export declare function isAutoReversedAccrual(accrual: JEOneTimeAccrual): boolean;
|
|
6
13
|
export declare function isManuallyReversedAccrual(accrual: JEOneTimeAccrual): boolean;
|
|
7
14
|
export declare function isPendingReviewAccrual(accrual: JEOneTimeAccrual): boolean;
|
|
15
|
+
export declare function isReversedMatchKind(kind: ActualMatchingRowKind): boolean;
|
|
8
16
|
export declare function getClearedMatchedAmount(accrual: JEOneTimeAccrual): number | undefined;
|
|
9
|
-
export declare function getActualMatchingAmount(
|
|
17
|
+
export declare function getActualMatchingAmount(row: ActualMatchingRow): number;
|
|
10
18
|
export declare function getActualMatchingReversalDate(accrual: JEOneTimeAccrual): ZeniDate | undefined;
|
|
19
|
+
export interface ExpenseAutomationActualMatchingMatchView {
|
|
20
|
+
detailFetchState: FetchStateAndError;
|
|
21
|
+
refreshStatus: FetchStateAndError;
|
|
22
|
+
match?: ActualMatchingMatch;
|
|
23
|
+
}
|
|
24
|
+
export declare function getExpenseAutomationActualMatchingMatchView(state: RootState, matchId: ActualMatchingMatchId): ExpenseAutomationActualMatchingMatchView;
|
|
11
25
|
export declare function getExpenseAutomationActualMatchingView(state: RootState): ExpenseAutomationActualMatchingViewSelector;
|
|
@@ -3,17 +3,66 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseActualMatchingMatchId = parseActualMatchingMatchId;
|
|
6
7
|
exports.isAutoReversedAccrual = isAutoReversedAccrual;
|
|
7
8
|
exports.isManuallyReversedAccrual = isManuallyReversedAccrual;
|
|
8
9
|
exports.isPendingReviewAccrual = isPendingReviewAccrual;
|
|
10
|
+
exports.isReversedMatchKind = isReversedMatchKind;
|
|
9
11
|
exports.getClearedMatchedAmount = getClearedMatchedAmount;
|
|
10
12
|
exports.getActualMatchingAmount = getActualMatchingAmount;
|
|
11
13
|
exports.getActualMatchingReversalDate = getActualMatchingReversalDate;
|
|
14
|
+
exports.getExpenseAutomationActualMatchingMatchView = getExpenseAutomationActualMatchingMatchView;
|
|
12
15
|
exports.getExpenseAutomationActualMatchingView = getExpenseAutomationActualMatchingView;
|
|
13
16
|
const orderBy_1 = __importDefault(require("lodash/orderBy"));
|
|
14
17
|
const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
|
|
18
|
+
const actualMatchingSelector_1 = require("../../../entity/actualMatching/actualMatchingSelector");
|
|
19
|
+
const jeScheduleHelper_1 = require("../../../entity/jeSchedules/jeScheduleHelper");
|
|
15
20
|
const jeSchedulesSelector_1 = require("../../../entity/jeSchedules/jeSchedulesSelector");
|
|
16
21
|
const tenantSelector_1 = require("../../../entity/tenant/tenantSelector");
|
|
22
|
+
function toMatchModalAccrual(member) {
|
|
23
|
+
if ('jeOneTimeAccrualKey' in member && member.jeOneTimeAccrualKey != null) {
|
|
24
|
+
return member;
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
...member,
|
|
28
|
+
jeOneTimeAccrualKey: (0, jeScheduleHelper_1.generateJEOneTimeAccrualKey)(member.accrualId),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function uniqueMatchModalAccruals(pinned, searched) {
|
|
32
|
+
const byId = new Map();
|
|
33
|
+
pinned.forEach((row) => byId.set(row.accrualId, row));
|
|
34
|
+
searched.forEach((row) => {
|
|
35
|
+
if (!byId.has(row.accrualId)) {
|
|
36
|
+
byId.set(row.accrualId, row);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
return Array.from(byId.values());
|
|
40
|
+
}
|
|
41
|
+
function uniqueTransactionSearchResults(pinned, searched) {
|
|
42
|
+
const byKey = new Map();
|
|
43
|
+
pinned.forEach((row) => byKey.set(`${row.transactionId}:${row.lineId}`, row));
|
|
44
|
+
searched.forEach((row) => {
|
|
45
|
+
const key = `${row.transactionId}:${row.lineId}`;
|
|
46
|
+
if (!byKey.has(key)) {
|
|
47
|
+
byKey.set(key, row);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return Array.from(byKey.values());
|
|
51
|
+
}
|
|
52
|
+
function parseActualMatchingMatchId(matchId) {
|
|
53
|
+
const separator = matchId.indexOf(':');
|
|
54
|
+
if (separator <= 0 || separator === matchId.length - 1) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
transactionType: matchId.slice(0, separator).toLowerCase(),
|
|
59
|
+
transactionIntegrationId: matchId.slice(separator + 1),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const NOT_STARTED = {
|
|
63
|
+
fetchState: 'Not-Started',
|
|
64
|
+
error: undefined,
|
|
65
|
+
};
|
|
17
66
|
function isAutoReversedAccrual(accrual) {
|
|
18
67
|
return (accrual.accrualStatus === 'reversed' &&
|
|
19
68
|
accrual.reversalTrigger === 'bill_match');
|
|
@@ -29,18 +78,14 @@ function isPendingReviewAccrual(accrual) {
|
|
|
29
78
|
const resolution = accrual.matchSuggestion.resolution;
|
|
30
79
|
return resolution == null || resolution.length === 0;
|
|
31
80
|
}
|
|
81
|
+
function isReversedMatchKind(kind) {
|
|
82
|
+
return kind === 'auto_reversed' || kind === 'manually_reversed';
|
|
83
|
+
}
|
|
32
84
|
function getClearedMatchedAmount(accrual) {
|
|
33
85
|
return accrual.cleared?.matchedAmount?.amount;
|
|
34
86
|
}
|
|
35
|
-
function getActualMatchingAmount(
|
|
36
|
-
|
|
37
|
-
return (accrual.matchSuggestion?.matchedAmount?.amount ??
|
|
38
|
-
accrual.estimatedAmount.amount);
|
|
39
|
-
}
|
|
40
|
-
if (isAutoReversedAccrual(accrual) || isManuallyReversedAccrual(accrual)) {
|
|
41
|
-
return getClearedMatchedAmount(accrual) ?? accrual.estimatedAmount.amount;
|
|
42
|
-
}
|
|
43
|
-
return accrual.estimatedAmount.amount;
|
|
87
|
+
function getActualMatchingAmount(row) {
|
|
88
|
+
return row.actualAmount?.amount ?? row.estimatedAmount.amount;
|
|
44
89
|
}
|
|
45
90
|
function getActualMatchingReversalDate(accrual) {
|
|
46
91
|
if (isPendingReviewAccrual(accrual)) {
|
|
@@ -48,40 +93,6 @@ function getActualMatchingReversalDate(accrual) {
|
|
|
48
93
|
}
|
|
49
94
|
return accrual.cleared?.matchedTransactionDate;
|
|
50
95
|
}
|
|
51
|
-
function getActualMatchingBillCollapseKey(accrual) {
|
|
52
|
-
const stamp = isPendingReviewAccrual(accrual)
|
|
53
|
-
? accrual.matchSuggestion
|
|
54
|
-
: accrual.cleared;
|
|
55
|
-
const txnId = stamp?.matchedTransactionId;
|
|
56
|
-
if (txnId != null && txnId !== '') {
|
|
57
|
-
return `txn:${txnId}`;
|
|
58
|
-
}
|
|
59
|
-
const integrationId = stamp?.matchedTransactionIntegrationId;
|
|
60
|
-
if (integrationId != null && integrationId !== '') {
|
|
61
|
-
return `int:${integrationId}`;
|
|
62
|
-
}
|
|
63
|
-
const ids = accrual.cleared?.accrualIds;
|
|
64
|
-
if (ids != null && ids.length > 1) {
|
|
65
|
-
return `cleared:${[...ids].sort().join(',')}`;
|
|
66
|
-
}
|
|
67
|
-
return `accrual:${accrual.accrualId}`;
|
|
68
|
-
}
|
|
69
|
-
function collectGroupedAccrualIds(members) {
|
|
70
|
-
const stampIds = members[0]?.cleared?.accrualIds;
|
|
71
|
-
const memberIds = members.map((member) => member.accrualId);
|
|
72
|
-
if (stampIds != null && stampIds.length >= memberIds.length) {
|
|
73
|
-
return stampIds;
|
|
74
|
-
}
|
|
75
|
-
const seen = new Set();
|
|
76
|
-
const grouped = [];
|
|
77
|
-
for (const id of [...(stampIds ?? []), ...memberIds]) {
|
|
78
|
-
if (!seen.has(id)) {
|
|
79
|
-
seen.add(id);
|
|
80
|
-
grouped.push(id);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return grouped;
|
|
84
|
-
}
|
|
85
96
|
function collectGroupedMembers(members) {
|
|
86
97
|
if (members.length <= 1) {
|
|
87
98
|
return undefined;
|
|
@@ -94,51 +105,48 @@ function collectGroupedMembers(members) {
|
|
|
94
105
|
serviceMonth: member.serviceMonth,
|
|
95
106
|
}));
|
|
96
107
|
}
|
|
97
|
-
function toActualMatchingRow(
|
|
98
|
-
const
|
|
108
|
+
function toActualMatchingRow(match) {
|
|
109
|
+
const firstMember = match.members[0];
|
|
110
|
+
if (firstMember == null) {
|
|
111
|
+
throw new Error('Actual matching row requires at least one member');
|
|
112
|
+
}
|
|
113
|
+
const first = toMatchModalAccrual(firstMember);
|
|
99
114
|
return {
|
|
100
|
-
...
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
115
|
+
...first,
|
|
116
|
+
matchId: match.matchId,
|
|
117
|
+
kind: match.kind,
|
|
118
|
+
accruedAmount: match.accruedAmount,
|
|
119
|
+
actualAmount: match.actualAmount,
|
|
120
|
+
matchTier: match.matchTier,
|
|
121
|
+
matchShape: match.matchShape,
|
|
122
|
+
transactionType: match.transactionType,
|
|
123
|
+
transactionDate: match.transactionDate,
|
|
124
|
+
groupedAccrualIds: match.members.map((member) => member.accrualId),
|
|
125
|
+
groupedMembers: collectGroupedMembers(match.members),
|
|
126
|
+
reversalDate: getActualMatchingReversalDate(first),
|
|
127
|
+
vendorName: match.vendorName !== '' ? match.vendorName : first.vendorName,
|
|
128
|
+
estimatedAmount: match.accruedAmount,
|
|
105
129
|
};
|
|
106
130
|
}
|
|
107
|
-
function
|
|
108
|
-
const groups = new Map();
|
|
109
|
-
for (const accrual of accruals) {
|
|
110
|
-
const key = getActualMatchingBillCollapseKey(accrual);
|
|
111
|
-
const members = groups.get(key);
|
|
112
|
-
if (members != null) {
|
|
113
|
-
members.push(accrual);
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
groups.set(key, [accrual]);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
const rows = [];
|
|
120
|
-
for (const members of groups.values()) {
|
|
121
|
-
rows.push(toActualMatchingRow(members, kind));
|
|
122
|
-
}
|
|
123
|
-
return rows;
|
|
124
|
-
}
|
|
125
|
-
function sumCollapsedActualMatchingAmounts(rows) {
|
|
126
|
-
return rows.reduce((sum, row) => sum + getActualMatchingAmount(row), 0);
|
|
127
|
-
}
|
|
128
|
-
function matchesSearch(accrual, searchString) {
|
|
131
|
+
function matchesSearch(row, searchString) {
|
|
129
132
|
const trimmed = searchString.trim().toLowerCase();
|
|
130
133
|
if (trimmed.length === 0) {
|
|
131
134
|
return true;
|
|
132
135
|
}
|
|
133
|
-
|
|
134
|
-
|
|
136
|
+
if (row.vendorName.toLowerCase().includes(trimmed)) {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
if (row.memo.toLowerCase().includes(trimmed)) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
return (row.groupedMembers ?? []).some((member) => (member.memo ?? '').toLowerCase().includes(trimmed));
|
|
135
143
|
}
|
|
136
144
|
function getActualMatchingSortValue(row, sortKey) {
|
|
137
145
|
switch (sortKey) {
|
|
138
146
|
case 'vendor':
|
|
139
147
|
return row.vendorName.toLowerCase();
|
|
140
148
|
case 'date':
|
|
141
|
-
return row.reversalDate?.valueOf();
|
|
149
|
+
return row.reversalDate?.valueOf() ?? row.transactionDate;
|
|
142
150
|
case 'amount':
|
|
143
151
|
return getActualMatchingAmount(row);
|
|
144
152
|
case 'category':
|
|
@@ -146,10 +154,23 @@ function getActualMatchingSortValue(row, sortKey) {
|
|
|
146
154
|
case 'class':
|
|
147
155
|
return row.jeDebitAccountingClassName?.toLowerCase();
|
|
148
156
|
case 'type':
|
|
149
|
-
return
|
|
150
|
-
row.matchSuggestion?.matchedTransactionType)?.toLowerCase();
|
|
157
|
+
return row.transactionType?.toLowerCase();
|
|
151
158
|
case 'lifecycle':
|
|
152
159
|
return row.kind;
|
|
160
|
+
case 'service':
|
|
161
|
+
return row.serviceMonth;
|
|
162
|
+
case 'accrued':
|
|
163
|
+
return row.accruedAmount?.amount ?? row.estimatedAmount.amount;
|
|
164
|
+
case 'actual':
|
|
165
|
+
return row.actualAmount?.amount;
|
|
166
|
+
case 'variance': {
|
|
167
|
+
const accrued = row.accruedAmount?.amount ?? row.estimatedAmount.amount;
|
|
168
|
+
const actual = row.actualAmount?.amount;
|
|
169
|
+
if (actual == null || accrued === 0) {
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
172
|
+
return ((actual - accrued) / Math.abs(accrued)) * 100;
|
|
173
|
+
}
|
|
153
174
|
default:
|
|
154
175
|
return undefined;
|
|
155
176
|
}
|
|
@@ -167,37 +188,50 @@ function emptyKpiSummary() {
|
|
|
167
188
|
manual: { count: 0 },
|
|
168
189
|
};
|
|
169
190
|
}
|
|
191
|
+
function sumRowAmounts(rows) {
|
|
192
|
+
return rows.reduce((sum, row) => sum + getActualMatchingAmount(row), 0);
|
|
193
|
+
}
|
|
194
|
+
function getExpenseAutomationActualMatchingMatchView(state, matchId) {
|
|
195
|
+
const view = state.expenseAutomationActualMatchingViewState;
|
|
196
|
+
return {
|
|
197
|
+
match: (0, actualMatchingSelector_1.getActualMatchingMatchById)(matchId, state.actualMatchingState),
|
|
198
|
+
detailFetchState: view.detailFetchStateByMatchId[matchId] ?? NOT_STARTED,
|
|
199
|
+
refreshStatus: view.detailRefreshStatusByMatchId[matchId] ?? NOT_STARTED,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
170
202
|
function getExpenseAutomationActualMatchingView(state) {
|
|
171
203
|
const { expenseAutomationActualMatchingViewState, expenseAutomationViewState } = state;
|
|
172
|
-
const {
|
|
204
|
+
const { matchIdsByPeriod, fetchState, error, refreshStatus, uiState, matchModal, } = expenseAutomationActualMatchingViewState;
|
|
173
205
|
const currentTenant = (0, tenantSelector_1.getCurrentTenant)(state);
|
|
174
206
|
const selectedPeriod = expenseAutomationViewState.selectedPeriodByTenantId[currentTenant.tenantId];
|
|
175
207
|
const monthYearPeriodId = selectedPeriod != null ? (0, timePeriod_1.toMonthYearPeriodId)(selectedPeriod) : undefined;
|
|
176
|
-
const
|
|
177
|
-
?
|
|
208
|
+
const matchIds = monthYearPeriodId != null
|
|
209
|
+
? matchIdsByPeriod[monthYearPeriodId]
|
|
178
210
|
: undefined;
|
|
179
|
-
const
|
|
180
|
-
.map((
|
|
181
|
-
.filter((
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
const
|
|
211
|
+
const rows = (matchIds ?? [])
|
|
212
|
+
.map((matchId) => (0, actualMatchingSelector_1.getActualMatchingMatchById)(matchId, state.actualMatchingState))
|
|
213
|
+
.filter((match) => match != null)
|
|
214
|
+
.filter((match) => match.members.length > 0)
|
|
215
|
+
.map(toActualMatchingRow)
|
|
216
|
+
.filter((row) => matchesSearch(row, uiState.searchString));
|
|
217
|
+
const reversed = sortActualMatchingRows(rows.filter((row) => isReversedMatchKind(row.kind)), uiState);
|
|
218
|
+
const pendingReview = sortActualMatchingRows(rows.filter((row) => row.kind === 'pending_review'), uiState);
|
|
219
|
+
const autoReversedForKpi = reversed.filter((row) => row.kind === 'auto_reversed');
|
|
220
|
+
const listedRows = [...reversed, ...pendingReview];
|
|
187
221
|
const kpiSummary = listedRows.length === 0
|
|
188
222
|
? emptyKpiSummary()
|
|
189
223
|
: {
|
|
190
224
|
autoReversed: {
|
|
191
|
-
count:
|
|
192
|
-
amount:
|
|
225
|
+
count: autoReversedForKpi.length,
|
|
226
|
+
amount: sumRowAmounts(autoReversedForKpi),
|
|
193
227
|
},
|
|
194
228
|
pendingReview: {
|
|
195
229
|
count: pendingReview.length,
|
|
196
|
-
amount:
|
|
230
|
+
amount: sumRowAmounts(pendingReview),
|
|
197
231
|
},
|
|
198
232
|
totalThisClose: {
|
|
199
233
|
count: listedRows.length,
|
|
200
|
-
amount:
|
|
234
|
+
amount: sumRowAmounts(listedRows),
|
|
201
235
|
},
|
|
202
236
|
ai: {
|
|
203
237
|
count: listedRows.filter((row) => row.origin === 'agent').length,
|
|
@@ -206,26 +240,40 @@ function getExpenseAutomationActualMatchingView(state) {
|
|
|
206
240
|
count: listedRows.filter((row) => row.origin === 'human').length,
|
|
207
241
|
},
|
|
208
242
|
};
|
|
209
|
-
const
|
|
243
|
+
const searchedAccruals = matchModal.accrualSearch.results
|
|
210
244
|
.map((key) => (0, jeSchedulesSelector_1.getJEOneTimeAccrualByKey)(key, state.jeSchedulesState))
|
|
211
245
|
.filter((accrual) => accrual != null);
|
|
246
|
+
const openedMatch = matchModal.openedFromMatchId != null
|
|
247
|
+
? (0, actualMatchingSelector_1.getActualMatchingMatchById)(matchModal.openedFromMatchId, state.actualMatchingState)
|
|
248
|
+
: undefined;
|
|
249
|
+
const pinnedAccruals = (openedMatch?.members ?? []).map(toMatchModalAccrual);
|
|
250
|
+
const firstSuggestion = openedMatch?.members[0]?.matchSuggestion;
|
|
251
|
+
const prefill = openedMatch == null
|
|
252
|
+
? undefined
|
|
253
|
+
: {
|
|
254
|
+
selectedAccrualIds: openedMatch.members.map((member) => member.accrualId),
|
|
255
|
+
actualAmount: openedMatch.actualAmount.amount,
|
|
256
|
+
matchedLineId: firstSuggestion?.matchedLineId,
|
|
257
|
+
matchedTransactionId: firstSuggestion?.matchedTransactionId,
|
|
258
|
+
};
|
|
212
259
|
return {
|
|
213
260
|
fetchState,
|
|
214
261
|
error,
|
|
215
|
-
|
|
262
|
+
reversed,
|
|
216
263
|
pendingReview,
|
|
217
|
-
manuallyReversed,
|
|
218
264
|
kpiSummary,
|
|
219
265
|
uiState,
|
|
220
266
|
refreshStatus,
|
|
221
|
-
hasLoadedForSelectedPeriod:
|
|
267
|
+
hasLoadedForSelectedPeriod: matchIds != null,
|
|
222
268
|
matchModal: {
|
|
223
269
|
isOpen: matchModal.isOpen,
|
|
270
|
+
openedFromMatchId: matchModal.openedFromMatchId,
|
|
271
|
+
prefill,
|
|
224
272
|
confirmStatus: matchModal.confirmStatus,
|
|
225
273
|
lastBatchResults: matchModal.lastBatchResults,
|
|
226
274
|
transactionSearch: {
|
|
227
275
|
query: matchModal.transactionSearch.query,
|
|
228
|
-
results: matchModal.transactionSearch.results,
|
|
276
|
+
results: uniqueTransactionSearchResults(matchModal.pinnedTransactionResults, matchModal.transactionSearch.results),
|
|
229
277
|
fetchState: {
|
|
230
278
|
fetchState: matchModal.transactionSearch.fetchState,
|
|
231
279
|
error: matchModal.transactionSearch.error,
|
|
@@ -235,7 +283,7 @@ function getExpenseAutomationActualMatchingView(state) {
|
|
|
235
283
|
},
|
|
236
284
|
accrualSearch: {
|
|
237
285
|
query: matchModal.accrualSearch.query,
|
|
238
|
-
results:
|
|
286
|
+
results: uniqueMatchModalAccruals(pinnedAccruals, searchedAccruals),
|
|
239
287
|
fetchState: {
|
|
240
288
|
fetchState: matchModal.accrualSearch.fetchState,
|
|
241
289
|
error: matchModal.accrualSearch.error,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { FetchStateAndError, FetchedState, ID } from '../../../commonStateTypes/common';
|
|
2
2
|
import { SortOrder } from '../../../commonStateTypes/selectorTypes/sortOrderTypes';
|
|
3
3
|
import { MonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
|
|
4
|
+
import { ActualMatchingMatchId } from '../../../entity/actualMatching/actualMatchingTypes';
|
|
4
5
|
import { JEOneTimeAccrualKey } from '../../../entity/jeSchedules/jeSchedulesTypes';
|
|
5
|
-
export declare const toActualMatchingSortKey: (v: string) => "type" | "date" | "vendor" | "category" | "class" | "amount" | "lifecycle";
|
|
6
|
+
export declare const toActualMatchingSortKey: (v: string) => "type" | "date" | "vendor" | "category" | "class" | "amount" | "variance" | "lifecycle" | "service" | "accrued" | "actual";
|
|
6
7
|
export type ActualMatchingSortKey = ReturnType<typeof toActualMatchingSortKey>;
|
|
7
8
|
export declare const MATCH_TRANSACTION_SEARCH_PAGE_SIZE = 50;
|
|
8
9
|
export declare const MATCH_ACCRUAL_SEARCH_LIMIT = 50;
|
|
@@ -70,11 +71,15 @@ export interface ActualMatchingMatchModalState {
|
|
|
70
71
|
accrualSearch: ActualMatchingAccrualSearchState;
|
|
71
72
|
confirmStatus: FetchStateAndError;
|
|
72
73
|
isOpen: boolean;
|
|
74
|
+
pinnedTransactionResults: ActualMatchingTransactionSearchResult[];
|
|
73
75
|
transactionSearch: ActualMatchingTransactionSearchState;
|
|
74
76
|
lastBatchResults?: MatchAndReverseResult[];
|
|
77
|
+
openedFromMatchId?: ActualMatchingMatchId;
|
|
75
78
|
}
|
|
76
79
|
export interface ActualMatchingViewState extends FetchedState {
|
|
77
|
-
|
|
80
|
+
detailFetchStateByMatchId: Record<ActualMatchingMatchId, FetchStateAndError>;
|
|
81
|
+
detailRefreshStatusByMatchId: Record<ActualMatchingMatchId, FetchStateAndError>;
|
|
82
|
+
matchIdsByPeriod: Record<MonthYearPeriodId, ActualMatchingMatchId[]>;
|
|
78
83
|
matchModal: ActualMatchingMatchModalState;
|
|
79
84
|
refreshStatus: FetchStateAndError;
|
|
80
85
|
uiState: ActualMatchingViewUIState;
|
|
@@ -10,6 +10,10 @@ const ACTUAL_MATCHING_SORT_KEYS = [
|
|
|
10
10
|
'class',
|
|
11
11
|
'type',
|
|
12
12
|
'lifecycle',
|
|
13
|
+
'service',
|
|
14
|
+
'accrued',
|
|
15
|
+
'actual',
|
|
16
|
+
'variance',
|
|
13
17
|
];
|
|
14
18
|
const toActualMatchingSortKey = (v) => (0, stringToUnion_1.stringToUnion)(v, ACTUAL_MATCHING_SORT_KEYS);
|
|
15
19
|
exports.toActualMatchingSortKey = toActualMatchingSortKey;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeniai/client-epic-state",
|
|
3
|
-
"version": "5.2.22-
|
|
3
|
+
"version": "5.2.22-betaAM5",
|
|
4
4
|
"description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/esm/index.js",
|