@zeniai/client-epic-state 4.19.37-betaVR19 → 4.19.37-betaVR2
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/epic.d.ts +1 -2
- package/lib/epic.js +1 -2
- package/lib/esm/epic.js +1 -2
- package/lib/esm/index.js +2 -2
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.js +8 -4
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchDetailsEpic.js +2 -2
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js +1 -6
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +3 -7
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.js +15 -24
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +32 -32
- package/lib/esm/view/expenseAutomationView/payload/missingReceiptsPayload.js +12 -15
- package/lib/esm/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +13 -73
- package/lib/esm/view/expenseAutomationView/selectors/missingReceiptsSelector.js +12 -99
- package/lib/index.d.ts +2 -2
- package/lib/index.js +32 -36
- package/lib/tsconfig.typecheck.tsbuildinfo +1 -0
- package/lib/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.d.ts +5 -2
- package/lib/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.js +7 -3
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchDetailsEpic.js +2 -2
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js +1 -6
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +2 -6
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.d.ts +2 -3
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.js +12 -25
- package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.d.ts +7 -5
- package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +28 -28
- package/lib/view/expenseAutomationView/payload/missingReceiptsPayload.d.ts +16 -15
- package/lib/view/expenseAutomationView/payload/missingReceiptsPayload.js +13 -16
- package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +3 -12
- package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +14 -75
- package/lib/view/expenseAutomationView/selectorTypes/missingReceiptsSelectorTypes.d.ts +1 -7
- package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.js +12 -99
- package/lib/view/expenseAutomationView/types/missingReceiptsViewState.d.ts +2 -10
- package/package.json +2 -2
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchMoreBatchDetailsEpic.js +0 -36
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMoreBatchDetailsEpic.d.ts +0 -8
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMoreBatchDetailsEpic.js +0 -43
package/lib/esm/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { catchError,
|
|
3
|
-
import { updateTransactions } from '../../../../entity/transaction/transactionReducer';
|
|
1
|
+
import { of, timer } from 'rxjs';
|
|
2
|
+
import { catchError, filter, mergeMap, switchMap, takeUntil, takeWhile, } from 'rxjs/operators';
|
|
4
3
|
import { isSuccessResponse } from '../../../../responsePayload';
|
|
5
|
-
import {
|
|
6
|
-
import { bulkUploadReceiptsSuccess, clearBulkUpload,
|
|
7
|
-
/** First poll after upload; then interval while batch not resolved via Pusher or API. */
|
|
8
|
-
const FALLBACK_FIRST_DELAY_MS = 30000;
|
|
9
|
-
const FALLBACK_POLL_INTERVAL_MS = 10000;
|
|
10
|
-
function isBatchDetailsCompletedStatus(status) {
|
|
11
|
-
return status.toLowerCase() === 'completed';
|
|
12
|
-
}
|
|
4
|
+
import { toBatchStatus, } from '../../payload/missingReceiptsPayload';
|
|
5
|
+
import { bulkUploadReceiptsSuccess, clearBulkUpload, fetchBulkUploadBatchDetails, pusherBatchStatusUpdate, updateBulkUploadBatchStatus, } from '../../reducers/missingReceiptsViewReducer';
|
|
13
6
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
7
|
+
* Watches batch status using two strategies:
|
|
8
|
+
* 1. Pusher (primary): Reacts to `pusherBatchStatusUpdate` dispatched by the UI layer
|
|
9
|
+
* when a Pusher event arrives. Immediately fetches full details on completion.
|
|
10
|
+
* 2. Polling (fallback): Starts a relaxed 10s poll after upload success as a safety net
|
|
11
|
+
* in case the Pusher event is missed. Stops on completion or `clearBulkUpload`.
|
|
16
12
|
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
export const pollBulkUploadBatchStatusEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(bulkUploadReceiptsSuccess.match),
|
|
13
|
+
// Pusher-driven: when Pusher delivers a completed status, fetch details
|
|
14
|
+
export const pusherBatchStatusCompletionEpic = (actions$) => actions$.pipe(filter(pusherBatchStatusUpdate.match), filter((action) => action.payload.status === 'completed'), mergeMap(() => of(fetchBulkUploadBatchDetails())));
|
|
15
|
+
// Polling fallback: relaxed interval as safety net
|
|
16
|
+
const FALLBACK_POLL_INTERVAL_MS = 10000;
|
|
17
|
+
export const pollBulkUploadBatchStatusEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(bulkUploadReceiptsSuccess.match), switchMap((action) => {
|
|
22
18
|
const { batchId } = action.payload;
|
|
23
|
-
return timer(
|
|
24
|
-
.
|
|
19
|
+
return timer(0, FALLBACK_POLL_INTERVAL_MS).pipe(takeUntil(actions$.pipe(filter((a) => clearBulkUpload.match(a) ||
|
|
20
|
+
(pusherBatchStatusUpdate.match(a) &&
|
|
21
|
+
a.payload.status === 'completed')))), switchMap(() => zeniAPI
|
|
22
|
+
.getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/receipts/batches/${batchId}/status`)
|
|
25
23
|
.pipe(mergeMap((response) => {
|
|
26
24
|
if (isSuccessResponse(response) && response.data != null) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
actions.push(fetchBulkUploadBatchDetailsSuccess(toBatchDetails(response.data, zeniAPI.apiEndPoints.fileMicroServiceBaseUrl)));
|
|
34
|
-
actions.push(fetchBulkUploadBatches(true));
|
|
35
|
-
actions.push(requestMissingReceiptsTabNavigation({ tab: 'unmatched' }));
|
|
36
|
-
return from(actions);
|
|
25
|
+
const batchStatus = toBatchStatus(response.data);
|
|
26
|
+
const actions = [
|
|
27
|
+
updateBulkUploadBatchStatus(batchStatus),
|
|
28
|
+
];
|
|
29
|
+
if (batchStatus.status === 'completed') {
|
|
30
|
+
actions.push(fetchBulkUploadBatchDetails());
|
|
37
31
|
}
|
|
32
|
+
return actions;
|
|
33
|
+
}
|
|
34
|
+
return [];
|
|
35
|
+
}), catchError(() => of()))), takeWhile((action) => {
|
|
36
|
+
if (fetchBulkUploadBatchDetails.match(action)) {
|
|
37
|
+
return false;
|
|
38
38
|
}
|
|
39
|
-
return
|
|
40
|
-
}
|
|
39
|
+
return true;
|
|
40
|
+
}, true));
|
|
41
41
|
}));
|
|
@@ -1,19 +1,14 @@
|
|
|
1
|
-
import { toURL } from '../../../commonPayloadTypes/urlPayload';
|
|
2
1
|
// -- Converter functions --
|
|
3
|
-
export function toBatchFile(payload
|
|
2
|
+
export function toBatchFile(payload) {
|
|
4
3
|
return {
|
|
5
4
|
attachmentId: payload.attachment_id,
|
|
6
5
|
candidates: payload.candidates?.map((c) => ({
|
|
7
6
|
transactionId: c.transaction_id,
|
|
8
7
|
matchScore: c.match_score,
|
|
9
8
|
})),
|
|
10
|
-
fileDownloadUrl: payload.file_id != null && filesEndPoint != null
|
|
11
|
-
? `${filesEndPoint}/1.0/files/${payload.file_id}?query=${encodeURIComponent(JSON.stringify({ download_file: true }))}`
|
|
12
|
-
: null,
|
|
13
9
|
fileId: payload.file_id,
|
|
14
10
|
filePreviewUrl: payload.file_preview_url,
|
|
15
11
|
filename: payload.filename,
|
|
16
|
-
matchSource: payload.match_source,
|
|
17
12
|
matchedTransactionId: payload.matched_transaction?.transaction_id,
|
|
18
13
|
status: payload.status,
|
|
19
14
|
};
|
|
@@ -44,12 +39,11 @@ export function extractTransactionPayloadsFromBatchFiles(files) {
|
|
|
44
39
|
function matchedTransactionPayloadToSupportedTransactionPayload(payload) {
|
|
45
40
|
return {
|
|
46
41
|
transaction_id: payload.transaction_id,
|
|
47
|
-
transaction_type: payload.transaction_type
|
|
48
|
-
transaction_date: payload.transaction_date
|
|
42
|
+
transaction_type: payload.transaction_type,
|
|
43
|
+
transaction_date: payload.transaction_date,
|
|
49
44
|
currency_code: payload.currency_code,
|
|
50
45
|
total_amount: payload.amount,
|
|
51
46
|
vendor_name: payload.vendor_name,
|
|
52
|
-
logo: payload.vendor_logo == null ? undefined : toURL(payload.vendor_logo),
|
|
53
47
|
};
|
|
54
48
|
}
|
|
55
49
|
export function toBatchSummary(payload) {
|
|
@@ -61,19 +55,22 @@ export function toBatchSummary(payload) {
|
|
|
61
55
|
total: payload.total,
|
|
62
56
|
};
|
|
63
57
|
}
|
|
64
|
-
export function
|
|
58
|
+
export function toBatchStatus(payload) {
|
|
59
|
+
return {
|
|
60
|
+
batchId: payload.batch_id,
|
|
61
|
+
progress: payload.progress,
|
|
62
|
+
status: payload.status,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function toBatchDetails(payload) {
|
|
65
66
|
return {
|
|
66
67
|
batchId: payload.batch_id,
|
|
67
68
|
createdAt: payload.created_at,
|
|
68
|
-
files: payload.files.map(
|
|
69
|
+
files: payload.files.map(toBatchFile),
|
|
69
70
|
status: payload.status,
|
|
70
71
|
summary: toBatchSummary(payload.summary),
|
|
71
72
|
};
|
|
72
73
|
}
|
|
73
|
-
/** Batch list `status` is a string from the API — compare case-insensitively. */
|
|
74
|
-
export function isBatchListStatusCompleted(status) {
|
|
75
|
-
return status.toLowerCase() === 'completed';
|
|
76
|
-
}
|
|
77
74
|
export function toBatchListItem(payload) {
|
|
78
75
|
return {
|
|
79
76
|
batchId: payload.batch_id,
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
2
|
import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
|
|
3
|
-
export const getCompletedTransactionsCacheKey = (periodId, sortKey, sortOrder, subTab) => `completed-${subTab}-${sortKey}-${sortOrder === 'ascending' ? 'asc' : 'desc'}-${periodId}`;
|
|
4
3
|
export const initialBulkUploadState = {
|
|
5
4
|
batchDetailsById: {},
|
|
6
|
-
batchDetailsPaginationState: { fetchState: 'Not-Started', error: undefined },
|
|
7
5
|
batchListByPeriod: {},
|
|
8
6
|
batchListFetchState: { fetchState: 'Not-Started', error: undefined },
|
|
9
7
|
batchStatusById: {},
|
|
@@ -12,7 +10,6 @@ export const initialBulkUploadState = {
|
|
|
12
10
|
confirmMatchStatus: { fetchState: 'Not-Started', error: undefined },
|
|
13
11
|
currentBatchId: undefined,
|
|
14
12
|
currentResultsTab: 'unmatched',
|
|
15
|
-
failedBatchDetailIds: [],
|
|
16
13
|
manualSearch: {
|
|
17
14
|
fetchState: { fetchState: 'Not-Started', error: undefined },
|
|
18
15
|
results: [],
|
|
@@ -26,7 +23,6 @@ export const initialBulkUploadState = {
|
|
|
26
23
|
};
|
|
27
24
|
export const initialState = {
|
|
28
25
|
bulkUpload: initialBulkUploadState,
|
|
29
|
-
pendingMissingReceiptsTabNavigation: null,
|
|
30
26
|
uploadReceiptStatusById: {},
|
|
31
27
|
refreshStatus: {
|
|
32
28
|
fetchState: 'Not-Started',
|
|
@@ -179,15 +175,13 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
179
175
|
};
|
|
180
176
|
draft.bulkUpload.phase = 'idle';
|
|
181
177
|
},
|
|
182
|
-
|
|
178
|
+
updateBulkUploadBatchStatus(draft, action) {
|
|
183
179
|
const batchStatus = action.payload;
|
|
184
180
|
draft.bulkUpload.batchStatusById[batchStatus.batchId] = batchStatus;
|
|
185
181
|
},
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
clearMissingReceiptsTabNavigation(draft) {
|
|
190
|
-
draft.pendingMissingReceiptsTabNavigation = null;
|
|
182
|
+
pusherBatchStatusUpdate(draft, action) {
|
|
183
|
+
const batchStatus = action.payload;
|
|
184
|
+
draft.bulkUpload.batchStatusById[batchStatus.batchId] = batchStatus;
|
|
191
185
|
},
|
|
192
186
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
193
187
|
fetchBulkUploadBatchDetails(_draft) {
|
|
@@ -205,58 +199,6 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
205
199
|
storeBatchDetails(draft, action) {
|
|
206
200
|
const details = action.payload;
|
|
207
201
|
draft.bulkUpload.batchDetailsById[details.batchId] = details;
|
|
208
|
-
/**
|
|
209
|
-
* Multi-batch fetch paths use `storeBatchDetails` (not `fetchBulkUploadBatchDetailsSuccess`).
|
|
210
|
-
* Without this, `phase` stays `matching` after upload forever and the Unmatched tab keeps
|
|
211
|
-
* showing the skeleton (`bulkUploadPhase === 'matching'` in web-components).
|
|
212
|
-
*/
|
|
213
|
-
if (draft.bulkUpload.phase === 'matching' &&
|
|
214
|
-
draft.bulkUpload.currentBatchId === details.batchId) {
|
|
215
|
-
draft.bulkUpload.phase = 'completed';
|
|
216
|
-
}
|
|
217
|
-
},
|
|
218
|
-
batchDetailFetchFailed(draft, action) {
|
|
219
|
-
const { batchId } = action.payload;
|
|
220
|
-
if (!draft.bulkUpload.failedBatchDetailIds.includes(batchId)) {
|
|
221
|
-
draft.bulkUpload.failedBatchDetailIds.push(batchId);
|
|
222
|
-
}
|
|
223
|
-
if (draft.bulkUpload.phase === 'matching' &&
|
|
224
|
-
draft.bulkUpload.currentBatchId === batchId) {
|
|
225
|
-
draft.bulkUpload.phase = 'completed';
|
|
226
|
-
}
|
|
227
|
-
},
|
|
228
|
-
setInitialBatchDetailsLoading(draft) {
|
|
229
|
-
draft.bulkUpload.batchDetailsPaginationState = {
|
|
230
|
-
fetchState: 'In-Progress',
|
|
231
|
-
error: undefined,
|
|
232
|
-
};
|
|
233
|
-
},
|
|
234
|
-
fetchMoreBatchDetails(_draft) {
|
|
235
|
-
_draft.bulkUpload.batchDetailsPaginationState = {
|
|
236
|
-
fetchState: 'In-Progress',
|
|
237
|
-
error: undefined,
|
|
238
|
-
};
|
|
239
|
-
},
|
|
240
|
-
fetchMoreBatchDetailsComplete(draft) {
|
|
241
|
-
draft.bulkUpload.batchDetailsPaginationState = {
|
|
242
|
-
fetchState: 'Completed',
|
|
243
|
-
error: undefined,
|
|
244
|
-
};
|
|
245
|
-
const currentId = draft.bulkUpload.currentBatchId;
|
|
246
|
-
const currentDetails = currentId != null
|
|
247
|
-
? draft.bulkUpload.batchDetailsById[currentId]
|
|
248
|
-
: undefined;
|
|
249
|
-
if (draft.bulkUpload.phase === 'matching' &&
|
|
250
|
-
currentId != null &&
|
|
251
|
-
currentDetails?.status === 'completed') {
|
|
252
|
-
draft.bulkUpload.phase = 'completed';
|
|
253
|
-
}
|
|
254
|
-
},
|
|
255
|
-
fetchMoreBatchDetailsFailure(draft, action) {
|
|
256
|
-
draft.bulkUpload.batchDetailsPaginationState = {
|
|
257
|
-
fetchState: 'Error',
|
|
258
|
-
error: action.payload.error,
|
|
259
|
-
};
|
|
260
202
|
},
|
|
261
203
|
fetchBulkUploadBatches: {
|
|
262
204
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -331,6 +273,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
331
273
|
},
|
|
332
274
|
setBulkUploadCompletedSubTab(draft, action) {
|
|
333
275
|
draft.bulkUpload.completedSubTab = action.payload;
|
|
276
|
+
draft.bulkUpload.completedTransactionsByPeriod = {};
|
|
334
277
|
},
|
|
335
278
|
setBulkUploadSortConfig(draft, action) {
|
|
336
279
|
draft.bulkUpload.sortKey = action.payload.sortKey;
|
|
@@ -338,7 +281,6 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
338
281
|
},
|
|
339
282
|
clearBulkUpload(draft) {
|
|
340
283
|
Object.assign(draft.bulkUpload, initialBulkUploadState);
|
|
341
|
-
draft.pendingMissingReceiptsTabNavigation = null;
|
|
342
284
|
},
|
|
343
285
|
searchTransactionsForManualMatch: {
|
|
344
286
|
reducer(draft, action) {
|
|
@@ -386,16 +328,15 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
386
328
|
}
|
|
387
329
|
}
|
|
388
330
|
},
|
|
389
|
-
prepare(pageToken
|
|
390
|
-
return { payload: { pageToken
|
|
331
|
+
prepare(pageToken) {
|
|
332
|
+
return { payload: { pageToken } };
|
|
391
333
|
},
|
|
392
334
|
},
|
|
393
335
|
fetchCompletedTransactionsSuccess(draft, action) {
|
|
394
336
|
const { transactionIds, nextPageToken, totalCount, selectedPeriod, isInitialLoad } = action.payload;
|
|
395
337
|
const periodId = toMonthYearPeriodId(selectedPeriod);
|
|
396
|
-
const cacheKey = getCompletedTransactionsCacheKey(periodId, draft.bulkUpload.sortKey, draft.bulkUpload.sortOrder, draft.bulkUpload.completedSubTab);
|
|
397
338
|
if (isInitialLoad) {
|
|
398
|
-
draft.bulkUpload.completedTransactionsByPeriod[
|
|
339
|
+
draft.bulkUpload.completedTransactionsByPeriod[periodId] = {
|
|
399
340
|
transactionIds,
|
|
400
341
|
nextPageToken,
|
|
401
342
|
totalCount,
|
|
@@ -403,7 +344,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
403
344
|
};
|
|
404
345
|
}
|
|
405
346
|
else {
|
|
406
|
-
const existing = draft.bulkUpload.completedTransactionsByPeriod[
|
|
347
|
+
const existing = draft.bulkUpload.completedTransactionsByPeriod[periodId];
|
|
407
348
|
if (existing != null) {
|
|
408
349
|
existing.transactionIds.push(...transactionIds);
|
|
409
350
|
existing.nextPageToken = nextPageToken;
|
|
@@ -411,7 +352,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
411
352
|
existing.fetchState = { fetchState: 'Completed', error: undefined };
|
|
412
353
|
}
|
|
413
354
|
else {
|
|
414
|
-
draft.bulkUpload.completedTransactionsByPeriod[
|
|
355
|
+
draft.bulkUpload.completedTransactionsByPeriod[periodId] = {
|
|
415
356
|
transactionIds,
|
|
416
357
|
nextPageToken,
|
|
417
358
|
totalCount,
|
|
@@ -422,8 +363,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
422
363
|
},
|
|
423
364
|
fetchCompletedTransactionsFailure(draft, action) {
|
|
424
365
|
const periodId = toMonthYearPeriodId(action.payload.selectedPeriod);
|
|
425
|
-
const
|
|
426
|
-
const existing = draft.bulkUpload.completedTransactionsByPeriod[cacheKey];
|
|
366
|
+
const existing = draft.bulkUpload.completedTransactionsByPeriod[periodId];
|
|
427
367
|
if (existing != null) {
|
|
428
368
|
existing.fetchState = {
|
|
429
369
|
fetchState: 'Error',
|
|
@@ -431,7 +371,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
431
371
|
};
|
|
432
372
|
}
|
|
433
373
|
else {
|
|
434
|
-
draft.bulkUpload.completedTransactionsByPeriod[
|
|
374
|
+
draft.bulkUpload.completedTransactionsByPeriod[periodId] = {
|
|
435
375
|
fetchState: { fetchState: 'Error', error: action.payload.error },
|
|
436
376
|
nextPageToken: null,
|
|
437
377
|
totalCount: 0,
|
|
@@ -443,7 +383,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
443
383
|
});
|
|
444
384
|
export const { fetchMissingReceipts, fetchMissingReceiptsSuccess, fetchMissingReceiptsFailure, uploadMissingReceiptSuccess, updateMissingReceiptUploadState, updateMissingReceiptsUIState, markMissingReceiptAsDone, clearExpenseAutomationMissingReceiptsView,
|
|
445
385
|
// Bulk Upload
|
|
446
|
-
bulkUploadReceipts, updateBulkUploadProgress, bulkUploadReceiptsSuccess, bulkUploadReceiptsFailure,
|
|
386
|
+
bulkUploadReceipts, updateBulkUploadProgress, bulkUploadReceiptsSuccess, bulkUploadReceiptsFailure, updateBulkUploadBatchStatus, pusherBatchStatusUpdate, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatchDetailsFailure, storeBatchDetails, fetchBulkUploadBatches, fetchBulkUploadBatchesSuccess, fetchBulkUploadBatchesFailure, confirmBulkUploadMatch, confirmBulkUploadMatchSuccess, confirmBulkUploadMatchFailure, setBulkUploadResultsTab, setBulkUploadCompletedSubTab, setBulkUploadSortConfig, clearBulkUpload, searchTransactionsForManualMatch, searchTransactionsForManualMatchSuccess, searchTransactionsForManualMatchFailure, clearManualSearchResults,
|
|
447
387
|
// Completed Transactions
|
|
448
388
|
fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, } = expenseAutomationMissingReceiptsView.actions;
|
|
449
389
|
export default expenseAutomationMissingReceiptsView.reducer;
|
|
@@ -3,8 +3,6 @@ import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
|
|
|
3
3
|
import { getCurrentTenant } from '../../../entity/tenant/tenantSelector';
|
|
4
4
|
import { getSupportedTransactionById, getSupportedTransactionsByIds, } from '../../../entity/transaction/transactionSelector';
|
|
5
5
|
import { getAllSteps } from '../selectorTypes/expenseAutomationViewSelectorTypes';
|
|
6
|
-
import { isBatchListStatusCompleted } from '../payload/missingReceiptsPayload';
|
|
7
|
-
import { getCompletedTransactionsCacheKey } from '../reducers/missingReceiptsViewReducer';
|
|
8
6
|
export function getExpenseAutomationMissingReceiptsView(state) {
|
|
9
7
|
const { expenseAutomationMissingReceiptsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, } = state;
|
|
10
8
|
const currentTenant = getCurrentTenant(state);
|
|
@@ -49,34 +47,14 @@ export function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
49
47
|
const completionStatus = missingReceiptsCompletionStatus != null
|
|
50
48
|
? missingReceiptsCompletionStatus
|
|
51
49
|
: 'incomplete';
|
|
52
|
-
const { bulkUpload
|
|
50
|
+
const { bulkUpload } = expenseAutomationMissingReceiptsViewState;
|
|
53
51
|
const currentBatchStatus = bulkUpload.currentBatchId != null
|
|
54
52
|
? bulkUpload.batchStatusById[bulkUpload.currentBatchId]
|
|
55
53
|
: undefined;
|
|
56
|
-
const
|
|
57
|
-
? bulkUpload.
|
|
58
|
-
: [];
|
|
59
|
-
/** API returns newest-first (`sort_order: desc`); primary batch uses oldest-first order. */
|
|
60
|
-
const batchListChronological = orderBy(batchList, (b) => new Date(b.createdAt).valueOf(), 'asc');
|
|
61
|
-
/**
|
|
62
|
-
* Primary "Unmatched" batch = first completed batch in chronological order, preferring the
|
|
63
|
-
* first batch that still has un_matched/no_match work when any completed batch has such work.
|
|
64
|
-
* Batches without details yet: wait if the list row still reports unmatched work; otherwise skip
|
|
65
|
-
* so we do not block the whole tab while older rows are not fetched yet.
|
|
66
|
-
*/
|
|
67
|
-
const primaryBatchIdFromDetailsOrder = getPrimaryBatchIdFromBatchListOrder(batchListChronological, bulkUpload.batchDetailsById, bulkUpload.failedBatchDetailIds);
|
|
68
|
-
/** During upload/matching, the in-flight batch may not appear in batchList yet — prefer currentBatchId. */
|
|
69
|
-
const unmatchedSectionBatchId = bulkUpload.phase === 'matching' || bulkUpload.phase === 'uploading'
|
|
70
|
-
? bulkUpload.currentBatchId ?? primaryBatchIdFromDetailsOrder
|
|
71
|
-
: primaryBatchIdFromDetailsOrder;
|
|
72
|
-
const completedBatchesInApiOrder = batchList.filter((b) => isBatchListStatusCompleted(b.status));
|
|
73
|
-
const currentBatchDetails = unmatchedSectionBatchId != null
|
|
74
|
-
? bulkUpload.batchDetailsById[unmatchedSectionBatchId]
|
|
54
|
+
const currentBatchDetails = bulkUpload.currentBatchId != null
|
|
55
|
+
? bulkUpload.batchDetailsById[bulkUpload.currentBatchId]
|
|
75
56
|
: undefined;
|
|
76
|
-
const resolvedFiles = currentBatchDetails?.files.map((file) => resolveBatchFile(file,
|
|
77
|
-
const failedIds = new Set(bulkUpload.failedBatchDetailIds);
|
|
78
|
-
const hasMoreBatchDetails = completedBatchesInApiOrder.some((b) => bulkUpload.batchDetailsById[b.batchId] == null &&
|
|
79
|
-
!failedIds.has(b.batchId));
|
|
57
|
+
const resolvedFiles = currentBatchDetails?.files.map((file) => resolveBatchFile(file, transactionState));
|
|
80
58
|
const getSortValue = (file) => {
|
|
81
59
|
const t = file.matchedTransaction;
|
|
82
60
|
if (t == null) {
|
|
@@ -114,14 +92,11 @@ export function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
114
92
|
: 0,
|
|
115
93
|
}
|
|
116
94
|
: { total: 0, processed: 0, percentage: 0 };
|
|
95
|
+
const batchList = monthYearPeriodId != null
|
|
96
|
+
? bulkUpload.batchListByPeriod[monthYearPeriodId] ?? []
|
|
97
|
+
: [];
|
|
117
98
|
const batchListFetchState = bulkUpload.batchListFetchState;
|
|
118
|
-
|
|
119
|
-
* When primary batch is not resolved yet, still aggregate unmatched files from every batch
|
|
120
|
-
* that has details loaded (otherwise past is empty and receipts vanish from the UI).
|
|
121
|
-
*/
|
|
122
|
-
const pastBatches = unmatchedSectionBatchId != null
|
|
123
|
-
? batchList.filter((b) => b.batchId !== unmatchedSectionBatchId)
|
|
124
|
-
: batchList;
|
|
99
|
+
const pastBatches = batchList.filter((b) => b.batchId !== bulkUpload.currentBatchId);
|
|
125
100
|
const pastUnmatchedFiles = pastBatches.flatMap((b) => {
|
|
126
101
|
const details = bulkUpload.batchDetailsById[b.batchId];
|
|
127
102
|
if (details == null) {
|
|
@@ -129,13 +104,10 @@ export function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
129
104
|
}
|
|
130
105
|
return details.files
|
|
131
106
|
.filter((f) => f.status === 'un_matched' || f.status === 'no_match')
|
|
132
|
-
.map((f) => resolveBatchFile(f,
|
|
107
|
+
.map((f) => resolveBatchFile(f, transactionState));
|
|
133
108
|
});
|
|
134
|
-
const
|
|
135
|
-
?
|
|
136
|
-
: undefined;
|
|
137
|
-
const completedTransactionsForPeriod = completedTransactionsCacheKey != null
|
|
138
|
-
? bulkUpload.completedTransactionsByPeriod[completedTransactionsCacheKey]
|
|
109
|
+
const completedTransactionsForPeriod = monthYearPeriodId != null
|
|
110
|
+
? bulkUpload.completedTransactionsByPeriod[monthYearPeriodId]
|
|
139
111
|
: undefined;
|
|
140
112
|
const completedTransactionIds = completedTransactionsForPeriod?.transactionIds ?? [];
|
|
141
113
|
const resolvedCompletedTransactions = getSupportedTransactionsByIds(transactionState, completedTransactionIds);
|
|
@@ -156,7 +128,6 @@ export function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
156
128
|
refreshStatus,
|
|
157
129
|
transactions: sortedTransactions,
|
|
158
130
|
completionStatus,
|
|
159
|
-
pendingMissingReceiptsTabNavigation: pendingMissingReceiptsTabNavigation ?? null,
|
|
160
131
|
bulkUpload: {
|
|
161
132
|
phase: bulkUpload.phase,
|
|
162
133
|
uploadStatus: bulkUpload.uploadStatus,
|
|
@@ -183,68 +154,12 @@ export function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
183
154
|
pastBatches,
|
|
184
155
|
pastUnmatchedFiles,
|
|
185
156
|
confirmMatchStatus: bulkUpload.confirmMatchStatus,
|
|
186
|
-
hasMoreBatchDetails,
|
|
187
|
-
batchDetailsPaginationState: bulkUpload.batchDetailsPaginationState,
|
|
188
157
|
manualSearch: bulkUpload.manualSearch,
|
|
189
158
|
uploadProgress: bulkUpload.uploadProgress,
|
|
190
159
|
},
|
|
191
160
|
};
|
|
192
161
|
}
|
|
193
|
-
function
|
|
194
|
-
return details.files.some((f) => f.status === 'un_matched' || f.status === 'no_match');
|
|
195
|
-
}
|
|
196
|
-
/** List row summary before batch details load — aligns with unmatched / possible-match work. */
|
|
197
|
-
function batchListItemHasUnmatchedWork(batch) {
|
|
198
|
-
return batch.noMatchCount > 0 || batch.possibleMatchesCount > 0;
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* `batchList` must be in chronological order (oldest first). Picks the primary batch for the
|
|
202
|
-
* top "Unmatched" section. Skips failed detail fetches.
|
|
203
|
-
*
|
|
204
|
-
* If details are not loaded for an older batch but the list row reports no unmatched work, we
|
|
205
|
-
* skip that batch so newer batches with loaded details can be primary (avoids an empty tab when
|
|
206
|
-
* the first fetch page only loaded newer batches). If the list reports unmatched work but details
|
|
207
|
-
* are still loading, we wait (undefined) so primary order stays correct once details arrive.
|
|
208
|
-
*/
|
|
209
|
-
function getPrimaryBatchIdFromBatchListOrder(batchListChronological, batchDetailsById, failedBatchDetailIds) {
|
|
210
|
-
const failedIds = new Set(failedBatchDetailIds);
|
|
211
|
-
const anyCompletedBatchHasUnmatchedWork = batchListChronological.some((b) => {
|
|
212
|
-
if (failedIds.has(b.batchId)) {
|
|
213
|
-
return false;
|
|
214
|
-
}
|
|
215
|
-
const d = batchDetailsById[b.batchId];
|
|
216
|
-
if (d != null &&
|
|
217
|
-
d.status === 'completed' &&
|
|
218
|
-
batchDetailsHasUnmatchedWork(d)) {
|
|
219
|
-
return true;
|
|
220
|
-
}
|
|
221
|
-
return d == null && batchListItemHasUnmatchedWork(b);
|
|
222
|
-
});
|
|
223
|
-
for (const batch of batchListChronological) {
|
|
224
|
-
if (failedIds.has(batch.batchId)) {
|
|
225
|
-
continue;
|
|
226
|
-
}
|
|
227
|
-
const details = batchDetailsById[batch.batchId];
|
|
228
|
-
if (details == null) {
|
|
229
|
-
if (batchListItemHasUnmatchedWork(batch)) {
|
|
230
|
-
return undefined;
|
|
231
|
-
}
|
|
232
|
-
continue;
|
|
233
|
-
}
|
|
234
|
-
if (details.status !== 'completed') {
|
|
235
|
-
continue;
|
|
236
|
-
}
|
|
237
|
-
if (anyCompletedBatchHasUnmatchedWork) {
|
|
238
|
-
if (batchDetailsHasUnmatchedWork(details)) {
|
|
239
|
-
return batch.batchId;
|
|
240
|
-
}
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
return batch.batchId;
|
|
244
|
-
}
|
|
245
|
-
return undefined;
|
|
246
|
-
}
|
|
247
|
-
function resolveBatchFile(file, batchId, transactionState) {
|
|
162
|
+
function resolveBatchFile(file, transactionState) {
|
|
248
163
|
const matchedTransaction = file.matchedTransactionId != null
|
|
249
164
|
? getSupportedTransactionById(transactionState, file.matchedTransactionId)
|
|
250
165
|
: undefined;
|
|
@@ -258,8 +173,6 @@ function resolveBatchFile(file, batchId, transactionState) {
|
|
|
258
173
|
.filter((c) => c != null);
|
|
259
174
|
return {
|
|
260
175
|
attachmentId: file.attachmentId,
|
|
261
|
-
batchId,
|
|
262
|
-
fileDownloadUrl: file.fileDownloadUrl,
|
|
263
176
|
fileId: file.fileId,
|
|
264
177
|
filename: file.filename,
|
|
265
178
|
filePreviewUrl: file.filePreviewUrl,
|
package/lib/index.d.ts
CHANGED
|
@@ -263,7 +263,7 @@ import { MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, getLine
|
|
|
263
263
|
import { UploadStatementDocumentAIPayload, UploadStatementDocumentAIResponse } from './view/expenseAutomationView/payload/reconciliationPayload';
|
|
264
264
|
import { clearExpenseAutomationFluxAnalysisView, fetchFluxAnalysisView, reviewFluxAnalysisView, updateFluxAnalysisViewPageMetaData, updateFluxAnalysisViewUIState, updateOperatingExpensesIdsForReview, updateSelectedSectionIdsForReview } from './view/expenseAutomationView/reducers/fluxAnalysisViewReducer';
|
|
265
265
|
import { clearJeScheduleLocalData as clearExpenseAutomationJEScheduleLocalData, clearExpenseAutomationJESchedulesView, fetchJeSchedulesPage as fetchExpenseAutomationJESchedulesPage, ignoreRecommendedJeSchedule as ignoreExpenseAutomationJESchedule, initializeAccountSettingsView as initializeJeAccountSettingsView, initializeJeScheduleLocalData, removeJeScheduleTransactionKey, retryJeSchedule as retryExpenseAutomationJESchedule, saveAccountSettings as saveJeAccountSettings, saveAccountSettingsLocalData as saveJeAccountSettingsLocalData, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys } from './view/expenseAutomationView/reducers/jeSchedulesViewReducer';
|
|
266
|
-
import { bulkUploadReceipts, bulkUploadReceiptsFailure, bulkUploadReceiptsSuccess, clearBulkUpload, confirmBulkUploadMatch, confirmBulkUploadMatchFailure, confirmBulkUploadMatchSuccess, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsFailure, fetchBulkUploadBatchDetailsSuccess, storeBatchDetails,
|
|
266
|
+
import { bulkUploadReceipts, bulkUploadReceiptsFailure, bulkUploadReceiptsSuccess, clearBulkUpload, confirmBulkUploadMatch, confirmBulkUploadMatchFailure, confirmBulkUploadMatchSuccess, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsFailure, fetchBulkUploadBatchDetailsSuccess, storeBatchDetails, fetchBulkUploadBatches, fetchBulkUploadBatchesFailure, fetchBulkUploadBatchesSuccess, fetchMissingReceipts as fetchExpenseAutomationMissingReceipts, markMissingReceiptAsDone as markExpenseAutomationMissingReceiptAsDone, pusherBatchStatusUpdate, setBulkUploadResultsTab, setBulkUploadCompletedSubTab, setBulkUploadSortConfig, searchTransactionsForManualMatch, searchTransactionsForManualMatchSuccess, searchTransactionsForManualMatchFailure, clearManualSearchResults, fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, updateBulkUploadBatchStatus, updateBulkUploadProgress, updateMissingReceiptUploadState as updateExpenseAutomationMissingReceiptUploadState, updateMissingReceiptsUIState as updateExpenseAutomationMissingReceiptsUIState, uploadMissingReceiptSuccess as uploadExpenseAutomationMissingReceiptSuccess } from './view/expenseAutomationView/reducers/missingReceiptsViewReducer';
|
|
267
267
|
import { deleteAccountStatement, fetchReconciliation as fetchReconciliationView, saveReconciliationDetail as saveExpenseAutomationReconciliationDetail, saveReconciliationReview as saveExpenseAutomationReconciliationReview, setConnectionInProgressForAccount as setConnectionInProgressForAccountReconciliation, setStatementParseInProgress, updateAccountReconciliationLocalData as updateExpenseAutomationAccountReconciliationLocalData, updateSelectedAccountId as updateExpenseAutomationAccountReconciliationSelectedAccountId, updateSelectedTab as updateExpenseAutomationAccountReconciliationSelectedTab, updateReconListScrollPosition as updateExpenseAutomationReconListScrollPosition, updateReviewTabSortState as updateExpenseAutomationReconReviewTabListSortState, updateReviewTabLocalData as updateExpenseAutomationReconReviewTabLocalData, updateReconcileTabListScrollState as updateExpenseAutomationReconcileTabListScrollState, updateReconcileTabListSortState as updateExpenseAutomationReconcileTabListSortState, updateReconcileTabLocalData as updateExpenseAutomationReconcileTabLocalData, updateSelectedDrawerAccountId as updateExpenseAutomationSelectedDrawerAccountId, updateStatementUploadChosen, uploadAccountStatement } from './view/expenseAutomationView/reducers/reconciliationViewReducer';
|
|
268
268
|
import { clearExpenseAutomationTransactionsView, fetchTransactionCategorization, fetchTransactionCategorizationFailure, fetchTransactionCategorizationView, initializeTransactionCategorizationViewLocalData, markTransactionAsNotMiscategorized, saveTransactionCategorization, saveTransactionCategorizationLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, setEntityRecommendationForLineIdsForCategorization, updateCurrentSelectedTransactionCategorizationTab, updateSelectedCheckboxTransactionIds, updateSelectedCustomerForTransaction, updateSelectedTransactionId, updateSelectedVendorForTransaction, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, updateTransactionCategorizationUIState } from './view/expenseAutomationView/reducers/transactionsViewReducer';
|
|
269
269
|
import { ExpenseAutomationStepDetails, ExpenseAutomationViewSelector } from './view/expenseAutomationView/selectorTypes/expenseAutomationViewSelectorTypes';
|
|
@@ -615,7 +615,7 @@ export { TransactionsOrder, COABalancesSliceOrder, EntityOrder, Section, Section
|
|
|
615
615
|
export { ClassesViewSelectorReportV2 };
|
|
616
616
|
export { BalancesTimeseries, TrendTimeseries, BalanceKind };
|
|
617
617
|
export { fetchMonthEndCloseChecks, fetchMonthClosePerformanceTrend, MonthClosePerformanceTrend, MonthEndCloseCheck, getMonthEndCloseChecksViewByTenantId, MonthEndCloseChecksView, MonthEndCloseCheckFrequency, MonthCloseCheckMetrics, ALL_MONTH_END_CLOSE_CHECKS_FREQUENCY, MonthEndAuditSummary, };
|
|
618
|
-
export { ExpenseAutomationViewSelector, ExpenseAutomationStepDetails, ExpenseAutomationViewType, ExpenseAutomationMissingReceiptsViewSelector, BulkUploadSelectorData, ExpenseAutomationFluxAnalysisViewSelector, FluxAnalysisVendorView, FluxAnalysisViewSectionReport, FluxVendorAccountsAndClassesView, ExpenseAutomationMissingReceiptsViewUIState, ExpenseAutomationMissingReceiptsViewState, ExpenseAutomationViewState, ExpenseAutomationTransactionsTab, ExpenseAutomationMissingReceiptsSortKey, BatchDetails, BatchFile, BatchFileStatus, BatchListItem, BatchStatus, BatchStatusValue, BatchSummary, BulkUploadPhase, BulkUploadResultsTab, BulkUploadSortKey, BulkUploadState, CandidateRef, CompletedSubTab, CompletedTransactionsSelectorData, MatchCandidate, MatchSource, MissingReceiptsTab, ResolvedBatchFile, ResolvedBatchDetails, ResolvedCandidate, getExpenseAutomationView, toExpenseAutomationMissingReceiptsSortKey, toExpenseAutomationTransactionsTabKey, toExpenseAutomationViewType, uploadExpenseAutomationMissingReceiptSuccess, markExpenseAutomationMissingReceiptAsDone, fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedTransactionCategorizationTab, fetchExpenseAutomationMissingReceipts, bulkUploadReceipts, bulkUploadReceiptsSuccess, bulkUploadReceiptsFailure, updateBulkUploadProgress, pusherBatchStatusUpdate,
|
|
618
|
+
export { ExpenseAutomationViewSelector, ExpenseAutomationStepDetails, ExpenseAutomationViewType, ExpenseAutomationMissingReceiptsViewSelector, BulkUploadSelectorData, ExpenseAutomationFluxAnalysisViewSelector, FluxAnalysisVendorView, FluxAnalysisViewSectionReport, FluxVendorAccountsAndClassesView, ExpenseAutomationMissingReceiptsViewUIState, ExpenseAutomationMissingReceiptsViewState, ExpenseAutomationViewState, ExpenseAutomationTransactionsTab, ExpenseAutomationMissingReceiptsSortKey, BatchDetails, BatchFile, BatchFileStatus, BatchListItem, BatchStatus, BatchStatusValue, BatchSummary, BulkUploadPhase, BulkUploadResultsTab, BulkUploadSortKey, BulkUploadState, CandidateRef, CompletedSubTab, CompletedTransactionsSelectorData, MatchCandidate, MatchSource, MissingReceiptsTab, ResolvedBatchFile, ResolvedBatchDetails, ResolvedCandidate, getExpenseAutomationView, toExpenseAutomationMissingReceiptsSortKey, toExpenseAutomationTransactionsTabKey, toExpenseAutomationViewType, uploadExpenseAutomationMissingReceiptSuccess, markExpenseAutomationMissingReceiptAsDone, fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedTransactionCategorizationTab, fetchExpenseAutomationMissingReceipts, bulkUploadReceipts, bulkUploadReceiptsSuccess, bulkUploadReceiptsFailure, updateBulkUploadBatchStatus, updateBulkUploadProgress, pusherBatchStatusUpdate, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatchDetailsFailure, storeBatchDetails, fetchBulkUploadBatches, fetchBulkUploadBatchesSuccess, fetchBulkUploadBatchesFailure, confirmBulkUploadMatch, confirmBulkUploadMatchSuccess, confirmBulkUploadMatchFailure, setBulkUploadResultsTab, setBulkUploadCompletedSubTab, setBulkUploadSortConfig, clearBulkUpload, searchTransactionsForManualMatch, searchTransactionsForManualMatchSuccess, searchTransactionsForManualMatchFailure, clearManualSearchResults, fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, fetchFluxAnalysisView, clearExpenseAutomationFluxAnalysisView, updateOperatingExpensesIdsForReview as updateFluxOperatingExpensesIdsForReview, updateSelectedSectionIdsForReview as updateFluxAnalysisSelectedSectionIdsForReview, reviewFluxAnalysisView, updateExpenseAutomationMissingReceiptUploadState, updateExpenseAutomationMissingReceiptsUIState, FluxAnalysisOperatingExpenseView, FluxAnalysisSectionType, getExpenseAutomationFluxAnalysisView, FluxAnalysisSortKey, FluxAnalysisActionType, FluxBalancesByMonth, updateCurrentSelectedView, updateCurrentSelectedPeriod, getExpenseAutomationTransactionView, ReconReconcileSortKey, ReconciliationReconcileTabLocalData, FluxAnalysisReviewStatus, updateFluxAnalysisViewUIState, FluxAnalysisViewUIState, updateFluxAnalysisViewPageMetaData, MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, getLineItemsByTransactionIdsFromLocalData, isAnyItemWithUncategorizedExpenseAccount, SaveExpenseAutomationReconciliationActionType, saveExpenseAutomationReconciliationDetail, updateExpenseAutomationReconcileTabListScrollState, updateExpenseAutomationReconReviewTabListSortState, updateExpenseAutomationReconcileTabListSortState, updateExpenseAutomationReconcileTabLocalData, updateExpenseAutomationAccountReconciliationSelectedTab, updateExpenseAutomationAccountReconciliationSelectedAccountId, ExpenseAutomationReconciliationViewSelector, getExpenseAutomationReconciliationView, AccountReconciliationBySection, fetchReconciliationView, uploadAccountStatementIntoDocumentAI, UploadStatementDocumentAIResponse, updateExpenseAutomationReconListScrollPosition, setConnectionInProgressForAccountReconciliation, AccountReconciliationByAccount, AccountReconciliationEntity, getAccountReconByAccountIdAndSelectedPeriod, ExpenseAutomationReconciliationViewTab, toReconciliationTabsType, isAccountReconReport, ReconReviewSortKey, AccountReconSectionID, ReconciliationReviewTabLocalData, TransactionsToReview, RecommendedActionCodeType, ReconciliationStatusCodeType, BalanceDataStatusCodeType, updateExpenseAutomationReconReviewTabLocalData, updateExpenseAutomationSelectedDrawerAccountId, saveExpenseAutomationReconciliationReview, updateExpenseAutomationAccountReconciliationLocalData, BankStatusCodeType, ReconciliationAccountSourceType, toReconciliationAccountSource, StatementStatusCodeType, AccountReconciliationLocalData, StatementDataStatusCodeType, deleteAccountStatement, uploadAccountStatement, UploadStatementDocumentAIPayload, updateStatementUploadChosen, isReviewTransactionBankTransferType, isReviewTransactionBillPaymentType, isReviewTransactionCreditCardPaymentType, isReviewTransactionDepositType, isReviewTransactionExpenseType, isReviewTransactionCreditCardCreditType, setStatementParseInProgress, };
|
|
619
619
|
export { JEScheduleLocalData };
|
|
620
620
|
export { ExpenseAutomationJESchedulesViewSelector, JEAccountSettingsView, JEScheduledTransactionWithFailedEntries, };
|
|
621
621
|
export { fetchTransactionCategorization, fetchTransactionCategorizationView, updateTransactionCategorizationUIState, updateSelectedCheckboxTransactionIds, setEntityRecommendationForLineIdsForCategorization, initializeTransactionCategorizationViewLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, updateSelectedTransactionId, clearExpenseAutomationTransactionsView, TransactionsSortKey, toTransactionsSortKey, TransactionsTab, TransactionCategorizationLineItemData, TransactionReviewLocalData, SupportedTransactionCategorization, ExpenseAutomationTransactionsViewState, ExpenseAutomationTransactionsViewUIState, ExpenseAutomationTransactionViewSelector, TransactionReviewLocalDataSelectorView, };
|