@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
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BULK_UPLOAD_BAR_COMPLETE_HOLD_MS = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* After upload API success, hold the bar at 100% this long before transitioning to matching,
|
|
6
|
+
* so the fill animation can complete without an abrupt swap to the auto-matching banner.
|
|
7
|
+
*/
|
|
8
|
+
exports.BULK_UPLOAD_BAR_COMPLETE_HOLD_MS = 400;
|
|
@@ -12,4 +12,7 @@ export declare const bulkUploadReceiptsEpic: (actions$: ActionsObservable<Action
|
|
|
12
12
|
error: import("../../../../responsePayload").ZeniAPIStatus;
|
|
13
13
|
};
|
|
14
14
|
type: "expenseAutomationMissingReceiptsView/bulkUploadReceiptsFailure";
|
|
15
|
+
} | {
|
|
16
|
+
payload: number;
|
|
17
|
+
type: "expenseAutomationMissingReceiptsView/updateBulkUploadProgress";
|
|
15
18
|
}>;
|
|
@@ -4,6 +4,7 @@ exports.bulkUploadReceiptsEpic = void 0;
|
|
|
4
4
|
const rxjs_1 = require("rxjs");
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
6
|
const responsePayload_1 = require("../../../../responsePayload");
|
|
7
|
+
const bulkUploadTiming_1 = require("../../bulkUploadTiming");
|
|
7
8
|
const missingReceiptsViewReducer_1 = require("../../reducers/missingReceiptsViewReducer");
|
|
8
9
|
const bulkUploadReceiptsEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.bulkUploadReceipts.match), (0, operators_1.mergeMap)((action) => {
|
|
9
10
|
const { files } = action.payload;
|
|
@@ -21,7 +22,7 @@ const bulkUploadReceiptsEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0,
|
|
|
21
22
|
error: (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Bulk upload succeeded but batch_id was missing or empty.'),
|
|
22
23
|
}));
|
|
23
24
|
}
|
|
24
|
-
return (0, rxjs_1.of)((0, missingReceiptsViewReducer_1.bulkUploadReceiptsSuccess)({ batchId }));
|
|
25
|
+
return (0, rxjs_1.concat)((0, rxjs_1.of)((0, missingReceiptsViewReducer_1.updateBulkUploadProgress)(100)), (0, rxjs_1.timer)(bulkUploadTiming_1.BULK_UPLOAD_BAR_COMPLETE_HOLD_MS).pipe((0, operators_1.mergeMap)(() => (0, rxjs_1.of)((0, missingReceiptsViewReducer_1.bulkUploadReceiptsSuccess)({ batchId })))));
|
|
25
26
|
}
|
|
26
27
|
return (0, rxjs_1.of)((0, missingReceiptsViewReducer_1.bulkUploadReceiptsFailure)({ error: response.status }));
|
|
27
28
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, missingReceiptsViewReducer_1.bulkUploadReceiptsFailure)({
|
package/lib/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js
CHANGED
|
@@ -18,14 +18,14 @@ const transactionsViewState_1 = require("../../types/transactionsViewState");
|
|
|
18
18
|
exports.MANUAL_TRANSACTION_SEARCH_AUTO_CATEGORIZED = false;
|
|
19
19
|
const searchTransactionsForManualMatchEpic = (actions$, state$, zeniAPI) => {
|
|
20
20
|
const searchActions$ = actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.searchTransactionsForManualMatch.match));
|
|
21
|
-
const pagination$ = searchActions$.pipe((0, operators_1.filter)((
|
|
21
|
+
const pagination$ = searchActions$.pipe((0, operators_1.filter)((action) => action.payload.pageToken != null));
|
|
22
22
|
/**
|
|
23
23
|
* No API for empty or 1-char queries; immediate merge so switchMap cancels any in-flight HTTP.
|
|
24
24
|
*/
|
|
25
|
-
const newSearchTooShortOrClear$ = searchActions$.pipe((0, operators_1.filter)((
|
|
26
|
-
|
|
27
|
-
const newSearchDebounced$ = searchActions$.pipe((0, operators_1.filter)((
|
|
28
|
-
|
|
25
|
+
const newSearchTooShortOrClear$ = searchActions$.pipe((0, operators_1.filter)((action) => action.payload.pageToken == null &&
|
|
26
|
+
action.payload.query.trim().length < 2));
|
|
27
|
+
const newSearchDebounced$ = searchActions$.pipe((0, operators_1.filter)((action) => action.payload.pageToken == null &&
|
|
28
|
+
action.payload.query.trim().length >= 2), (0, operators_1.debounceTime)(300));
|
|
29
29
|
return (0, rxjs_1.merge)(pagination$, newSearchTooShortOrClear$, newSearchDebounced$).pipe((0, operators_1.switchMap)((action) => {
|
|
30
30
|
const { query, pageToken } = action.payload;
|
|
31
31
|
if (pageToken == null &&
|
package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js
CHANGED
|
@@ -31,7 +31,7 @@ exports.pusherBatchStatusCompletionEpic = pusherBatchStatusCompletionEpic;
|
|
|
31
31
|
const pollBulkUploadBatchStatusEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.bulkUploadReceiptsSuccess.match), (0, operators_1.mergeMap)((action) => {
|
|
32
32
|
const { batchId } = action.payload;
|
|
33
33
|
let pollErrorNotified = false;
|
|
34
|
-
return (0, rxjs_1.timer)(FALLBACK_FIRST_DELAY_MS, FALLBACK_POLL_INTERVAL_MS).pipe((0, operators_1.takeUntil)((0, rxjs_1.merge)(actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.clearBulkUpload.match)), actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.pusherBatchStatusUpdate.match), (0, operators_1.filter)((
|
|
34
|
+
return (0, rxjs_1.timer)(FALLBACK_FIRST_DELAY_MS, FALLBACK_POLL_INTERVAL_MS).pipe((0, operators_1.takeUntil)((0, rxjs_1.merge)(actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.clearBulkUpload.match)), actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.pusherBatchStatusUpdate.match), (0, operators_1.filter)((action) => action.payload.batchId === batchId)), actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.fetchBulkUploadBatchDetailsSuccess.match), (0, operators_1.filter)((action) => action.payload.batchId === batchId)))), (0, operators_1.switchMap)(() => zeniAPI
|
|
35
35
|
.getJSON(`${zeniAPI.apiEndPoints.communicationAgentMicroServiceBaseUrl}/1.0/batches/${batchId}`)
|
|
36
36
|
.pipe((0, operators_1.mergeMap)((response) => {
|
|
37
37
|
/** Same batch-details URL; polls until `status` is completed (Pusher may win first). */
|
|
@@ -3,7 +3,7 @@ import { TransactionPayload } from '../../../entity/transaction/payloadTypes/tra
|
|
|
3
3
|
import { SupportedTransactionPayload } from '../../../entity/transaction/transactionState';
|
|
4
4
|
import { ZeniAPIResponse } from '../../../responsePayload';
|
|
5
5
|
import type { MonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
|
|
6
|
-
import type
|
|
6
|
+
import { type BatchDetails, type BatchFile, type BatchFileStatus, type BatchListItem, type BatchStatus, type BatchSummary, type ManualSearchResult } from '../types/missingReceiptsViewState';
|
|
7
7
|
export interface MissingReceiptsQueryPayload {
|
|
8
8
|
end_date: string;
|
|
9
9
|
is_attachment_missing_only: boolean;
|
|
@@ -14,6 +14,7 @@ exports.toBatchListItem = toBatchListItem;
|
|
|
14
14
|
exports.supportedTransactionPayloadToManualSearchResult = supportedTransactionPayloadToManualSearchResult;
|
|
15
15
|
const urlPayload_1 = require("../../../commonPayloadTypes/urlPayload");
|
|
16
16
|
const transactionPayload_1 = require("../../../entity/transaction/payloadTypes/transactionPayload");
|
|
17
|
+
const missingReceiptsViewState_1 = require("../types/missingReceiptsViewState");
|
|
17
18
|
// -- Converter functions --
|
|
18
19
|
/**
|
|
19
20
|
* Maps batch-details API `files[].status` strings to canonical {@link BatchFileStatus}.
|
|
@@ -21,8 +22,8 @@ const transactionPayload_1 = require("../../../entity/transaction/payloadTypes/t
|
|
|
21
22
|
* holds untyped status values.
|
|
22
23
|
*/
|
|
23
24
|
function parseBatchFileStatus(raw) {
|
|
24
|
-
const
|
|
25
|
-
switch (
|
|
25
|
+
const normalizedStatus = raw.trim().toLowerCase().replace(/-/g, '_');
|
|
26
|
+
switch (normalizedStatus) {
|
|
26
27
|
case 'exact_match':
|
|
27
28
|
case 'matched':
|
|
28
29
|
return 'exact_match';
|
|
@@ -44,9 +45,9 @@ function parseBatchFileStatus(raw) {
|
|
|
44
45
|
function toBatchFile(payload, filesEndPoint) {
|
|
45
46
|
return {
|
|
46
47
|
attachmentId: payload.attachment_id,
|
|
47
|
-
candidates: payload.candidates?.map((
|
|
48
|
-
transactionId:
|
|
49
|
-
matchScore:
|
|
48
|
+
candidates: payload.candidates?.map((candidate) => ({
|
|
49
|
+
transactionId: candidate.transaction_id,
|
|
50
|
+
matchScore: candidate.match_score,
|
|
50
51
|
})),
|
|
51
52
|
fileDownloadUrl: payload.file_id != null && filesEndPoint != null
|
|
52
53
|
? `${filesEndPoint}/1.0/files/${payload.file_id}?query=${encodeURIComponent(JSON.stringify({ download_file: true }))}`
|
|
@@ -54,9 +55,11 @@ function toBatchFile(payload, filesEndPoint) {
|
|
|
54
55
|
fileId: payload.file_id,
|
|
55
56
|
filePreviewUrl: payload.file_preview_url,
|
|
56
57
|
filename: payload.filename,
|
|
57
|
-
matchSource: payload.match_source
|
|
58
|
+
matchSource: payload.match_source != null
|
|
59
|
+
? (0, missingReceiptsViewState_1.toMatchSource)(payload.match_source)
|
|
60
|
+
: undefined,
|
|
58
61
|
matchedTransactionId: payload.matched_transaction?.transaction_id,
|
|
59
|
-
status:
|
|
62
|
+
status: (0, missingReceiptsViewState_1.toBatchFileStatus)(payload.status),
|
|
60
63
|
};
|
|
61
64
|
}
|
|
62
65
|
function extractTransactionPayloadsFromBatchFiles(files) {
|
|
@@ -106,8 +109,8 @@ function toBatchDetails(payload, filesEndPoint) {
|
|
|
106
109
|
return {
|
|
107
110
|
batchId: payload.batch_id,
|
|
108
111
|
createdAt: payload.created_at,
|
|
109
|
-
files: payload.files.map((
|
|
110
|
-
status: payload.status,
|
|
112
|
+
files: payload.files.map((file) => toBatchFile(file, filesEndPoint)),
|
|
113
|
+
status: (0, missingReceiptsViewState_1.toBatchStatusValue)(payload.status),
|
|
111
114
|
summary: toBatchSummary(payload.summary),
|
|
112
115
|
};
|
|
113
116
|
}
|
|
@@ -121,7 +124,7 @@ function isBatchListStatusCompleted(status) {
|
|
|
121
124
|
* statuses for UI; only `completed` rows should trigger batch-details requests.
|
|
122
125
|
*/
|
|
123
126
|
function filterBatchListItemsForBatchDetailsFetch(batches) {
|
|
124
|
-
return batches.filter((
|
|
127
|
+
return batches.filter((batch) => isBatchListStatusCompleted(batch.status));
|
|
125
128
|
}
|
|
126
129
|
/**
|
|
127
130
|
* Batch details API response `status` field — only completed payloads should be stored from
|
|
@@ -132,7 +135,7 @@ function isBatchDetailsApiStatusCompleted(status) {
|
|
|
132
135
|
}
|
|
133
136
|
function findBatchListItemForBatchId(batchListByPeriod, batchId) {
|
|
134
137
|
for (const list of Object.values(batchListByPeriod)) {
|
|
135
|
-
const found = list.find((
|
|
138
|
+
const found = list.find((batch) => batch.batchId === batchId);
|
|
136
139
|
if (found != null) {
|
|
137
140
|
return found;
|
|
138
141
|
}
|
|
@@ -10,6 +10,8 @@ import type { MonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
|
|
|
10
10
|
export declare const getCompletedTransactionsCacheKey: (periodId: MonthYearPeriodId, sortKey: BulkUploadSortKey, sortOrder: SortOrder, subTab: CompletedSubTab) => string;
|
|
11
11
|
export declare const initialBulkUploadState: BulkUploadState;
|
|
12
12
|
export declare const initialState: MissingReceiptsViewState;
|
|
13
|
+
/** Epic trigger only; batch-details fetch is handled in epics. */
|
|
14
|
+
export declare const fetchBulkUploadBatchDetails: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationMissingReceiptsView/fetchBulkUploadBatchDetails">;
|
|
13
15
|
export declare const fetchMissingReceipts: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[period: TimePeriod, minimumTransactionAmount: Amount, cacheOverride?: any, refreshViewInBackground?: any], {
|
|
14
16
|
period: TimePeriod;
|
|
15
17
|
minimumTransactionAmount: Amount;
|
|
@@ -38,9 +40,11 @@ export declare const fetchMissingReceipts: import("@reduxjs/toolkit").ActionCrea
|
|
|
38
40
|
error: ZeniAPIStatus;
|
|
39
41
|
}, "expenseAutomationMissingReceiptsView/bulkUploadReceiptsFailure">, pusherBatchStatusUpdate: import("@reduxjs/toolkit").ActionCreatorWithPayload<BatchStatus, "expenseAutomationMissingReceiptsView/pusherBatchStatusUpdate">, requestMissingReceiptsTabNavigation: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
40
42
|
tab: BulkUploadResultsTab;
|
|
41
|
-
}, "expenseAutomationMissingReceiptsView/requestMissingReceiptsTabNavigation">, clearMissingReceiptsTabNavigation: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationMissingReceiptsView/clearMissingReceiptsTabNavigation">,
|
|
43
|
+
}, "expenseAutomationMissingReceiptsView/requestMissingReceiptsTabNavigation">, clearMissingReceiptsTabNavigation: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationMissingReceiptsView/clearMissingReceiptsTabNavigation">, fetchBulkUploadBatchDetailsSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<BatchDetails, "expenseAutomationMissingReceiptsView/fetchBulkUploadBatchDetailsSuccess">, fetchBulkUploadBatchDetailsFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: {
|
|
42
44
|
error: ZeniAPIStatus;
|
|
43
|
-
},
|
|
45
|
+
}], {
|
|
46
|
+
error: ZeniAPIStatus;
|
|
47
|
+
}, "expenseAutomationMissingReceiptsView/fetchBulkUploadBatchDetailsFailure", never, never>, storeBatchDetails: import("@reduxjs/toolkit").ActionCreatorWithPayload<BatchDetails, "expenseAutomationMissingReceiptsView/storeBatchDetails">, batchDetailFetchFailed: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
44
48
|
batchId: ID;
|
|
45
49
|
}, "expenseAutomationMissingReceiptsView/batchDetailFetchFailed">, setInitialBatchDetailsLoading: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationMissingReceiptsView/setInitialBatchDetailsLoading">, fetchMoreBatchDetails: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationMissingReceiptsView/fetchMoreBatchDetails">, fetchMoreBatchDetailsComplete: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationMissingReceiptsView/fetchMoreBatchDetailsComplete">, fetchMoreBatchDetailsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
46
50
|
error: ZeniAPIStatus;
|
|
@@ -68,7 +72,7 @@ export declare const fetchMissingReceipts: import("@reduxjs/toolkit").ActionCrea
|
|
|
68
72
|
transactionId: ID;
|
|
69
73
|
}, "expenseAutomationMissingReceiptsView/confirmBulkUploadMatchSuccess">, confirmBulkUploadMatchFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
70
74
|
error: ZeniAPIStatus;
|
|
71
|
-
}, "expenseAutomationMissingReceiptsView/confirmBulkUploadMatchFailure">, setBulkUploadResultsTab: import("@reduxjs/toolkit").ActionCreatorWithPayload<
|
|
75
|
+
}, "expenseAutomationMissingReceiptsView/confirmBulkUploadMatchFailure">, setBulkUploadResultsTab: import("@reduxjs/toolkit").ActionCreatorWithPayload<"completed" | "unmatched", "expenseAutomationMissingReceiptsView/setBulkUploadResultsTab">, setBulkUploadCompletedSubTab: import("@reduxjs/toolkit").ActionCreatorWithPayload<"all" | "manual" | "ai_accountant", "expenseAutomationMissingReceiptsView/setBulkUploadCompletedSubTab">, setBulkUploadSortConfig: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
72
76
|
sortKey: BulkUploadSortKey;
|
|
73
77
|
sortOrder: SortOrder;
|
|
74
78
|
}, "expenseAutomationMissingReceiptsView/setBulkUploadSortConfig">, clearBulkUpload: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationMissingReceiptsView/clearBulkUpload">, searchTransactionsForManualMatch: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[query: string, pageToken?: string | null | undefined], {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.fetchCompletedTransactionsFailure = exports.fetchCompletedTransactionsSuccess = exports.fetchCompletedTransactions = exports.acknowledgeBulkUploadConfirmMatchComplete = exports.clearManualSearchResults = exports.searchTransactionsForManualMatchFailure = exports.searchTransactionsForManualMatchSuccess = exports.searchTransactionsForManualMatch = exports.clearBulkUpload = exports.setBulkUploadSortConfig = exports.setBulkUploadCompletedSubTab = exports.setBulkUploadResultsTab = exports.confirmBulkUploadMatchFailure = exports.confirmBulkUploadMatchSuccess = exports.confirmBulkUploadMatch = exports.fetchBulkUploadBatchesFailure = exports.fetchBulkUploadBatchesSuccess = exports.fetchBulkUploadBatches = exports.fetchMoreBatchDetailsFailure = exports.fetchMoreBatchDetailsComplete = exports.fetchMoreBatchDetails = exports.setInitialBatchDetailsLoading = exports.batchDetailFetchFailed = exports.storeBatchDetails = exports.fetchBulkUploadBatchDetailsFailure = exports.fetchBulkUploadBatchDetailsSuccess = exports.
|
|
4
|
+
exports.fetchCompletedTransactionsFailure = exports.fetchCompletedTransactionsSuccess = exports.fetchCompletedTransactions = exports.acknowledgeBulkUploadConfirmMatchComplete = exports.clearManualSearchResults = exports.searchTransactionsForManualMatchFailure = exports.searchTransactionsForManualMatchSuccess = exports.searchTransactionsForManualMatch = exports.clearBulkUpload = exports.setBulkUploadSortConfig = exports.setBulkUploadCompletedSubTab = exports.setBulkUploadResultsTab = exports.confirmBulkUploadMatchFailure = exports.confirmBulkUploadMatchSuccess = exports.confirmBulkUploadMatch = exports.fetchBulkUploadBatchesFailure = exports.fetchBulkUploadBatchesSuccess = exports.fetchBulkUploadBatches = exports.fetchMoreBatchDetailsFailure = exports.fetchMoreBatchDetailsComplete = exports.fetchMoreBatchDetails = exports.setInitialBatchDetailsLoading = exports.batchDetailFetchFailed = exports.storeBatchDetails = exports.fetchBulkUploadBatchDetailsFailure = exports.fetchBulkUploadBatchDetailsSuccess = exports.clearMissingReceiptsTabNavigation = exports.requestMissingReceiptsTabNavigation = exports.pusherBatchStatusUpdate = exports.bulkUploadReceiptsFailure = exports.bulkUploadReceiptsSuccess = exports.updateBulkUploadProgress = exports.bulkUploadReceipts = exports.clearExpenseAutomationMissingReceiptsView = exports.markMissingReceiptAsDone = exports.updateMissingReceiptsUIState = exports.updateMissingReceiptUploadState = exports.uploadMissingReceiptSuccess = exports.fetchMissingReceiptsFailure = exports.fetchMissingReceiptsSuccess = exports.fetchMissingReceipts = exports.fetchBulkUploadBatchDetails = exports.initialState = exports.initialBulkUploadState = exports.getCompletedTransactionsCacheKey = void 0;
|
|
5
5
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
6
6
|
const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
|
|
7
7
|
const missingReceiptsViewState_1 = require("../types/missingReceiptsViewState");
|
|
@@ -56,6 +56,8 @@ exports.initialState = {
|
|
|
56
56
|
return this.fetchState == 'Completed';
|
|
57
57
|
},
|
|
58
58
|
};
|
|
59
|
+
/** Epic trigger only; batch-details fetch is handled in epics. */
|
|
60
|
+
exports.fetchBulkUploadBatchDetails = (0, toolkit_1.createAction)('expenseAutomationMissingReceiptsView/fetchBulkUploadBatchDetails');
|
|
59
61
|
const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
|
|
60
62
|
name: 'expenseAutomationMissingReceiptsView',
|
|
61
63
|
initialState: exports.initialState,
|
|
@@ -159,8 +161,7 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
|
|
|
159
161
|
},
|
|
160
162
|
// -- Bulk Upload Actions --
|
|
161
163
|
bulkUploadReceipts: {
|
|
162
|
-
|
|
163
|
-
reducer(draft, _action) {
|
|
164
|
+
reducer(draft) {
|
|
164
165
|
draft.bulkUpload.phase = 'uploading';
|
|
165
166
|
draft.bulkUpload.uploadProgress = 0;
|
|
166
167
|
draft.bulkUpload.uploadStatus = {
|
|
@@ -177,6 +178,7 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
|
|
|
177
178
|
},
|
|
178
179
|
bulkUploadReceiptsSuccess(draft, action) {
|
|
179
180
|
draft.bulkUpload.currentBatchId = action.payload.batchId;
|
|
181
|
+
draft.bulkUpload.uploadProgress = 100;
|
|
180
182
|
draft.bulkUpload.uploadStatus = {
|
|
181
183
|
fetchState: 'Completed',
|
|
182
184
|
error: undefined,
|
|
@@ -210,18 +212,18 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
|
|
|
210
212
|
clearMissingReceiptsTabNavigation(draft) {
|
|
211
213
|
draft.pendingMissingReceiptsTabNavigation = null;
|
|
212
214
|
},
|
|
213
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
214
|
-
fetchBulkUploadBatchDetails(_draft) {
|
|
215
|
-
// trigger epic, no state change needed
|
|
216
|
-
},
|
|
217
215
|
fetchBulkUploadBatchDetailsSuccess(draft, action) {
|
|
218
216
|
const details = action.payload;
|
|
219
217
|
draft.bulkUpload.batchDetailsById[details.batchId] = details;
|
|
220
218
|
draft.bulkUpload.phase = 'completed';
|
|
221
219
|
},
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
220
|
+
fetchBulkUploadBatchDetailsFailure: {
|
|
221
|
+
reducer(draft) {
|
|
222
|
+
draft.bulkUpload.phase = 'completed';
|
|
223
|
+
},
|
|
224
|
+
prepare(payload) {
|
|
225
|
+
return { payload };
|
|
226
|
+
},
|
|
225
227
|
},
|
|
226
228
|
storeBatchDetails(draft, action) {
|
|
227
229
|
const details = action.payload;
|
|
@@ -252,8 +254,8 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
|
|
|
252
254
|
error: undefined,
|
|
253
255
|
};
|
|
254
256
|
},
|
|
255
|
-
fetchMoreBatchDetails(
|
|
256
|
-
|
|
257
|
+
fetchMoreBatchDetails(draft) {
|
|
258
|
+
draft.bulkUpload.batchDetailsPaginationState = {
|
|
257
259
|
fetchState: 'In-Progress',
|
|
258
260
|
error: undefined,
|
|
259
261
|
};
|
|
@@ -291,11 +293,11 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
|
|
|
291
293
|
};
|
|
292
294
|
},
|
|
293
295
|
prepare(input) {
|
|
294
|
-
const
|
|
296
|
+
const fetchOptions = input ?? {};
|
|
295
297
|
return {
|
|
296
298
|
payload: {
|
|
297
|
-
cacheOverride:
|
|
298
|
-
invalidateBatchDetailsCache:
|
|
299
|
+
cacheOverride: fetchOptions.cacheOverride === true,
|
|
300
|
+
invalidateBatchDetailsCache: fetchOptions.invalidateBatchDetailsCache === true,
|
|
299
301
|
},
|
|
300
302
|
};
|
|
301
303
|
},
|
|
@@ -329,8 +331,7 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
|
|
|
329
331
|
};
|
|
330
332
|
},
|
|
331
333
|
confirmBulkUploadMatch: {
|
|
332
|
-
|
|
333
|
-
reducer(draft, _action) {
|
|
334
|
+
reducer(draft) {
|
|
334
335
|
draft.bulkUpload.confirmMatchStatus = {
|
|
335
336
|
fetchState: 'In-Progress',
|
|
336
337
|
error: undefined,
|
|
@@ -348,7 +349,7 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
|
|
|
348
349
|
};
|
|
349
350
|
const details = draft.bulkUpload.batchDetailsById[batchId];
|
|
350
351
|
if (details != null) {
|
|
351
|
-
const file = details.files.find((
|
|
352
|
+
const file = details.files.find((batchFile) => batchFile.attachmentId === attachmentId);
|
|
352
353
|
if (file != null) {
|
|
353
354
|
const originalStatus = file.status;
|
|
354
355
|
file.status = 'exact_match';
|
|
@@ -431,7 +432,7 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
|
|
|
431
432
|
const { append, nextPageToken, results, totalCount } = action.payload;
|
|
432
433
|
if (append) {
|
|
433
434
|
const merged = [...draft.bulkUpload.manualSearch.results, ...results];
|
|
434
|
-
const byId = new Map(merged.map((
|
|
435
|
+
const byId = new Map(merged.map((result) => [result.transactionId, result]));
|
|
435
436
|
draft.bulkUpload.manualSearch.results = Array.from(byId.values());
|
|
436
437
|
}
|
|
437
438
|
else {
|
|
@@ -536,7 +537,7 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
|
|
|
536
537
|
});
|
|
537
538
|
_a = expenseAutomationMissingReceiptsView.actions, exports.fetchMissingReceipts = _a.fetchMissingReceipts, exports.fetchMissingReceiptsSuccess = _a.fetchMissingReceiptsSuccess, exports.fetchMissingReceiptsFailure = _a.fetchMissingReceiptsFailure, exports.uploadMissingReceiptSuccess = _a.uploadMissingReceiptSuccess, exports.updateMissingReceiptUploadState = _a.updateMissingReceiptUploadState, exports.updateMissingReceiptsUIState = _a.updateMissingReceiptsUIState, exports.markMissingReceiptAsDone = _a.markMissingReceiptAsDone, exports.clearExpenseAutomationMissingReceiptsView = _a.clearExpenseAutomationMissingReceiptsView,
|
|
538
539
|
// Bulk Upload
|
|
539
|
-
exports.bulkUploadReceipts = _a.bulkUploadReceipts, exports.updateBulkUploadProgress = _a.updateBulkUploadProgress, exports.bulkUploadReceiptsSuccess = _a.bulkUploadReceiptsSuccess, exports.bulkUploadReceiptsFailure = _a.bulkUploadReceiptsFailure, exports.pusherBatchStatusUpdate = _a.pusherBatchStatusUpdate, exports.requestMissingReceiptsTabNavigation = _a.requestMissingReceiptsTabNavigation, exports.clearMissingReceiptsTabNavigation = _a.clearMissingReceiptsTabNavigation, exports.
|
|
540
|
+
exports.bulkUploadReceipts = _a.bulkUploadReceipts, exports.updateBulkUploadProgress = _a.updateBulkUploadProgress, exports.bulkUploadReceiptsSuccess = _a.bulkUploadReceiptsSuccess, exports.bulkUploadReceiptsFailure = _a.bulkUploadReceiptsFailure, exports.pusherBatchStatusUpdate = _a.pusherBatchStatusUpdate, exports.requestMissingReceiptsTabNavigation = _a.requestMissingReceiptsTabNavigation, exports.clearMissingReceiptsTabNavigation = _a.clearMissingReceiptsTabNavigation, exports.fetchBulkUploadBatchDetailsSuccess = _a.fetchBulkUploadBatchDetailsSuccess, exports.fetchBulkUploadBatchDetailsFailure = _a.fetchBulkUploadBatchDetailsFailure, exports.storeBatchDetails = _a.storeBatchDetails, exports.batchDetailFetchFailed = _a.batchDetailFetchFailed, exports.setInitialBatchDetailsLoading = _a.setInitialBatchDetailsLoading, exports.fetchMoreBatchDetails = _a.fetchMoreBatchDetails, exports.fetchMoreBatchDetailsComplete = _a.fetchMoreBatchDetailsComplete, exports.fetchMoreBatchDetailsFailure = _a.fetchMoreBatchDetailsFailure, exports.fetchBulkUploadBatches = _a.fetchBulkUploadBatches, exports.fetchBulkUploadBatchesSuccess = _a.fetchBulkUploadBatchesSuccess, exports.fetchBulkUploadBatchesFailure = _a.fetchBulkUploadBatchesFailure, exports.confirmBulkUploadMatch = _a.confirmBulkUploadMatch, exports.confirmBulkUploadMatchSuccess = _a.confirmBulkUploadMatchSuccess, exports.confirmBulkUploadMatchFailure = _a.confirmBulkUploadMatchFailure, exports.setBulkUploadResultsTab = _a.setBulkUploadResultsTab, exports.setBulkUploadCompletedSubTab = _a.setBulkUploadCompletedSubTab, exports.setBulkUploadSortConfig = _a.setBulkUploadSortConfig, exports.clearBulkUpload = _a.clearBulkUpload, exports.searchTransactionsForManualMatch = _a.searchTransactionsForManualMatch, exports.searchTransactionsForManualMatchSuccess = _a.searchTransactionsForManualMatchSuccess, exports.searchTransactionsForManualMatchFailure = _a.searchTransactionsForManualMatchFailure, exports.clearManualSearchResults = _a.clearManualSearchResults, exports.acknowledgeBulkUploadConfirmMatchComplete = _a.acknowledgeBulkUploadConfirmMatchComplete,
|
|
540
541
|
// Completed Transactions
|
|
541
542
|
exports.fetchCompletedTransactions = _a.fetchCompletedTransactions, exports.fetchCompletedTransactionsSuccess = _a.fetchCompletedTransactionsSuccess, exports.fetchCompletedTransactionsFailure = _a.fetchCompletedTransactionsFailure;
|
|
542
543
|
exports.default = expenseAutomationMissingReceiptsView.reducer;
|
|
@@ -70,45 +70,68 @@ function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
70
70
|
* so we do not block the whole tab while other rows are not fetched yet.
|
|
71
71
|
*/
|
|
72
72
|
const primaryBatchIdFromDetailsOrder = getPrimaryBatchIdFromBatchListOrder(batchList, bulkUpload.batchDetailsById, bulkUpload.failedBatchDetailIds);
|
|
73
|
-
/**
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
/**
|
|
74
|
+
* During upload/matching, prefer `currentBatchId` only when it is not yet in the period
|
|
75
|
+
* `batchList` (true in-flight), or when its details are completed and include unmatched-tab work.
|
|
76
|
+
* Otherwise keep `primaryBatchIdFromDetailsOrder` so a new batch with no `possible_matches` /
|
|
77
|
+
* `no_match` rows yet does not vacate the primary column and push older batches into "past".
|
|
78
|
+
*/
|
|
79
|
+
const unmatchedSectionBatchId = (() => {
|
|
80
|
+
const phase = bulkUpload.phase;
|
|
81
|
+
if (phase !== 'matching' && phase !== 'uploading') {
|
|
82
|
+
return primaryBatchIdFromDetailsOrder;
|
|
83
|
+
}
|
|
84
|
+
const currentId = bulkUpload.currentBatchId;
|
|
85
|
+
if (currentId == null) {
|
|
86
|
+
return primaryBatchIdFromDetailsOrder;
|
|
87
|
+
}
|
|
88
|
+
const currentInBatchList = batchList.some((b) => b.batchId === currentId);
|
|
89
|
+
if (!currentInBatchList) {
|
|
90
|
+
return currentId;
|
|
91
|
+
}
|
|
92
|
+
const currentDetails = bulkUpload.batchDetailsById[currentId];
|
|
93
|
+
if (currentDetails != null &&
|
|
94
|
+
currentDetails.status === 'completed' &&
|
|
95
|
+
batchDetailsHasUnmatchedWork(currentDetails)) {
|
|
96
|
+
return currentId;
|
|
97
|
+
}
|
|
98
|
+
return primaryBatchIdFromDetailsOrder;
|
|
99
|
+
})();
|
|
100
|
+
const completedBatchesInApiOrder = batchList.filter((batchListItem) => (0, missingReceiptsPayload_1.isBatchListStatusCompleted)(batchListItem.status));
|
|
78
101
|
const currentBatchDetails = unmatchedSectionBatchId != null
|
|
79
102
|
? bulkUpload.batchDetailsById[unmatchedSectionBatchId]
|
|
80
103
|
: undefined;
|
|
81
104
|
const resolvedFiles = currentBatchDetails?.files.map((file) => resolveBatchFile(file, currentBatchDetails.batchId, transactionState));
|
|
82
105
|
const failedIds = new Set(bulkUpload.failedBatchDetailIds);
|
|
83
|
-
const hasMoreBatchDetails = completedBatchesInApiOrder.some((
|
|
84
|
-
!failedIds.has(
|
|
106
|
+
const hasMoreBatchDetails = completedBatchesInApiOrder.some((batchListItem) => bulkUpload.batchDetailsById[batchListItem.batchId] == null &&
|
|
107
|
+
!failedIds.has(batchListItem.batchId));
|
|
85
108
|
const getSortValue = (file) => {
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
109
|
+
const matchedTransaction = file.matchedTransaction;
|
|
110
|
+
if (matchedTransaction == null) {
|
|
88
111
|
return null;
|
|
89
112
|
}
|
|
90
113
|
switch (bulkUpload.sortKey) {
|
|
91
114
|
case 'vendor':
|
|
92
|
-
return (
|
|
115
|
+
return (matchedTransaction.vendorName ?? matchedTransaction.description)?.toLowerCase() ?? null;
|
|
93
116
|
case 'category': {
|
|
94
|
-
const line =
|
|
117
|
+
const line = matchedTransaction.lines?.[0];
|
|
95
118
|
return line?.account?.accountName?.toLowerCase() ?? null;
|
|
96
119
|
}
|
|
97
120
|
case 'class': {
|
|
98
|
-
const line =
|
|
121
|
+
const line = matchedTransaction.lines?.[0];
|
|
99
122
|
return line?.class?.className?.toLowerCase() ?? null;
|
|
100
123
|
}
|
|
101
124
|
case 'date':
|
|
102
|
-
return
|
|
125
|
+
return matchedTransaction.date.valueOf();
|
|
103
126
|
case 'amount':
|
|
104
|
-
return
|
|
127
|
+
return matchedTransaction.amount.amount;
|
|
105
128
|
default:
|
|
106
129
|
return null;
|
|
107
130
|
}
|
|
108
131
|
};
|
|
109
132
|
const bulkUploadSortDirection = bulkUpload.sortOrder === 'ascending' ? 'asc' : 'desc';
|
|
110
|
-
const matchedFiles = (0, orderBy_1.default)(resolvedFiles?.filter((
|
|
111
|
-
const unmatchedFiles = (0, orderBy_1.default)(resolvedFiles?.filter((
|
|
133
|
+
const matchedFiles = (0, orderBy_1.default)(resolvedFiles?.filter((resolvedFile) => resolvedFile.status === 'exact_match') ?? [], getSortValue, bulkUploadSortDirection);
|
|
134
|
+
const unmatchedFiles = (0, orderBy_1.default)(resolvedFiles?.filter((resolvedFile) => (0, missingReceiptsViewState_1.isUnmatchedTabFileStatus)(resolvedFile.status)) ?? [], getSortValue, bulkUploadSortDirection);
|
|
112
135
|
const progress = currentBatchStatus != null
|
|
113
136
|
? {
|
|
114
137
|
...currentBatchStatus.progress,
|
|
@@ -125,16 +148,16 @@ function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
125
148
|
* that has details loaded (otherwise past is empty and receipts vanish from the UI).
|
|
126
149
|
*/
|
|
127
150
|
const pastBatches = unmatchedSectionBatchId != null
|
|
128
|
-
? batchList.filter((
|
|
151
|
+
? batchList.filter((batchListItem) => batchListItem.batchId !== unmatchedSectionBatchId)
|
|
129
152
|
: batchList;
|
|
130
|
-
const pastUnmatchedFiles = pastBatches.flatMap((
|
|
131
|
-
const details = bulkUpload.batchDetailsById[
|
|
153
|
+
const pastUnmatchedFiles = pastBatches.flatMap((pastBatch) => {
|
|
154
|
+
const details = bulkUpload.batchDetailsById[pastBatch.batchId];
|
|
132
155
|
if (details == null) {
|
|
133
156
|
return [];
|
|
134
157
|
}
|
|
135
158
|
return details.files
|
|
136
|
-
.filter((
|
|
137
|
-
.map((
|
|
159
|
+
.filter((batchFile) => (0, missingReceiptsViewState_1.isUnmatchedTabFileStatus)(batchFile.status))
|
|
160
|
+
.map((batchFile) => resolveBatchFile(batchFile, pastBatch.batchId, transactionState));
|
|
138
161
|
});
|
|
139
162
|
const completedTransactionsCacheKey = monthYearPeriodId != null
|
|
140
163
|
? (0, missingReceiptsViewReducer_1.getCompletedTransactionsCacheKey)(monthYearPeriodId, bulkUpload.sortKey, bulkUpload.sortOrder, bulkUpload.completedSubTab)
|
|
@@ -153,11 +176,11 @@ function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
153
176
|
summary: currentBatchDetails.summary,
|
|
154
177
|
}
|
|
155
178
|
: undefined;
|
|
156
|
-
const manualSearchResults = bulkUpload.manualSearch.results.map((
|
|
157
|
-
const
|
|
179
|
+
const manualSearchResults = bulkUpload.manualSearch.results.map((result) => {
|
|
180
|
+
const transaction = (0, transactionSelector_1.getSupportedTransactionById)(transactionState, result.transactionId);
|
|
158
181
|
return {
|
|
159
|
-
...
|
|
160
|
-
vendorLogo:
|
|
182
|
+
...result,
|
|
183
|
+
vendorLogo: result.vendorLogo ?? transaction?.logo?.href,
|
|
161
184
|
};
|
|
162
185
|
});
|
|
163
186
|
return {
|
|
@@ -207,7 +230,7 @@ function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
207
230
|
};
|
|
208
231
|
}
|
|
209
232
|
function batchDetailsHasUnmatchedWork(details) {
|
|
210
|
-
return details.files.some((
|
|
233
|
+
return details.files.some((file) => (0, missingReceiptsViewState_1.isUnmatchedTabFileStatus)(file.status));
|
|
211
234
|
}
|
|
212
235
|
/** List row summary before batch details load — aligns with unmatched / possible-match work. */
|
|
213
236
|
function batchListItemHasUnmatchedWork(batch) {
|
|
@@ -224,17 +247,17 @@ function batchListItemHasUnmatchedWork(batch) {
|
|
|
224
247
|
*/
|
|
225
248
|
function getPrimaryBatchIdFromBatchListOrder(batchListInPlatformOrder, batchDetailsById, failedBatchDetailIds) {
|
|
226
249
|
const failedIds = new Set(failedBatchDetailIds);
|
|
227
|
-
const anyCompletedBatchHasUnmatchedWork = batchListInPlatformOrder.some((
|
|
228
|
-
if (failedIds.has(
|
|
250
|
+
const anyCompletedBatchHasUnmatchedWork = batchListInPlatformOrder.some((batch) => {
|
|
251
|
+
if (failedIds.has(batch.batchId)) {
|
|
229
252
|
return false;
|
|
230
253
|
}
|
|
231
|
-
const
|
|
232
|
-
if (
|
|
233
|
-
|
|
234
|
-
batchDetailsHasUnmatchedWork(
|
|
254
|
+
const details = batchDetailsById[batch.batchId];
|
|
255
|
+
if (details != null &&
|
|
256
|
+
details.status === 'completed' &&
|
|
257
|
+
batchDetailsHasUnmatchedWork(details)) {
|
|
235
258
|
return true;
|
|
236
259
|
}
|
|
237
|
-
return
|
|
260
|
+
return details == null && batchListItemHasUnmatchedWork(batch);
|
|
238
261
|
});
|
|
239
262
|
for (const batch of batchListInPlatformOrder) {
|
|
240
263
|
if (failedIds.has(batch.batchId)) {
|
|
@@ -271,7 +294,7 @@ function resolveBatchFile(file, batchId, transactionState) {
|
|
|
271
294
|
? { transaction, matchScore: ref.matchScore }
|
|
272
295
|
: undefined;
|
|
273
296
|
})
|
|
274
|
-
.filter((
|
|
297
|
+
.filter((candidate) => candidate != null);
|
|
275
298
|
return {
|
|
276
299
|
attachmentId: file.attachmentId,
|
|
277
300
|
batchId,
|
|
@@ -3,7 +3,6 @@ import { SortOrder } from '../../../commonStateTypes/selectorTypes/sortOrderType
|
|
|
3
3
|
import { MonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
|
|
4
4
|
export declare const toMissingReceiptsSortKey: (v: string) => "date" | "amount" | "vendor" | "category" | "class";
|
|
5
5
|
export type MissingReceiptsSortKey = ReturnType<typeof toMissingReceiptsSortKey>;
|
|
6
|
-
export type BulkUploadSortKey = 'amount' | 'category' | 'class' | 'date' | 'vendor';
|
|
7
6
|
export interface MissingReceiptsViewUIState {
|
|
8
7
|
scrollPosition: {
|
|
9
8
|
scrollTop: number;
|
|
@@ -18,15 +17,26 @@ export interface MissingReceiptsViewUIState {
|
|
|
18
17
|
* Kept in sync with `ManualSearchInput` in web-components (fires search only when length ≥ this).
|
|
19
18
|
*/
|
|
20
19
|
export declare const MIN_MANUAL_TRANSACTION_SEARCH_LENGTH = 2;
|
|
21
|
-
export
|
|
22
|
-
export type
|
|
20
|
+
export declare const toBatchStatusValue: (v: string) => "pending" | "processing" | "completed";
|
|
21
|
+
export type BatchStatusValue = ReturnType<typeof toBatchStatusValue>;
|
|
22
|
+
/** Canonical batch file statuses (API ingress may use aliases; see `parseBatchFileStatus`). */
|
|
23
|
+
export declare const BATCH_FILE_STATUSES: readonly ["exact_match", "possible_matches", "no_match", "failed"];
|
|
24
|
+
export declare const toBatchFileStatus: (v: string) => "failed" | "exact_match" | "possible_matches" | "no_match";
|
|
25
|
+
export type BatchFileStatus = ReturnType<typeof toBatchFileStatus>;
|
|
23
26
|
/** True for files that belong in the Unmatched tab (possible matches or no match). */
|
|
24
27
|
export declare function isUnmatchedTabFileStatus(status: BatchFileStatus): boolean;
|
|
25
|
-
export
|
|
26
|
-
export type
|
|
27
|
-
export
|
|
28
|
-
export type
|
|
29
|
-
export
|
|
28
|
+
export declare const toBulkUploadPhase: (v: string) => "completed" | "idle" | "uploading" | "matching";
|
|
29
|
+
export type BulkUploadPhase = ReturnType<typeof toBulkUploadPhase>;
|
|
30
|
+
export declare const toBulkUploadResultsTab: (v: string) => "completed" | "unmatched";
|
|
31
|
+
export type BulkUploadResultsTab = ReturnType<typeof toBulkUploadResultsTab>;
|
|
32
|
+
export declare const toMissingReceiptsTab: (v: string) => "completed" | "unmatched" | "missing";
|
|
33
|
+
export type MissingReceiptsTab = ReturnType<typeof toMissingReceiptsTab>;
|
|
34
|
+
export declare const toCompletedSubTab: (v: string) => "all" | "manual" | "ai_accountant";
|
|
35
|
+
export type CompletedSubTab = ReturnType<typeof toCompletedSubTab>;
|
|
36
|
+
export declare const toMatchSource: (v: string) => "manual" | "ai";
|
|
37
|
+
export type MatchSource = ReturnType<typeof toMatchSource>;
|
|
38
|
+
export declare const toBulkUploadSortKey: (v: string) => "date" | "amount" | "vendor" | "category" | "class";
|
|
39
|
+
export type BulkUploadSortKey = ReturnType<typeof toBulkUploadSortKey>;
|
|
30
40
|
export interface CandidateRef {
|
|
31
41
|
matchScore: number;
|
|
32
42
|
transactionId: ID;
|
|
@@ -106,7 +116,8 @@ export interface ManualSearchState {
|
|
|
106
116
|
searchQuery: string;
|
|
107
117
|
totalCount: number;
|
|
108
118
|
}
|
|
109
|
-
|
|
119
|
+
/** Same union as {@link CompletedSubTab} — used for completed-transactions API `match_type`. */
|
|
120
|
+
export type CompletedTransactionsMatchType = CompletedSubTab;
|
|
110
121
|
export interface CompletedTransactionsState {
|
|
111
122
|
fetchState: FetchStateAndError;
|
|
112
123
|
nextPageToken: string | null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MIN_MANUAL_TRANSACTION_SEARCH_LENGTH = exports.toMissingReceiptsSortKey = void 0;
|
|
3
|
+
exports.toBulkUploadSortKey = exports.toMatchSource = exports.toCompletedSubTab = exports.toMissingReceiptsTab = exports.toBulkUploadResultsTab = exports.toBulkUploadPhase = exports.toBatchFileStatus = exports.BATCH_FILE_STATUSES = exports.toBatchStatusValue = exports.MIN_MANUAL_TRANSACTION_SEARCH_LENGTH = exports.toMissingReceiptsSortKey = void 0;
|
|
4
4
|
exports.isUnmatchedTabFileStatus = isUnmatchedTabFileStatus;
|
|
5
5
|
const stringToUnion_1 = require("../../../commonStateTypes/stringToUnion");
|
|
6
6
|
const MISSING_RECEIPTS_SORT_KEYS = [
|
|
@@ -18,7 +18,44 @@ exports.toMissingReceiptsSortKey = toMissingReceiptsSortKey;
|
|
|
18
18
|
* Kept in sync with `ManualSearchInput` in web-components (fires search only when length ≥ this).
|
|
19
19
|
*/
|
|
20
20
|
exports.MIN_MANUAL_TRANSACTION_SEARCH_LENGTH = 2;
|
|
21
|
+
const BATCH_STATUS_VALUES = ['pending', 'processing', 'completed'];
|
|
22
|
+
const toBatchStatusValue = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase(), BATCH_STATUS_VALUES);
|
|
23
|
+
exports.toBatchStatusValue = toBatchStatusValue;
|
|
24
|
+
/** Canonical batch file statuses (API ingress may use aliases; see `parseBatchFileStatus`). */
|
|
25
|
+
exports.BATCH_FILE_STATUSES = [
|
|
26
|
+
'exact_match',
|
|
27
|
+
'possible_matches',
|
|
28
|
+
'no_match',
|
|
29
|
+
'failed',
|
|
30
|
+
];
|
|
31
|
+
const toBatchFileStatus = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase().replace(/-/g, '_'), exports.BATCH_FILE_STATUSES);
|
|
32
|
+
exports.toBatchFileStatus = toBatchFileStatus;
|
|
33
|
+
const UNMATCHED_TAB_FILE_STATUSES = ['possible_matches', 'no_match'];
|
|
21
34
|
/** True for files that belong in the Unmatched tab (possible matches or no match). */
|
|
22
35
|
function isUnmatchedTabFileStatus(status) {
|
|
23
|
-
return status
|
|
36
|
+
return UNMATCHED_TAB_FILE_STATUSES.includes(status);
|
|
24
37
|
}
|
|
38
|
+
const BULK_UPLOAD_PHASES = ['idle', 'uploading', 'matching', 'completed'];
|
|
39
|
+
const toBulkUploadPhase = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase(), BULK_UPLOAD_PHASES);
|
|
40
|
+
exports.toBulkUploadPhase = toBulkUploadPhase;
|
|
41
|
+
const BULK_UPLOAD_RESULTS_TABS = ['completed', 'unmatched'];
|
|
42
|
+
const toBulkUploadResultsTab = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase(), BULK_UPLOAD_RESULTS_TABS);
|
|
43
|
+
exports.toBulkUploadResultsTab = toBulkUploadResultsTab;
|
|
44
|
+
const MISSING_RECEIPTS_TABS = ['missing', 'completed', 'unmatched'];
|
|
45
|
+
const toMissingReceiptsTab = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase(), MISSING_RECEIPTS_TABS);
|
|
46
|
+
exports.toMissingReceiptsTab = toMissingReceiptsTab;
|
|
47
|
+
const COMPLETED_SUB_TABS = ['all', 'ai_accountant', 'manual'];
|
|
48
|
+
const toCompletedSubTab = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase(), COMPLETED_SUB_TABS);
|
|
49
|
+
exports.toCompletedSubTab = toCompletedSubTab;
|
|
50
|
+
const MATCH_SOURCES = ['ai', 'manual'];
|
|
51
|
+
const toMatchSource = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase(), MATCH_SOURCES);
|
|
52
|
+
exports.toMatchSource = toMatchSource;
|
|
53
|
+
const BULK_UPLOAD_SORT_KEYS = [
|
|
54
|
+
'amount',
|
|
55
|
+
'category',
|
|
56
|
+
'class',
|
|
57
|
+
'date',
|
|
58
|
+
'vendor',
|
|
59
|
+
];
|
|
60
|
+
const toBulkUploadSortKey = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase(), BULK_UPLOAD_SORT_KEYS);
|
|
61
|
+
exports.toBulkUploadSortKey = toBulkUploadSortKey;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeniai/client-epic-state",
|
|
3
|
-
"version": "4.19.84-
|
|
3
|
+
"version": "4.19.84-betaVR12",
|
|
4
4
|
"description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/esm/index.js",
|