@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.
Files changed (36) hide show
  1. package/lib/epic.d.ts +1 -2
  2. package/lib/epic.js +1 -2
  3. package/lib/esm/epic.js +1 -2
  4. package/lib/esm/index.js +2 -2
  5. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.js +8 -4
  6. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchDetailsEpic.js +2 -2
  7. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js +1 -6
  8. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +3 -7
  9. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.js +15 -24
  10. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +32 -32
  11. package/lib/esm/view/expenseAutomationView/payload/missingReceiptsPayload.js +12 -15
  12. package/lib/esm/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +13 -73
  13. package/lib/esm/view/expenseAutomationView/selectors/missingReceiptsSelector.js +12 -99
  14. package/lib/index.d.ts +2 -2
  15. package/lib/index.js +32 -36
  16. package/lib/tsconfig.typecheck.tsbuildinfo +1 -0
  17. package/lib/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.d.ts +5 -2
  18. package/lib/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.js +7 -3
  19. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchDetailsEpic.js +2 -2
  20. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js +1 -6
  21. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +2 -6
  22. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.d.ts +2 -3
  23. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.js +12 -25
  24. package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.d.ts +7 -5
  25. package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +28 -28
  26. package/lib/view/expenseAutomationView/payload/missingReceiptsPayload.d.ts +16 -15
  27. package/lib/view/expenseAutomationView/payload/missingReceiptsPayload.js +13 -16
  28. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +3 -12
  29. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +14 -75
  30. package/lib/view/expenseAutomationView/selectorTypes/missingReceiptsSelectorTypes.d.ts +1 -7
  31. package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.js +12 -99
  32. package/lib/view/expenseAutomationView/types/missingReceiptsViewState.d.ts +2 -10
  33. package/package.json +2 -2
  34. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchMoreBatchDetailsEpic.js +0 -36
  35. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMoreBatchDetailsEpic.d.ts +0 -8
  36. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMoreBatchDetailsEpic.js +0 -43
@@ -1,41 +1,41 @@
1
- import { EMPTY, from, merge, of, timer } from 'rxjs';
2
- import { catchError, debounceTime, filter, mergeMap, switchMap, takeUntil, } from 'rxjs/operators';
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 { extractTransactionPayloadsFromBatchFiles, toBatchDetails, } from '../../payload/missingReceiptsPayload';
6
- import { bulkUploadReceiptsSuccess, clearBulkUpload, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatches, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, } from '../../reducers/missingReceiptsViewReducer';
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
- * On Pusher batch completion: refresh batch list (then fetchMultipleBatchDetailsEpic runs),
15
- * and request switching to the Unmatched tab. Debounced to reduce duplicate refreshes.
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
- export const pusherBatchStatusCompletionEpic = (actions$) => actions$.pipe(filter(pusherBatchStatusUpdate.match), filter((action) => action.payload.status === 'completed'), debounceTime(300), mergeMap(() => from([
18
- fetchBulkUploadBatches(true),
19
- requestMissingReceiptsTabNavigation({ tab: 'unmatched' }),
20
- ])));
21
- export const pollBulkUploadBatchStatusEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(bulkUploadReceiptsSuccess.match), mergeMap((action) => {
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(FALLBACK_FIRST_DELAY_MS, FALLBACK_POLL_INTERVAL_MS).pipe(takeUntil(merge(actions$.pipe(filter(clearBulkUpload.match)), actions$.pipe(filter(pusherBatchStatusUpdate.match), filter((a) => a.payload.batchId === batchId)), actions$.pipe(filter(fetchBulkUploadBatchDetailsSuccess.match), filter((a) => a.payload.batchId === batchId)))), switchMap(() => zeniAPI
24
- .getJSON(`${zeniAPI.apiEndPoints.communicationAgentMicroServiceBaseUrl}/1.0/batches/${batchId}`)
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
- if (isBatchDetailsCompletedStatus(response.data.status)) {
28
- const actions = [];
29
- const transactionPayloads = extractTransactionPayloadsFromBatchFiles(response.data.files);
30
- if (transactionPayloads.length > 0) {
31
- actions.push(updateTransactions(transactionPayloads, (value) => value.transaction_id));
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 EMPTY;
40
- }), catchError(() => of()))));
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, filesEndPoint) {
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 ?? 'expense',
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 toBatchDetails(payload, filesEndPoint) {
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((f) => toBatchFile(f, filesEndPoint)),
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
- pusherBatchStatusUpdate(draft, action) {
178
+ updateBulkUploadBatchStatus(draft, action) {
183
179
  const batchStatus = action.payload;
184
180
  draft.bulkUpload.batchStatusById[batchStatus.batchId] = batchStatus;
185
181
  },
186
- requestMissingReceiptsTabNavigation(draft, action) {
187
- draft.pendingMissingReceiptsTabNavigation = action.payload.tab;
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, cacheOverride) {
390
- return { payload: { pageToken, cacheOverride } };
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[cacheKey] = {
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[cacheKey];
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[cacheKey] = {
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 cacheKey = getCompletedTransactionsCacheKey(periodId, draft.bulkUpload.sortKey, draft.bulkUpload.sortOrder, draft.bulkUpload.completedSubTab);
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[cacheKey] = {
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, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, clearMissingReceiptsTabNavigation, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatchDetailsFailure, storeBatchDetails, batchDetailFetchFailed, setInitialBatchDetailsLoading, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, fetchBulkUploadBatches, fetchBulkUploadBatchesSuccess, fetchBulkUploadBatchesFailure, confirmBulkUploadMatch, confirmBulkUploadMatchSuccess, confirmBulkUploadMatchFailure, setBulkUploadResultsTab, setBulkUploadCompletedSubTab, setBulkUploadSortConfig, clearBulkUpload, searchTransactionsForManualMatch, searchTransactionsForManualMatchSuccess, searchTransactionsForManualMatchFailure, clearManualSearchResults,
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, pendingMissingReceiptsTabNavigation, } = expenseAutomationMissingReceiptsViewState;
50
+ const { bulkUpload } = expenseAutomationMissingReceiptsViewState;
53
51
  const currentBatchStatus = bulkUpload.currentBatchId != null
54
52
  ? bulkUpload.batchStatusById[bulkUpload.currentBatchId]
55
53
  : undefined;
56
- const batchList = monthYearPeriodId != null
57
- ? bulkUpload.batchListByPeriod[monthYearPeriodId] ?? []
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, currentBatchDetails.batchId, transactionState));
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, b.batchId, transactionState));
107
+ .map((f) => resolveBatchFile(f, transactionState));
133
108
  });
134
- const completedTransactionsCacheKey = monthYearPeriodId != null
135
- ? getCompletedTransactionsCacheKey(monthYearPeriodId, bulkUpload.sortKey, bulkUpload.sortOrder, bulkUpload.completedSubTab)
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 batchDetailsHasUnmatchedWork(details) {
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, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, fetchBulkUploadBatches, fetchBulkUploadBatchesFailure, fetchBulkUploadBatchesSuccess, fetchMissingReceipts as fetchExpenseAutomationMissingReceipts, markMissingReceiptAsDone as markExpenseAutomationMissingReceiptAsDone, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, clearMissingReceiptsTabNavigation, setBulkUploadResultsTab, setBulkUploadCompletedSubTab, setBulkUploadSortConfig, searchTransactionsForManualMatch, searchTransactionsForManualMatchSuccess, searchTransactionsForManualMatchFailure, clearManualSearchResults, fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, updateBulkUploadProgress, updateMissingReceiptUploadState as updateExpenseAutomationMissingReceiptUploadState, updateMissingReceiptsUIState as updateExpenseAutomationMissingReceiptsUIState, uploadMissingReceiptSuccess as uploadExpenseAutomationMissingReceiptSuccess } from './view/expenseAutomationView/reducers/missingReceiptsViewReducer';
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, requestMissingReceiptsTabNavigation, clearMissingReceiptsTabNavigation, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatchDetailsFailure, storeBatchDetails, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, 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, };
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, };