@zeniai/client-epic-state 4.19.84-betaVR10 → 4.19.84-betaVR12
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/esm/index.js +5 -2
- package/lib/esm/view/expenseAutomationView/bulkUploadTiming.js +5 -0
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.js +4 -3
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +5 -5
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +1 -1
- package/lib/esm/view/expenseAutomationView/payload/missingReceiptsPayload.js +14 -11
- package/lib/esm/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +21 -20
- package/lib/esm/view/expenseAutomationView/selectors/missingReceiptsSelector.js +57 -34
- package/lib/esm/view/expenseAutomationView/types/missingReceiptsViewState.js +30 -1
- package/lib/index.d.ts +3 -2
- package/lib/index.js +43 -32
- package/lib/tsconfig.typecheck.tsbuildinfo +1 -1
- package/lib/view/expenseAutomationView/bulkUploadTiming.d.ts +5 -0
- package/lib/view/expenseAutomationView/bulkUploadTiming.js +8 -0
- package/lib/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.d.ts +3 -0
- package/lib/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.js +2 -1
- package/lib/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +5 -5
- package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +1 -1
- package/lib/view/expenseAutomationView/payload/missingReceiptsPayload.d.ts +1 -1
- package/lib/view/expenseAutomationView/payload/missingReceiptsPayload.js +14 -11
- package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +7 -3
- package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +21 -20
- package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.js +57 -34
- package/lib/view/expenseAutomationView/types/missingReceiptsViewState.d.ts +20 -9
- package/lib/view/expenseAutomationView/types/missingReceiptsViewState.js +39 -2
- package/package.json +1 -1
package/lib/esm/index.js
CHANGED
|
@@ -169,7 +169,7 @@ import { backgroundRefetchReviewTab, clearExpenseAutomationTransactionsView, fet
|
|
|
169
169
|
import { getExpenseAutomationFluxAnalysisView } from './view/expenseAutomationView/selectors/fluxAnalysisViewSelector';
|
|
170
170
|
import { getExpenseAutomationReconciliationView, isAccountReconReport, } from './view/expenseAutomationView/selectors/reconciliationViewSelector';
|
|
171
171
|
import { getExpenseAutomationTransactionView } from './view/expenseAutomationView/selectors/transactionCategorizationSelector';
|
|
172
|
-
import { isUnmatchedTabFileStatus, } from './view/expenseAutomationView/types/missingReceiptsViewState';
|
|
172
|
+
import { BATCH_FILE_STATUSES, isUnmatchedTabFileStatus, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toCompletedSubTab, toMatchSource, toMissingReceiptsTab, } from './view/expenseAutomationView/types/missingReceiptsViewState';
|
|
173
173
|
import { toMissingReceiptsSortKey as toExpenseAutomationMissingReceiptsSortKey, } from './view/expenseAutomationView/types/missingReceiptsViewState';
|
|
174
174
|
import { toReconciliationTabsType, } from './view/expenseAutomationView/types/reconciliationViewState';
|
|
175
175
|
import { toTransactionsTabKey as toExpenseAutomationTransactionsTabKey, toTransactionsSortKey, } from './view/expenseAutomationView/types/transactionsViewState';
|
|
@@ -416,7 +416,9 @@ export { newBalancesFilterClassesView };
|
|
|
416
416
|
export { toCOABalanceTypeStrict, toCOABalanceType as toCOABlanaceType, isCalculatedBalanceType, };
|
|
417
417
|
export { stringToUnion, stringToUnionStrict };
|
|
418
418
|
export { fetchMonthEndCloseChecks, fetchMonthClosePerformanceTrend, getMonthEndCloseChecksViewByTenantId, ALL_MONTH_END_CLOSE_CHECKS_FREQUENCY, };
|
|
419
|
-
export {
|
|
419
|
+
export {
|
|
420
|
+
// Bulk Upload Types
|
|
421
|
+
BATCH_FILE_STATUSES, isUnmatchedTabFileStatus, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toCompletedSubTab, toMatchSource, toMissingReceiptsTab, getExpenseAutomationView, toExpenseAutomationMissingReceiptsSortKey, toExpenseAutomationTransactionsTabKey, toExpenseAutomationViewType, uploadExpenseAutomationMissingReceiptSuccess, markExpenseAutomationMissingReceiptAsDone, fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedTransactionCategorizationTab, fetchExpenseAutomationMissingReceipts,
|
|
420
422
|
// Bulk Upload Actions
|
|
421
423
|
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, acknowledgeBulkUploadConfirmMatchComplete, fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, fetchFluxAnalysisView, clearExpenseAutomationFluxAnalysisView, updateOperatingExpensesIdsForReview as updateFluxOperatingExpensesIdsForReview, updateSelectedSectionIdsForReview as updateFluxAnalysisSelectedSectionIdsForReview, reviewFluxAnalysisView, updateExpenseAutomationMissingReceiptUploadState, updateExpenseAutomationMissingReceiptsUIState, updateTransactionCategorizationUploadReceiptState, uploadTransactionCategorizationReceiptSuccess, getExpenseAutomationFluxAnalysisView, updateCurrentSelectedView, updateCurrentSelectedPeriod, getExpenseAutomationTransactionView, updateFluxAnalysisViewUIState, updateFluxAnalysisViewPageMetaData, MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, getLineItemsByTransactionIdsFromLocalData, isAnyItemWithUncategorizedExpenseAccount, saveExpenseAutomationReconciliationDetail, updateExpenseAutomationReconcileTabListScrollState, updateExpenseAutomationReconReviewTabListSortState, updateExpenseAutomationReconcileTabListSortState, updateExpenseAutomationReconcileTabLocalData, updateExpenseAutomationAccountReconciliationSelectedTab, updateExpenseAutomationAccountReconciliationSelectedAccountId, getExpenseAutomationReconciliationView, fetchReconciliationView, uploadAccountStatementIntoDocumentAI, updateExpenseAutomationReconListScrollPosition, setConnectionInProgressForAccountReconciliation, getAccountReconByAccountIdAndSelectedPeriod, toReconciliationTabsType, isAccountReconReport, updateExpenseAutomationReconReviewTabLocalData, updateExpenseAutomationSelectedDrawerAccountId, saveExpenseAutomationReconciliationReview, updateExpenseAutomationAccountReconciliationLocalData, toReconciliationAccountSource, deleteAccountStatement, uploadAccountStatement, updateStatementUploadChosen, isReviewTransactionBankTransferType, isReviewTransactionBillPaymentType, isReviewTransactionCreditCardPaymentType, isReviewTransactionDepositType, isReviewTransactionExpenseType, isReviewTransactionCreditCardCreditType, setStatementParseInProgress, };
|
|
422
424
|
export { fetchTransactionCategorization, fetchTransactionCategorizationView, updateTransactionCategorizationUIState, updateSelectedCheckboxTransactionIds, setEntityRecommendationForLineIdsForCategorization, initializeTransactionCategorizationViewLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, updateSelectedTransactionId, syncTransactionCategorizationFromDetailSave, backgroundRefetchReviewTab, clearExpenseAutomationTransactionsView, toTransactionsSortKey, };
|
|
@@ -610,5 +612,6 @@ export { fetchTreasuryStatementList } from './view/spendManagement/treasury/trea
|
|
|
610
612
|
export { getTreasuryStatements, } from './view/spendManagement/treasury/treasuryStatementList/treasuryStatementListSelector';
|
|
611
613
|
export { fetchTreasuryTaxLetterList } from './view/spendManagement/treasury/treasuryTaxLetterList/treasuryTaxLetterListReducer';
|
|
612
614
|
export { getTreasuryTaxLetters, } from './view/spendManagement/treasury/treasuryTaxLetterList/treasuryTaxLetterListSelector';
|
|
615
|
+
export { BULK_UPLOAD_BAR_COMPLETE_HOLD_MS } from './view/expenseAutomationView/bulkUploadTiming';
|
|
613
616
|
export { fetchTransactionActivityLog } from './view/transactionActivityLogView/transactionActivityLogViewReducer';
|
|
614
617
|
export { getTransactionActivityLogView, } from './view/transactionActivityLogView/transactionActivityLogViewSelector';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { of } from 'rxjs';
|
|
1
|
+
import { concat, of, timer } from 'rxjs';
|
|
2
2
|
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
3
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
4
|
-
import {
|
|
4
|
+
import { BULK_UPLOAD_BAR_COMPLETE_HOLD_MS } from '../../bulkUploadTiming';
|
|
5
|
+
import { bulkUploadReceipts, bulkUploadReceiptsFailure, bulkUploadReceiptsSuccess, updateBulkUploadProgress, } from '../../reducers/missingReceiptsViewReducer';
|
|
5
6
|
export const bulkUploadReceiptsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(bulkUploadReceipts.match), mergeMap((action) => {
|
|
6
7
|
const { files } = action.payload;
|
|
7
8
|
const formData = new FormData();
|
|
@@ -18,7 +19,7 @@ export const bulkUploadReceiptsEpic = (actions$, _state$, zeniAPI) => actions$.p
|
|
|
18
19
|
error: createZeniAPIStatus('Unexpected Error', 'Bulk upload succeeded but batch_id was missing or empty.'),
|
|
19
20
|
}));
|
|
20
21
|
}
|
|
21
|
-
return of(bulkUploadReceiptsSuccess({ batchId }));
|
|
22
|
+
return concat(of(updateBulkUploadProgress(100)), timer(BULK_UPLOAD_BAR_COMPLETE_HOLD_MS).pipe(mergeMap(() => of(bulkUploadReceiptsSuccess({ batchId })))));
|
|
22
23
|
}
|
|
23
24
|
return of(bulkUploadReceiptsFailure({ error: response.status }));
|
|
24
25
|
}), catchError((error) => of(bulkUploadReceiptsFailure({
|
|
@@ -15,14 +15,14 @@ import { toTransactionsSortKey } from '../../types/transactionsViewState';
|
|
|
15
15
|
export const MANUAL_TRANSACTION_SEARCH_AUTO_CATEGORIZED = false;
|
|
16
16
|
export const searchTransactionsForManualMatchEpic = (actions$, state$, zeniAPI) => {
|
|
17
17
|
const searchActions$ = actions$.pipe(filter(searchTransactionsForManualMatch.match));
|
|
18
|
-
const pagination$ = searchActions$.pipe(filter((
|
|
18
|
+
const pagination$ = searchActions$.pipe(filter((action) => action.payload.pageToken != null));
|
|
19
19
|
/**
|
|
20
20
|
* No API for empty or 1-char queries; immediate merge so switchMap cancels any in-flight HTTP.
|
|
21
21
|
*/
|
|
22
|
-
const newSearchTooShortOrClear$ = searchActions$.pipe(filter((
|
|
23
|
-
|
|
24
|
-
const newSearchDebounced$ = searchActions$.pipe(filter((
|
|
25
|
-
|
|
22
|
+
const newSearchTooShortOrClear$ = searchActions$.pipe(filter((action) => action.payload.pageToken == null &&
|
|
23
|
+
action.payload.query.trim().length < 2));
|
|
24
|
+
const newSearchDebounced$ = searchActions$.pipe(filter((action) => action.payload.pageToken == null &&
|
|
25
|
+
action.payload.query.trim().length >= 2), debounceTime(300));
|
|
26
26
|
return merge(pagination$, newSearchTooShortOrClear$, newSearchDebounced$).pipe(switchMap((action) => {
|
|
27
27
|
const { query, pageToken } = action.payload;
|
|
28
28
|
if (pageToken == null &&
|
package/lib/esm/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js
CHANGED
|
@@ -27,7 +27,7 @@ export const pusherBatchStatusCompletionEpic = (actions$) => actions$.pipe(filte
|
|
|
27
27
|
export const pollBulkUploadBatchStatusEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(bulkUploadReceiptsSuccess.match), mergeMap((action) => {
|
|
28
28
|
const { batchId } = action.payload;
|
|
29
29
|
let pollErrorNotified = false;
|
|
30
|
-
return timer(FALLBACK_FIRST_DELAY_MS, FALLBACK_POLL_INTERVAL_MS).pipe(takeUntil(merge(actions$.pipe(filter(clearBulkUpload.match)), actions$.pipe(filter(pusherBatchStatusUpdate.match), filter((
|
|
30
|
+
return timer(FALLBACK_FIRST_DELAY_MS, FALLBACK_POLL_INTERVAL_MS).pipe(takeUntil(merge(actions$.pipe(filter(clearBulkUpload.match)), actions$.pipe(filter(pusherBatchStatusUpdate.match), filter((action) => action.payload.batchId === batchId)), actions$.pipe(filter(fetchBulkUploadBatchDetailsSuccess.match), filter((action) => action.payload.batchId === batchId)))), switchMap(() => zeniAPI
|
|
31
31
|
.getJSON(`${zeniAPI.apiEndPoints.communicationAgentMicroServiceBaseUrl}/1.0/batches/${batchId}`)
|
|
32
32
|
.pipe(mergeMap((response) => {
|
|
33
33
|
/** Same batch-details URL; polls until `status` is completed (Pusher may win first). */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { toURL } from '../../../commonPayloadTypes/urlPayload';
|
|
2
2
|
import { getTransactionPayloadAmount, } from '../../../entity/transaction/payloadTypes/transactionPayload';
|
|
3
|
+
import { toBatchFileStatus, toBatchStatusValue, toMatchSource, } from '../types/missingReceiptsViewState';
|
|
3
4
|
// -- Converter functions --
|
|
4
5
|
/**
|
|
5
6
|
* Maps batch-details API `files[].status` strings to canonical {@link BatchFileStatus}.
|
|
@@ -7,8 +8,8 @@ import { getTransactionPayloadAmount, } from '../../../entity/transaction/payloa
|
|
|
7
8
|
* holds untyped status values.
|
|
8
9
|
*/
|
|
9
10
|
export function parseBatchFileStatus(raw) {
|
|
10
|
-
const
|
|
11
|
-
switch (
|
|
11
|
+
const normalizedStatus = raw.trim().toLowerCase().replace(/-/g, '_');
|
|
12
|
+
switch (normalizedStatus) {
|
|
12
13
|
case 'exact_match':
|
|
13
14
|
case 'matched':
|
|
14
15
|
return 'exact_match';
|
|
@@ -30,9 +31,9 @@ export function parseBatchFileStatus(raw) {
|
|
|
30
31
|
export function toBatchFile(payload, filesEndPoint) {
|
|
31
32
|
return {
|
|
32
33
|
attachmentId: payload.attachment_id,
|
|
33
|
-
candidates: payload.candidates?.map((
|
|
34
|
-
transactionId:
|
|
35
|
-
matchScore:
|
|
34
|
+
candidates: payload.candidates?.map((candidate) => ({
|
|
35
|
+
transactionId: candidate.transaction_id,
|
|
36
|
+
matchScore: candidate.match_score,
|
|
36
37
|
})),
|
|
37
38
|
fileDownloadUrl: payload.file_id != null && filesEndPoint != null
|
|
38
39
|
? `${filesEndPoint}/1.0/files/${payload.file_id}?query=${encodeURIComponent(JSON.stringify({ download_file: true }))}`
|
|
@@ -40,9 +41,11 @@ export function toBatchFile(payload, filesEndPoint) {
|
|
|
40
41
|
fileId: payload.file_id,
|
|
41
42
|
filePreviewUrl: payload.file_preview_url,
|
|
42
43
|
filename: payload.filename,
|
|
43
|
-
matchSource: payload.match_source
|
|
44
|
+
matchSource: payload.match_source != null
|
|
45
|
+
? toMatchSource(payload.match_source)
|
|
46
|
+
: undefined,
|
|
44
47
|
matchedTransactionId: payload.matched_transaction?.transaction_id,
|
|
45
|
-
status:
|
|
48
|
+
status: toBatchFileStatus(payload.status),
|
|
46
49
|
};
|
|
47
50
|
}
|
|
48
51
|
export function extractTransactionPayloadsFromBatchFiles(files) {
|
|
@@ -92,8 +95,8 @@ export function toBatchDetails(payload, filesEndPoint) {
|
|
|
92
95
|
return {
|
|
93
96
|
batchId: payload.batch_id,
|
|
94
97
|
createdAt: payload.created_at,
|
|
95
|
-
files: payload.files.map((
|
|
96
|
-
status: payload.status,
|
|
98
|
+
files: payload.files.map((file) => toBatchFile(file, filesEndPoint)),
|
|
99
|
+
status: toBatchStatusValue(payload.status),
|
|
97
100
|
summary: toBatchSummary(payload.summary),
|
|
98
101
|
};
|
|
99
102
|
}
|
|
@@ -107,7 +110,7 @@ export function isBatchListStatusCompleted(status) {
|
|
|
107
110
|
* statuses for UI; only `completed` rows should trigger batch-details requests.
|
|
108
111
|
*/
|
|
109
112
|
export function filterBatchListItemsForBatchDetailsFetch(batches) {
|
|
110
|
-
return batches.filter((
|
|
113
|
+
return batches.filter((batch) => isBatchListStatusCompleted(batch.status));
|
|
111
114
|
}
|
|
112
115
|
/**
|
|
113
116
|
* Batch details API response `status` field — only completed payloads should be stored from
|
|
@@ -118,7 +121,7 @@ export function isBatchDetailsApiStatusCompleted(status) {
|
|
|
118
121
|
}
|
|
119
122
|
export function findBatchListItemForBatchId(batchListByPeriod, batchId) {
|
|
120
123
|
for (const list of Object.values(batchListByPeriod)) {
|
|
121
|
-
const found = list.find((
|
|
124
|
+
const found = list.find((batch) => batch.batchId === batchId);
|
|
122
125
|
if (found != null) {
|
|
123
126
|
return found;
|
|
124
127
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createSlice } from '@reduxjs/toolkit';
|
|
1
|
+
import { createAction, createSlice } from '@reduxjs/toolkit';
|
|
2
2
|
import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
|
|
3
3
|
import { MIN_MANUAL_TRANSACTION_SEARCH_LENGTH, } from '../types/missingReceiptsViewState';
|
|
4
4
|
export const getCompletedTransactionsCacheKey = (periodId, sortKey, sortOrder, subTab) => `completed-${subTab}-${sortKey}-${sortOrder === 'ascending' ? 'asc' : 'desc'}-${periodId}`;
|
|
@@ -51,6 +51,8 @@ export const initialState = {
|
|
|
51
51
|
return this.fetchState == 'Completed';
|
|
52
52
|
},
|
|
53
53
|
};
|
|
54
|
+
/** Epic trigger only; batch-details fetch is handled in epics. */
|
|
55
|
+
export const fetchBulkUploadBatchDetails = createAction('expenseAutomationMissingReceiptsView/fetchBulkUploadBatchDetails');
|
|
54
56
|
const expenseAutomationMissingReceiptsView = createSlice({
|
|
55
57
|
name: 'expenseAutomationMissingReceiptsView',
|
|
56
58
|
initialState,
|
|
@@ -154,8 +156,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
154
156
|
},
|
|
155
157
|
// -- Bulk Upload Actions --
|
|
156
158
|
bulkUploadReceipts: {
|
|
157
|
-
|
|
158
|
-
reducer(draft, _action) {
|
|
159
|
+
reducer(draft) {
|
|
159
160
|
draft.bulkUpload.phase = 'uploading';
|
|
160
161
|
draft.bulkUpload.uploadProgress = 0;
|
|
161
162
|
draft.bulkUpload.uploadStatus = {
|
|
@@ -172,6 +173,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
172
173
|
},
|
|
173
174
|
bulkUploadReceiptsSuccess(draft, action) {
|
|
174
175
|
draft.bulkUpload.currentBatchId = action.payload.batchId;
|
|
176
|
+
draft.bulkUpload.uploadProgress = 100;
|
|
175
177
|
draft.bulkUpload.uploadStatus = {
|
|
176
178
|
fetchState: 'Completed',
|
|
177
179
|
error: undefined,
|
|
@@ -205,18 +207,18 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
205
207
|
clearMissingReceiptsTabNavigation(draft) {
|
|
206
208
|
draft.pendingMissingReceiptsTabNavigation = null;
|
|
207
209
|
},
|
|
208
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
209
|
-
fetchBulkUploadBatchDetails(_draft) {
|
|
210
|
-
// trigger epic, no state change needed
|
|
211
|
-
},
|
|
212
210
|
fetchBulkUploadBatchDetailsSuccess(draft, action) {
|
|
213
211
|
const details = action.payload;
|
|
214
212
|
draft.bulkUpload.batchDetailsById[details.batchId] = details;
|
|
215
213
|
draft.bulkUpload.phase = 'completed';
|
|
216
214
|
},
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
215
|
+
fetchBulkUploadBatchDetailsFailure: {
|
|
216
|
+
reducer(draft) {
|
|
217
|
+
draft.bulkUpload.phase = 'completed';
|
|
218
|
+
},
|
|
219
|
+
prepare(payload) {
|
|
220
|
+
return { payload };
|
|
221
|
+
},
|
|
220
222
|
},
|
|
221
223
|
storeBatchDetails(draft, action) {
|
|
222
224
|
const details = action.payload;
|
|
@@ -247,8 +249,8 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
247
249
|
error: undefined,
|
|
248
250
|
};
|
|
249
251
|
},
|
|
250
|
-
fetchMoreBatchDetails(
|
|
251
|
-
|
|
252
|
+
fetchMoreBatchDetails(draft) {
|
|
253
|
+
draft.bulkUpload.batchDetailsPaginationState = {
|
|
252
254
|
fetchState: 'In-Progress',
|
|
253
255
|
error: undefined,
|
|
254
256
|
};
|
|
@@ -286,11 +288,11 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
286
288
|
};
|
|
287
289
|
},
|
|
288
290
|
prepare(input) {
|
|
289
|
-
const
|
|
291
|
+
const fetchOptions = input ?? {};
|
|
290
292
|
return {
|
|
291
293
|
payload: {
|
|
292
|
-
cacheOverride:
|
|
293
|
-
invalidateBatchDetailsCache:
|
|
294
|
+
cacheOverride: fetchOptions.cacheOverride === true,
|
|
295
|
+
invalidateBatchDetailsCache: fetchOptions.invalidateBatchDetailsCache === true,
|
|
294
296
|
},
|
|
295
297
|
};
|
|
296
298
|
},
|
|
@@ -324,8 +326,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
324
326
|
};
|
|
325
327
|
},
|
|
326
328
|
confirmBulkUploadMatch: {
|
|
327
|
-
|
|
328
|
-
reducer(draft, _action) {
|
|
329
|
+
reducer(draft) {
|
|
329
330
|
draft.bulkUpload.confirmMatchStatus = {
|
|
330
331
|
fetchState: 'In-Progress',
|
|
331
332
|
error: undefined,
|
|
@@ -343,7 +344,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
343
344
|
};
|
|
344
345
|
const details = draft.bulkUpload.batchDetailsById[batchId];
|
|
345
346
|
if (details != null) {
|
|
346
|
-
const file = details.files.find((
|
|
347
|
+
const file = details.files.find((batchFile) => batchFile.attachmentId === attachmentId);
|
|
347
348
|
if (file != null) {
|
|
348
349
|
const originalStatus = file.status;
|
|
349
350
|
file.status = 'exact_match';
|
|
@@ -426,7 +427,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
426
427
|
const { append, nextPageToken, results, totalCount } = action.payload;
|
|
427
428
|
if (append) {
|
|
428
429
|
const merged = [...draft.bulkUpload.manualSearch.results, ...results];
|
|
429
|
-
const byId = new Map(merged.map((
|
|
430
|
+
const byId = new Map(merged.map((result) => [result.transactionId, result]));
|
|
430
431
|
draft.bulkUpload.manualSearch.results = Array.from(byId.values());
|
|
431
432
|
}
|
|
432
433
|
else {
|
|
@@ -531,7 +532,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
|
|
|
531
532
|
});
|
|
532
533
|
export const { fetchMissingReceipts, fetchMissingReceiptsSuccess, fetchMissingReceiptsFailure, uploadMissingReceiptSuccess, updateMissingReceiptUploadState, updateMissingReceiptsUIState, markMissingReceiptAsDone, clearExpenseAutomationMissingReceiptsView,
|
|
533
534
|
// Bulk Upload
|
|
534
|
-
bulkUploadReceipts, updateBulkUploadProgress, bulkUploadReceiptsSuccess, bulkUploadReceiptsFailure, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, clearMissingReceiptsTabNavigation,
|
|
535
|
+
bulkUploadReceipts, updateBulkUploadProgress, bulkUploadReceiptsSuccess, bulkUploadReceiptsFailure, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, clearMissingReceiptsTabNavigation, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatchDetailsFailure, storeBatchDetails, batchDetailFetchFailed, setInitialBatchDetailsLoading, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, fetchBulkUploadBatches, fetchBulkUploadBatchesSuccess, fetchBulkUploadBatchesFailure, confirmBulkUploadMatch, confirmBulkUploadMatchSuccess, confirmBulkUploadMatchFailure, setBulkUploadResultsTab, setBulkUploadCompletedSubTab, setBulkUploadSortConfig, clearBulkUpload, searchTransactionsForManualMatch, searchTransactionsForManualMatchSuccess, searchTransactionsForManualMatchFailure, clearManualSearchResults, acknowledgeBulkUploadConfirmMatchComplete,
|
|
535
536
|
// Completed Transactions
|
|
536
537
|
fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, } = expenseAutomationMissingReceiptsView.actions;
|
|
537
538
|
export default expenseAutomationMissingReceiptsView.reducer;
|
|
@@ -64,45 +64,68 @@ export function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
64
64
|
* so we do not block the whole tab while other rows are not fetched yet.
|
|
65
65
|
*/
|
|
66
66
|
const primaryBatchIdFromDetailsOrder = getPrimaryBatchIdFromBatchListOrder(batchList, bulkUpload.batchDetailsById, bulkUpload.failedBatchDetailIds);
|
|
67
|
-
/**
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
/**
|
|
68
|
+
* During upload/matching, prefer `currentBatchId` only when it is not yet in the period
|
|
69
|
+
* `batchList` (true in-flight), or when its details are completed and include unmatched-tab work.
|
|
70
|
+
* Otherwise keep `primaryBatchIdFromDetailsOrder` so a new batch with no `possible_matches` /
|
|
71
|
+
* `no_match` rows yet does not vacate the primary column and push older batches into "past".
|
|
72
|
+
*/
|
|
73
|
+
const unmatchedSectionBatchId = (() => {
|
|
74
|
+
const phase = bulkUpload.phase;
|
|
75
|
+
if (phase !== 'matching' && phase !== 'uploading') {
|
|
76
|
+
return primaryBatchIdFromDetailsOrder;
|
|
77
|
+
}
|
|
78
|
+
const currentId = bulkUpload.currentBatchId;
|
|
79
|
+
if (currentId == null) {
|
|
80
|
+
return primaryBatchIdFromDetailsOrder;
|
|
81
|
+
}
|
|
82
|
+
const currentInBatchList = batchList.some((b) => b.batchId === currentId);
|
|
83
|
+
if (!currentInBatchList) {
|
|
84
|
+
return currentId;
|
|
85
|
+
}
|
|
86
|
+
const currentDetails = bulkUpload.batchDetailsById[currentId];
|
|
87
|
+
if (currentDetails != null &&
|
|
88
|
+
currentDetails.status === 'completed' &&
|
|
89
|
+
batchDetailsHasUnmatchedWork(currentDetails)) {
|
|
90
|
+
return currentId;
|
|
91
|
+
}
|
|
92
|
+
return primaryBatchIdFromDetailsOrder;
|
|
93
|
+
})();
|
|
94
|
+
const completedBatchesInApiOrder = batchList.filter((batchListItem) => isBatchListStatusCompleted(batchListItem.status));
|
|
72
95
|
const currentBatchDetails = unmatchedSectionBatchId != null
|
|
73
96
|
? bulkUpload.batchDetailsById[unmatchedSectionBatchId]
|
|
74
97
|
: undefined;
|
|
75
98
|
const resolvedFiles = currentBatchDetails?.files.map((file) => resolveBatchFile(file, currentBatchDetails.batchId, transactionState));
|
|
76
99
|
const failedIds = new Set(bulkUpload.failedBatchDetailIds);
|
|
77
|
-
const hasMoreBatchDetails = completedBatchesInApiOrder.some((
|
|
78
|
-
!failedIds.has(
|
|
100
|
+
const hasMoreBatchDetails = completedBatchesInApiOrder.some((batchListItem) => bulkUpload.batchDetailsById[batchListItem.batchId] == null &&
|
|
101
|
+
!failedIds.has(batchListItem.batchId));
|
|
79
102
|
const getSortValue = (file) => {
|
|
80
|
-
const
|
|
81
|
-
if (
|
|
103
|
+
const matchedTransaction = file.matchedTransaction;
|
|
104
|
+
if (matchedTransaction == null) {
|
|
82
105
|
return null;
|
|
83
106
|
}
|
|
84
107
|
switch (bulkUpload.sortKey) {
|
|
85
108
|
case 'vendor':
|
|
86
|
-
return (
|
|
109
|
+
return (matchedTransaction.vendorName ?? matchedTransaction.description)?.toLowerCase() ?? null;
|
|
87
110
|
case 'category': {
|
|
88
|
-
const line =
|
|
111
|
+
const line = matchedTransaction.lines?.[0];
|
|
89
112
|
return line?.account?.accountName?.toLowerCase() ?? null;
|
|
90
113
|
}
|
|
91
114
|
case 'class': {
|
|
92
|
-
const line =
|
|
115
|
+
const line = matchedTransaction.lines?.[0];
|
|
93
116
|
return line?.class?.className?.toLowerCase() ?? null;
|
|
94
117
|
}
|
|
95
118
|
case 'date':
|
|
96
|
-
return
|
|
119
|
+
return matchedTransaction.date.valueOf();
|
|
97
120
|
case 'amount':
|
|
98
|
-
return
|
|
121
|
+
return matchedTransaction.amount.amount;
|
|
99
122
|
default:
|
|
100
123
|
return null;
|
|
101
124
|
}
|
|
102
125
|
};
|
|
103
126
|
const bulkUploadSortDirection = bulkUpload.sortOrder === 'ascending' ? 'asc' : 'desc';
|
|
104
|
-
const matchedFiles = orderBy(resolvedFiles?.filter((
|
|
105
|
-
const unmatchedFiles = orderBy(resolvedFiles?.filter((
|
|
127
|
+
const matchedFiles = orderBy(resolvedFiles?.filter((resolvedFile) => resolvedFile.status === 'exact_match') ?? [], getSortValue, bulkUploadSortDirection);
|
|
128
|
+
const unmatchedFiles = orderBy(resolvedFiles?.filter((resolvedFile) => isUnmatchedTabFileStatus(resolvedFile.status)) ?? [], getSortValue, bulkUploadSortDirection);
|
|
106
129
|
const progress = currentBatchStatus != null
|
|
107
130
|
? {
|
|
108
131
|
...currentBatchStatus.progress,
|
|
@@ -119,16 +142,16 @@ export function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
119
142
|
* that has details loaded (otherwise past is empty and receipts vanish from the UI).
|
|
120
143
|
*/
|
|
121
144
|
const pastBatches = unmatchedSectionBatchId != null
|
|
122
|
-
? batchList.filter((
|
|
145
|
+
? batchList.filter((batchListItem) => batchListItem.batchId !== unmatchedSectionBatchId)
|
|
123
146
|
: batchList;
|
|
124
|
-
const pastUnmatchedFiles = pastBatches.flatMap((
|
|
125
|
-
const details = bulkUpload.batchDetailsById[
|
|
147
|
+
const pastUnmatchedFiles = pastBatches.flatMap((pastBatch) => {
|
|
148
|
+
const details = bulkUpload.batchDetailsById[pastBatch.batchId];
|
|
126
149
|
if (details == null) {
|
|
127
150
|
return [];
|
|
128
151
|
}
|
|
129
152
|
return details.files
|
|
130
|
-
.filter((
|
|
131
|
-
.map((
|
|
153
|
+
.filter((batchFile) => isUnmatchedTabFileStatus(batchFile.status))
|
|
154
|
+
.map((batchFile) => resolveBatchFile(batchFile, pastBatch.batchId, transactionState));
|
|
132
155
|
});
|
|
133
156
|
const completedTransactionsCacheKey = monthYearPeriodId != null
|
|
134
157
|
? getCompletedTransactionsCacheKey(monthYearPeriodId, bulkUpload.sortKey, bulkUpload.sortOrder, bulkUpload.completedSubTab)
|
|
@@ -147,11 +170,11 @@ export function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
147
170
|
summary: currentBatchDetails.summary,
|
|
148
171
|
}
|
|
149
172
|
: undefined;
|
|
150
|
-
const manualSearchResults = bulkUpload.manualSearch.results.map((
|
|
151
|
-
const
|
|
173
|
+
const manualSearchResults = bulkUpload.manualSearch.results.map((result) => {
|
|
174
|
+
const transaction = getSupportedTransactionById(transactionState, result.transactionId);
|
|
152
175
|
return {
|
|
153
|
-
...
|
|
154
|
-
vendorLogo:
|
|
176
|
+
...result,
|
|
177
|
+
vendorLogo: result.vendorLogo ?? transaction?.logo?.href,
|
|
155
178
|
};
|
|
156
179
|
});
|
|
157
180
|
return {
|
|
@@ -201,7 +224,7 @@ export function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
201
224
|
};
|
|
202
225
|
}
|
|
203
226
|
function batchDetailsHasUnmatchedWork(details) {
|
|
204
|
-
return details.files.some((
|
|
227
|
+
return details.files.some((file) => isUnmatchedTabFileStatus(file.status));
|
|
205
228
|
}
|
|
206
229
|
/** List row summary before batch details load — aligns with unmatched / possible-match work. */
|
|
207
230
|
function batchListItemHasUnmatchedWork(batch) {
|
|
@@ -218,17 +241,17 @@ function batchListItemHasUnmatchedWork(batch) {
|
|
|
218
241
|
*/
|
|
219
242
|
function getPrimaryBatchIdFromBatchListOrder(batchListInPlatformOrder, batchDetailsById, failedBatchDetailIds) {
|
|
220
243
|
const failedIds = new Set(failedBatchDetailIds);
|
|
221
|
-
const anyCompletedBatchHasUnmatchedWork = batchListInPlatformOrder.some((
|
|
222
|
-
if (failedIds.has(
|
|
244
|
+
const anyCompletedBatchHasUnmatchedWork = batchListInPlatformOrder.some((batch) => {
|
|
245
|
+
if (failedIds.has(batch.batchId)) {
|
|
223
246
|
return false;
|
|
224
247
|
}
|
|
225
|
-
const
|
|
226
|
-
if (
|
|
227
|
-
|
|
228
|
-
batchDetailsHasUnmatchedWork(
|
|
248
|
+
const details = batchDetailsById[batch.batchId];
|
|
249
|
+
if (details != null &&
|
|
250
|
+
details.status === 'completed' &&
|
|
251
|
+
batchDetailsHasUnmatchedWork(details)) {
|
|
229
252
|
return true;
|
|
230
253
|
}
|
|
231
|
-
return
|
|
254
|
+
return details == null && batchListItemHasUnmatchedWork(batch);
|
|
232
255
|
});
|
|
233
256
|
for (const batch of batchListInPlatformOrder) {
|
|
234
257
|
if (failedIds.has(batch.batchId)) {
|
|
@@ -265,7 +288,7 @@ function resolveBatchFile(file, batchId, transactionState) {
|
|
|
265
288
|
? { transaction, matchScore: ref.matchScore }
|
|
266
289
|
: undefined;
|
|
267
290
|
})
|
|
268
|
-
.filter((
|
|
291
|
+
.filter((candidate) => candidate != null);
|
|
269
292
|
return {
|
|
270
293
|
attachmentId: file.attachmentId,
|
|
271
294
|
batchId,
|
|
@@ -13,7 +13,36 @@ export const toMissingReceiptsSortKey = (v) => stringToUnion(v, MISSING_RECEIPTS
|
|
|
13
13
|
* Kept in sync with `ManualSearchInput` in web-components (fires search only when length ≥ this).
|
|
14
14
|
*/
|
|
15
15
|
export const MIN_MANUAL_TRANSACTION_SEARCH_LENGTH = 2;
|
|
16
|
+
const BATCH_STATUS_VALUES = ['pending', 'processing', 'completed'];
|
|
17
|
+
export const toBatchStatusValue = (v) => stringToUnion(v.trim().toLowerCase(), BATCH_STATUS_VALUES);
|
|
18
|
+
/** Canonical batch file statuses (API ingress may use aliases; see `parseBatchFileStatus`). */
|
|
19
|
+
export const BATCH_FILE_STATUSES = [
|
|
20
|
+
'exact_match',
|
|
21
|
+
'possible_matches',
|
|
22
|
+
'no_match',
|
|
23
|
+
'failed',
|
|
24
|
+
];
|
|
25
|
+
export const toBatchFileStatus = (v) => stringToUnion(v.trim().toLowerCase().replace(/-/g, '_'), BATCH_FILE_STATUSES);
|
|
26
|
+
const UNMATCHED_TAB_FILE_STATUSES = ['possible_matches', 'no_match'];
|
|
16
27
|
/** True for files that belong in the Unmatched tab (possible matches or no match). */
|
|
17
28
|
export function isUnmatchedTabFileStatus(status) {
|
|
18
|
-
return status
|
|
29
|
+
return UNMATCHED_TAB_FILE_STATUSES.includes(status);
|
|
19
30
|
}
|
|
31
|
+
const BULK_UPLOAD_PHASES = ['idle', 'uploading', 'matching', 'completed'];
|
|
32
|
+
export const toBulkUploadPhase = (v) => stringToUnion(v.trim().toLowerCase(), BULK_UPLOAD_PHASES);
|
|
33
|
+
const BULK_UPLOAD_RESULTS_TABS = ['completed', 'unmatched'];
|
|
34
|
+
export const toBulkUploadResultsTab = (v) => stringToUnion(v.trim().toLowerCase(), BULK_UPLOAD_RESULTS_TABS);
|
|
35
|
+
const MISSING_RECEIPTS_TABS = ['missing', 'completed', 'unmatched'];
|
|
36
|
+
export const toMissingReceiptsTab = (v) => stringToUnion(v.trim().toLowerCase(), MISSING_RECEIPTS_TABS);
|
|
37
|
+
const COMPLETED_SUB_TABS = ['all', 'ai_accountant', 'manual'];
|
|
38
|
+
export const toCompletedSubTab = (v) => stringToUnion(v.trim().toLowerCase(), COMPLETED_SUB_TABS);
|
|
39
|
+
const MATCH_SOURCES = ['ai', 'manual'];
|
|
40
|
+
export const toMatchSource = (v) => stringToUnion(v.trim().toLowerCase(), MATCH_SOURCES);
|
|
41
|
+
const BULK_UPLOAD_SORT_KEYS = [
|
|
42
|
+
'amount',
|
|
43
|
+
'category',
|
|
44
|
+
'class',
|
|
45
|
+
'date',
|
|
46
|
+
'vendor',
|
|
47
|
+
];
|
|
48
|
+
export const toBulkUploadSortKey = (v) => stringToUnion(v.trim().toLowerCase(), BULK_UPLOAD_SORT_KEYS);
|
package/lib/index.d.ts
CHANGED
|
@@ -281,7 +281,7 @@ import { getExpenseAutomationReconciliationView, isAccountReconReport } from './
|
|
|
281
281
|
import { getExpenseAutomationTransactionView } from './view/expenseAutomationView/selectors/transactionCategorizationSelector';
|
|
282
282
|
import { FluxAnalysisActionType, FluxAnalysisReviewStatus, FluxAnalysisSortKey, FluxAnalysisViewUIState, FluxBalancesByMonth } from './view/expenseAutomationView/types/fluxAnalysisViewState';
|
|
283
283
|
import { AccountSettingsLocalData, JEScheduleLocalData } from './view/expenseAutomationView/types/jeSchedulesViewState';
|
|
284
|
-
import { BatchDetails, BatchFile, BatchFileStatus, BatchListItem, BatchStatus, BatchStatusValue, BatchSummary, BulkUploadPhase, BulkUploadResultsTab, BulkUploadSortKey, BulkUploadState, CandidateRef, CompletedSubTab, isUnmatchedTabFileStatus, MatchCandidate, MatchSource, MissingReceiptsTab } from './view/expenseAutomationView/types/missingReceiptsViewState';
|
|
284
|
+
import { BATCH_FILE_STATUSES, BatchDetails, BatchFile, BatchFileStatus, BatchListItem, BatchStatus, BatchStatusValue, BatchSummary, BulkUploadPhase, BulkUploadResultsTab, BulkUploadSortKey, BulkUploadState, CandidateRef, CompletedSubTab, isUnmatchedTabFileStatus, MatchCandidate, MatchSource, MissingReceiptsTab, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toCompletedSubTab, toMatchSource, toMissingReceiptsTab } from './view/expenseAutomationView/types/missingReceiptsViewState';
|
|
285
285
|
import { CompletedTransactionsSelectorData, ResolvedBatchFile, ResolvedCandidate, ResolvedBatchDetails } from './view/expenseAutomationView/selectorTypes/missingReceiptsSelectorTypes';
|
|
286
286
|
import { MissingReceiptsSortKey as ExpenseAutomationMissingReceiptsSortKey, MissingReceiptsViewState as ExpenseAutomationMissingReceiptsViewState, MissingReceiptsViewUIState as ExpenseAutomationMissingReceiptsViewUIState, toMissingReceiptsSortKey as toExpenseAutomationMissingReceiptsSortKey } from './view/expenseAutomationView/types/missingReceiptsViewState';
|
|
287
287
|
import { AccountReconciliationLocalData, ReconciliationViewTabType as ExpenseAutomationReconciliationViewTab, ReconReconcileSortKey, ReconReviewSortKey, ReconciliationReconcileTabLocalData, ReconciliationReviewTabLocalData, SaveReconcileDetailActionPayload as SaveExpenseAutomationReconciliationActionType, toReconciliationTabsType } from './view/expenseAutomationView/types/reconciliationViewState';
|
|
@@ -623,7 +623,7 @@ export { TransactionsOrder, COABalancesSliceOrder, EntityOrder, Section, Section
|
|
|
623
623
|
export { ClassesViewSelectorReportV2 };
|
|
624
624
|
export { BalancesTimeseries, TrendTimeseries, BalanceKind };
|
|
625
625
|
export { fetchMonthEndCloseChecks, fetchMonthClosePerformanceTrend, MonthClosePerformanceTrend, MonthEndCloseCheck, getMonthEndCloseChecksViewByTenantId, MonthEndCloseChecksView, MonthEndCloseCheckFrequency, MonthCloseCheckMetrics, ALL_MONTH_END_CLOSE_CHECKS_FREQUENCY, MonthEndAuditSummary, };
|
|
626
|
-
export { ExpenseAutomationViewSelector, ExpenseAutomationStepDetails, ExpenseAutomationViewType, ExpenseAutomationMissingReceiptsViewSelector, BulkUploadSelectorData, ExpenseAutomationFluxAnalysisViewSelector, FluxAnalysisVendorView, FluxAnalysisViewSectionReport, FluxVendorAccountsAndClassesView, ExpenseAutomationMissingReceiptsViewUIState, ExpenseAutomationMissingReceiptsViewState, ExpenseAutomationViewState, ExpenseAutomationTransactionsTab, ExpenseAutomationMissingReceiptsSortKey, BatchDetails, BatchFile, BatchFileStatus, BatchListItem, isUnmatchedTabFileStatus, 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, acknowledgeBulkUploadConfirmMatchComplete, fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, fetchFluxAnalysisView, clearExpenseAutomationFluxAnalysisView, updateOperatingExpensesIdsForReview as updateFluxOperatingExpensesIdsForReview, updateSelectedSectionIdsForReview as updateFluxAnalysisSelectedSectionIdsForReview, reviewFluxAnalysisView, updateExpenseAutomationMissingReceiptUploadState, updateExpenseAutomationMissingReceiptsUIState, updateTransactionCategorizationUploadReceiptState, uploadTransactionCategorizationReceiptSuccess, 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, };
|
|
626
|
+
export { ExpenseAutomationViewSelector, ExpenseAutomationStepDetails, ExpenseAutomationViewType, ExpenseAutomationMissingReceiptsViewSelector, BulkUploadSelectorData, ExpenseAutomationFluxAnalysisViewSelector, FluxAnalysisVendorView, FluxAnalysisViewSectionReport, FluxVendorAccountsAndClassesView, ExpenseAutomationMissingReceiptsViewUIState, ExpenseAutomationMissingReceiptsViewState, ExpenseAutomationViewState, ExpenseAutomationTransactionsTab, ExpenseAutomationMissingReceiptsSortKey, BATCH_FILE_STATUSES, BatchDetails, BatchFile, BatchFileStatus, BatchListItem, isUnmatchedTabFileStatus, BatchStatus, BatchStatusValue, BatchSummary, BulkUploadPhase, BulkUploadResultsTab, BulkUploadSortKey, BulkUploadState, CandidateRef, CompletedSubTab, CompletedTransactionsSelectorData, MatchCandidate, MatchSource, MissingReceiptsTab, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toCompletedSubTab, toMatchSource, toMissingReceiptsTab, 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, acknowledgeBulkUploadConfirmMatchComplete, fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, fetchFluxAnalysisView, clearExpenseAutomationFluxAnalysisView, updateOperatingExpensesIdsForReview as updateFluxOperatingExpensesIdsForReview, updateSelectedSectionIdsForReview as updateFluxAnalysisSelectedSectionIdsForReview, reviewFluxAnalysisView, updateExpenseAutomationMissingReceiptUploadState, updateExpenseAutomationMissingReceiptsUIState, updateTransactionCategorizationUploadReceiptState, uploadTransactionCategorizationReceiptSuccess, 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, };
|
|
627
627
|
export { JEScheduleLocalData };
|
|
628
628
|
export { ExpenseAutomationJESchedulesViewSelector, JEAccountSettingsView, JEScheduledTransactionWithFailedEntries, };
|
|
629
629
|
export { fetchTransactionCategorization, fetchTransactionCategorizationView, updateTransactionCategorizationUIState, updateSelectedCheckboxTransactionIds, setEntityRecommendationForLineIdsForCategorization, initializeTransactionCategorizationViewLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, updateSelectedTransactionId, syncTransactionCategorizationFromDetailSave, backgroundRefetchReviewTab, clearExpenseAutomationTransactionsView, TransactionsSortKey, toTransactionsSortKey, TransactionsTab, TransactionCategorizationLineItemData, TransactionReviewLocalData, SupportedTransactionCategorization, ExpenseAutomationTransactionsViewState, ExpenseAutomationTransactionsViewUIState, ExpenseAutomationTransactionViewSelector, TransactionReviewLocalDataSelectorView, };
|
|
@@ -870,5 +870,6 @@ export { fetchTreasuryTaxLetterList } from './view/spendManagement/treasury/trea
|
|
|
870
870
|
export { TreasuryTaxLettersSelectorView, getTreasuryTaxLetters, } from './view/spendManagement/treasury/treasuryTaxLetterList/treasuryTaxLetterListSelector';
|
|
871
871
|
export { TreasuryTransactionStatus } from './view/spendManagement/treasury/treasuryList/treasuryDetailPayload';
|
|
872
872
|
export type { TransactionActivityLog } from './entity/transactionActivityLog/transactionActivityLogState';
|
|
873
|
+
export { BULK_UPLOAD_BAR_COMPLETE_HOLD_MS } from './view/expenseAutomationView/bulkUploadTiming';
|
|
873
874
|
export { fetchTransactionActivityLog } from './view/transactionActivityLogView/transactionActivityLogViewReducer';
|
|
874
875
|
export { TransactionActivityLogViewSelectorView, getTransactionActivityLogView, } from './view/transactionActivityLogView/transactionActivityLogViewSelector';
|