@zeniai/client-epic-state 4.19.37-betaVR18 → 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 -51
- 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 -53
- 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) {
|
|
@@ -206,36 +200,6 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
206
200
|
const details = action.payload;
|
|
207
201
|
draft.bulkUpload.batchDetailsById[details.batchId] = details;
|
|
208
202
|
},
|
|
209
|
-
batchDetailFetchFailed(draft, action) {
|
|
210
|
-
const { batchId } = action.payload;
|
|
211
|
-
if (!draft.bulkUpload.failedBatchDetailIds.includes(batchId)) {
|
|
212
|
-
draft.bulkUpload.failedBatchDetailIds.push(batchId);
|
|
213
|
-
}
|
|
214
|
-
},
|
|
215
|
-
setInitialBatchDetailsLoading(draft) {
|
|
216
|
-
draft.bulkUpload.batchDetailsPaginationState = {
|
|
217
|
-
fetchState: 'In-Progress',
|
|
218
|
-
error: undefined,
|
|
219
|
-
};
|
|
220
|
-
},
|
|
221
|
-
fetchMoreBatchDetails(_draft) {
|
|
222
|
-
_draft.bulkUpload.batchDetailsPaginationState = {
|
|
223
|
-
fetchState: 'In-Progress',
|
|
224
|
-
error: undefined,
|
|
225
|
-
};
|
|
226
|
-
},
|
|
227
|
-
fetchMoreBatchDetailsComplete(draft) {
|
|
228
|
-
draft.bulkUpload.batchDetailsPaginationState = {
|
|
229
|
-
fetchState: 'Completed',
|
|
230
|
-
error: undefined,
|
|
231
|
-
};
|
|
232
|
-
},
|
|
233
|
-
fetchMoreBatchDetailsFailure(draft, action) {
|
|
234
|
-
draft.bulkUpload.batchDetailsPaginationState = {
|
|
235
|
-
fetchState: 'Error',
|
|
236
|
-
error: action.payload.error,
|
|
237
|
-
};
|
|
238
|
-
},
|
|
239
203
|
fetchBulkUploadBatches: {
|
|
240
204
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
241
205
|
reducer(draft, _action) {
|
|
@@ -309,6 +273,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
309
273
|
},
|
|
310
274
|
setBulkUploadCompletedSubTab(draft, action) {
|
|
311
275
|
draft.bulkUpload.completedSubTab = action.payload;
|
|
276
|
+
draft.bulkUpload.completedTransactionsByPeriod = {};
|
|
312
277
|
},
|
|
313
278
|
setBulkUploadSortConfig(draft, action) {
|
|
314
279
|
draft.bulkUpload.sortKey = action.payload.sortKey;
|
|
@@ -316,7 +281,6 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
316
281
|
},
|
|
317
282
|
clearBulkUpload(draft) {
|
|
318
283
|
Object.assign(draft.bulkUpload, initialBulkUploadState);
|
|
319
|
-
draft.pendingMissingReceiptsTabNavigation = null;
|
|
320
284
|
},
|
|
321
285
|
searchTransactionsForManualMatch: {
|
|
322
286
|
reducer(draft, action) {
|
|
@@ -364,16 +328,15 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
364
328
|
}
|
|
365
329
|
}
|
|
366
330
|
},
|
|
367
|
-
prepare(pageToken
|
|
368
|
-
return { payload: { pageToken
|
|
331
|
+
prepare(pageToken) {
|
|
332
|
+
return { payload: { pageToken } };
|
|
369
333
|
},
|
|
370
334
|
},
|
|
371
335
|
fetchCompletedTransactionsSuccess(draft, action) {
|
|
372
336
|
const { transactionIds, nextPageToken, totalCount, selectedPeriod, isInitialLoad } = action.payload;
|
|
373
337
|
const periodId = toMonthYearPeriodId(selectedPeriod);
|
|
374
|
-
const cacheKey = getCompletedTransactionsCacheKey(periodId, draft.bulkUpload.sortKey, draft.bulkUpload.sortOrder, draft.bulkUpload.completedSubTab);
|
|
375
338
|
if (isInitialLoad) {
|
|
376
|
-
draft.bulkUpload.completedTransactionsByPeriod[
|
|
339
|
+
draft.bulkUpload.completedTransactionsByPeriod[periodId] = {
|
|
377
340
|
transactionIds,
|
|
378
341
|
nextPageToken,
|
|
379
342
|
totalCount,
|
|
@@ -381,7 +344,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
381
344
|
};
|
|
382
345
|
}
|
|
383
346
|
else {
|
|
384
|
-
const existing = draft.bulkUpload.completedTransactionsByPeriod[
|
|
347
|
+
const existing = draft.bulkUpload.completedTransactionsByPeriod[periodId];
|
|
385
348
|
if (existing != null) {
|
|
386
349
|
existing.transactionIds.push(...transactionIds);
|
|
387
350
|
existing.nextPageToken = nextPageToken;
|
|
@@ -389,7 +352,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
389
352
|
existing.fetchState = { fetchState: 'Completed', error: undefined };
|
|
390
353
|
}
|
|
391
354
|
else {
|
|
392
|
-
draft.bulkUpload.completedTransactionsByPeriod[
|
|
355
|
+
draft.bulkUpload.completedTransactionsByPeriod[periodId] = {
|
|
393
356
|
transactionIds,
|
|
394
357
|
nextPageToken,
|
|
395
358
|
totalCount,
|
|
@@ -400,8 +363,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
400
363
|
},
|
|
401
364
|
fetchCompletedTransactionsFailure(draft, action) {
|
|
402
365
|
const periodId = toMonthYearPeriodId(action.payload.selectedPeriod);
|
|
403
|
-
const
|
|
404
|
-
const existing = draft.bulkUpload.completedTransactionsByPeriod[cacheKey];
|
|
366
|
+
const existing = draft.bulkUpload.completedTransactionsByPeriod[periodId];
|
|
405
367
|
if (existing != null) {
|
|
406
368
|
existing.fetchState = {
|
|
407
369
|
fetchState: 'Error',
|
|
@@ -409,7 +371,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
409
371
|
};
|
|
410
372
|
}
|
|
411
373
|
else {
|
|
412
|
-
draft.bulkUpload.completedTransactionsByPeriod[
|
|
374
|
+
draft.bulkUpload.completedTransactionsByPeriod[periodId] = {
|
|
413
375
|
fetchState: { fetchState: 'Error', error: action.payload.error },
|
|
414
376
|
nextPageToken: null,
|
|
415
377
|
totalCount: 0,
|
|
@@ -421,7 +383,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
421
383
|
});
|
|
422
384
|
export const { fetchMissingReceipts, fetchMissingReceiptsSuccess, fetchMissingReceiptsFailure, uploadMissingReceiptSuccess, updateMissingReceiptUploadState, updateMissingReceiptsUIState, markMissingReceiptAsDone, clearExpenseAutomationMissingReceiptsView,
|
|
423
385
|
// Bulk Upload
|
|
424
|
-
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,
|
|
425
387
|
// Completed Transactions
|
|
426
388
|
fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, } = expenseAutomationMissingReceiptsView.actions;
|
|
427
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, };
|