@zeniai/client-epic-state 4.19.37-betaVR11 → 4.19.37-betaVR13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (17) hide show
  1. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchMoreBatchDetailsEpic.js +3 -1
  2. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.js +8 -4
  3. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +16 -28
  4. package/lib/esm/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +14 -1
  5. package/lib/esm/view/expenseAutomationView/selectors/missingReceiptsSelector.js +7 -4
  6. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMoreBatchDetailsEpic.d.ts +2 -2
  7. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMoreBatchDetailsEpic.js +3 -1
  8. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.d.ts +2 -2
  9. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.js +6 -2
  10. package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.d.ts +4 -3
  11. package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +13 -25
  12. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +3 -1
  13. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +15 -2
  14. package/lib/view/expenseAutomationView/selectorTypes/missingReceiptsSelectorTypes.d.ts +1 -0
  15. package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.js +7 -4
  16. package/lib/view/expenseAutomationView/types/missingReceiptsViewState.d.ts +1 -0
  17. package/package.json +1 -1
@@ -16,9 +16,11 @@ export const fetchMoreBatchDetailsEpic = (actions$, state$, zeniAPI) => actions$
16
16
  }
17
17
  const periodId = toMonthYearPeriodId(selectedPeriod);
18
18
  const batchList = bulkUpload.batchListByPeriod[periodId] ?? [];
19
+ const failedIds = new Set(bulkUpload.failedBatchDetailIds);
19
20
  const unfetchedBatchIds = batchList
20
21
  .filter((batch) => batch.status === 'completed' &&
21
- bulkUpload.batchDetailsById[batch.batchId] == null)
22
+ bulkUpload.batchDetailsById[batch.batchId] == null &&
23
+ !failedIds.has(batch.batchId))
22
24
  .map((batch) => batch.batchId);
23
25
  if (unfetchedBatchIds.length === 0) {
24
26
  return of(fetchMoreBatchDetailsComplete());
@@ -1,9 +1,9 @@
1
- import { EMPTY, from } from 'rxjs';
1
+ import { EMPTY, concat, from, of } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { updateTransactions } from '../../../../entity/transaction/transactionReducer';
4
4
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
5
5
  import { extractTransactionPayloadsFromBatchFiles, toBatchDetails, } from '../../payload/missingReceiptsPayload';
6
- import { fetchBulkUploadBatchesSuccess, storeBatchDetails, } from '../../reducers/missingReceiptsViewReducer';
6
+ import { batchDetailFetchFailed, fetchBulkUploadBatchesSuccess, fetchMoreBatchDetailsComplete, setInitialBatchDetailsLoading, storeBatchDetails, } from '../../reducers/missingReceiptsViewReducer';
7
7
  const INITIAL_BATCH_PAGE_SIZE = 4;
8
8
  export function fetchBatchDetailsByIds(batchIds, zeniAPI) {
9
9
  if (batchIds.length === 0) {
@@ -25,7 +25,7 @@ export function fetchBatchDetailsByIds(batchIds, zeniAPI) {
25
25
  }), catchError((error) => {
26
26
  console.error(`Failed to fetch batch details for ${batchId}:`, createZeniAPIStatus('Unexpected Error', 'Fetch batch details errored out: ' +
27
27
  JSON.stringify(error)));
28
- return EMPTY;
28
+ return of(batchDetailFetchFailed({ batchId }));
29
29
  })), 5));
30
30
  }
31
31
  export const fetchMultipleBatchDetailsEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchBulkUploadBatchesSuccess.match), mergeMap((action) => {
@@ -35,5 +35,9 @@ export const fetchMultipleBatchDetailsEpic = (actions$, state$, zeniAPI) => acti
35
35
  .filter((batch) => batch.status === 'completed' &&
36
36
  batchDetailsById[batch.batchId] == null)
37
37
  .map((batch) => batch.batchId);
38
- return fetchBatchDetailsByIds(completedBatchIds.slice(0, INITIAL_BATCH_PAGE_SIZE), zeniAPI);
38
+ const batchIdsToFetch = completedBatchIds.slice(0, INITIAL_BATCH_PAGE_SIZE);
39
+ if (batchIdsToFetch.length === 0) {
40
+ return EMPTY;
41
+ }
42
+ return concat(of(setInitialBatchDetailsLoading()), fetchBatchDetailsByIds(batchIdsToFetch, zeniAPI), of(fetchMoreBatchDetailsComplete()));
39
43
  }));
@@ -1,47 +1,35 @@
1
- import { of, timer } from 'rxjs';
1
+ import { from, of, timer } from 'rxjs';
2
2
  import { catchError, filter, mergeMap, switchMap, takeUntil, takeWhile, } from 'rxjs/operators';
3
- import { convertToPeriod } from '../../../../commonStateTypes/timePeriod';
4
- import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
3
+ import { updateTransactions } from '../../../../entity/transaction/transactionReducer';
5
4
  import { isSuccessResponse } from '../../../../responsePayload';
6
- import { toBatchListItem, } from '../../payload/missingReceiptsPayload';
7
- import { bulkUploadReceiptsSuccess, clearBulkUpload, fetchBulkUploadBatchDetails, fetchBulkUploadBatchesSuccess, pusherBatchStatusUpdate, } from '../../reducers/missingReceiptsViewReducer';
5
+ import { extractTransactionPayloadsFromBatchFiles, toBatchDetails, } from '../../payload/missingReceiptsPayload';
6
+ import { bulkUploadReceiptsSuccess, clearBulkUpload, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatches, pusherBatchStatusUpdate, } from '../../reducers/missingReceiptsViewReducer';
8
7
  export const pusherBatchStatusCompletionEpic = (actions$) => actions$.pipe(filter(pusherBatchStatusUpdate.match), filter((action) => action.payload.status === 'completed'), mergeMap(() => of(fetchBulkUploadBatchDetails())));
9
8
  const FALLBACK_POLL_INTERVAL_MS = 10000;
10
- export const pollBulkUploadBatchStatusEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(bulkUploadReceiptsSuccess.match), switchMap((action) => {
9
+ export const pollBulkUploadBatchStatusEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(bulkUploadReceiptsSuccess.match), switchMap((action) => {
11
10
  const { batchId } = action.payload;
12
11
  return timer(0, FALLBACK_POLL_INTERVAL_MS).pipe(takeUntil(actions$.pipe(filter((a) => clearBulkUpload.match(a) ||
13
12
  (pusherBatchStatusUpdate.match(a) &&
14
13
  a.payload.status === 'completed')))), switchMap(() => {
15
- const state = state$.value;
16
- const { expenseAutomationViewState: { selectedPeriodByTenantId }, } = state;
17
- const currentTenant = getCurrentTenant(state);
18
- const selectedPeriod = selectedPeriodByTenantId[currentTenant.tenantId];
19
- const period = convertToPeriod(selectedPeriod);
20
- const queryParam = {
21
- start_date: period.start,
22
- end_date: period.end,
23
- sort_order: 'desc',
24
- };
25
14
  return zeniAPI
26
- .getJSON(`${zeniAPI.apiEndPoints.communicationAgentMicroServiceBaseUrl}/1.0/batches?query=${encodeURIComponent(JSON.stringify(queryParam))}`)
15
+ .getJSON(`${zeniAPI.apiEndPoints.communicationAgentMicroServiceBaseUrl}/1.0/batches/${batchId}`)
27
16
  .pipe(mergeMap((response) => {
28
17
  if (isSuccessResponse(response) && response.data != null) {
29
- const batchList = response.data.batches.map(toBatchListItem);
30
- const currentBatch = batchList.find((b) => b.batchId === batchId);
31
- if (currentBatch?.status === 'completed') {
32
- return [
33
- fetchBulkUploadBatchesSuccess({
34
- batchList,
35
- selectedPeriod,
36
- }),
37
- fetchBulkUploadBatchDetails(),
38
- ];
18
+ if (response.data.status === 'completed') {
19
+ const actions = [];
20
+ const transactionPayloads = extractTransactionPayloadsFromBatchFiles(response.data.files);
21
+ if (transactionPayloads.length > 0) {
22
+ actions.push(updateTransactions(transactionPayloads, (value) => value.transaction_id));
23
+ }
24
+ actions.push(fetchBulkUploadBatchDetailsSuccess(toBatchDetails(response.data, zeniAPI.apiEndPoints.fileMicroServiceBaseUrl)));
25
+ actions.push(fetchBulkUploadBatches(true));
26
+ return from(actions);
39
27
  }
40
28
  }
41
29
  return [];
42
30
  }), catchError(() => of()));
43
31
  }), takeWhile((emittedAction) => {
44
- if (fetchBulkUploadBatchDetails.match(emittedAction)) {
32
+ if (fetchBulkUploadBatchDetailsSuccess.match(emittedAction)) {
45
33
  return false;
46
34
  }
47
35
  return true;
@@ -11,6 +11,7 @@ export const initialBulkUploadState = {
11
11
  confirmMatchStatus: { fetchState: 'Not-Started', error: undefined },
12
12
  currentBatchId: undefined,
13
13
  currentResultsTab: 'unmatched',
14
+ failedBatchDetailIds: [],
14
15
  manualSearch: {
15
16
  fetchState: { fetchState: 'Not-Started', error: undefined },
16
17
  results: [],
@@ -197,6 +198,18 @@ const expenseAutomationMissingReceiptsView = createSlice({
197
198
  const details = action.payload;
198
199
  draft.bulkUpload.batchDetailsById[details.batchId] = details;
199
200
  },
201
+ batchDetailFetchFailed(draft, action) {
202
+ const { batchId } = action.payload;
203
+ if (!draft.bulkUpload.failedBatchDetailIds.includes(batchId)) {
204
+ draft.bulkUpload.failedBatchDetailIds.push(batchId);
205
+ }
206
+ },
207
+ setInitialBatchDetailsLoading(draft) {
208
+ draft.bulkUpload.batchDetailsPaginationState = {
209
+ fetchState: 'In-Progress',
210
+ error: undefined,
211
+ };
212
+ },
200
213
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
201
214
  fetchMoreBatchDetails(_draft) {
202
215
  _draft.bulkUpload.batchDetailsPaginationState = {
@@ -399,7 +412,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
399
412
  });
400
413
  export const { fetchMissingReceipts, fetchMissingReceiptsSuccess, fetchMissingReceiptsFailure, uploadMissingReceiptSuccess, updateMissingReceiptUploadState, updateMissingReceiptsUIState, markMissingReceiptAsDone, clearExpenseAutomationMissingReceiptsView,
401
414
  // Bulk Upload
402
- bulkUploadReceipts, updateBulkUploadProgress, bulkUploadReceiptsSuccess, bulkUploadReceiptsFailure, pusherBatchStatusUpdate, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatchDetailsFailure, storeBatchDetails, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, fetchBulkUploadBatches, fetchBulkUploadBatchesSuccess, fetchBulkUploadBatchesFailure, confirmBulkUploadMatch, confirmBulkUploadMatchSuccess, confirmBulkUploadMatchFailure, setBulkUploadResultsTab, setBulkUploadCompletedSubTab, setBulkUploadSortConfig, clearBulkUpload, searchTransactionsForManualMatch, searchTransactionsForManualMatchSuccess, searchTransactionsForManualMatchFailure, clearManualSearchResults,
415
+ bulkUploadReceipts, updateBulkUploadProgress, bulkUploadReceiptsSuccess, bulkUploadReceiptsFailure, pusherBatchStatusUpdate, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatchDetailsFailure, storeBatchDetails, batchDetailFetchFailed, setInitialBatchDetailsLoading, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, fetchBulkUploadBatches, fetchBulkUploadBatchesSuccess, fetchBulkUploadBatchesFailure, confirmBulkUploadMatch, confirmBulkUploadMatchSuccess, confirmBulkUploadMatchFailure, setBulkUploadResultsTab, setBulkUploadCompletedSubTab, setBulkUploadSortConfig, clearBulkUpload, searchTransactionsForManualMatch, searchTransactionsForManualMatchSuccess, searchTransactionsForManualMatchFailure, clearManualSearchResults,
403
416
  // Completed Transactions
404
417
  fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, } = expenseAutomationMissingReceiptsView.actions;
405
418
  export default expenseAutomationMissingReceiptsView.reducer;
@@ -59,8 +59,10 @@ export function getExpenseAutomationMissingReceiptsView(state) {
59
59
  const currentBatchDetails = effectiveCurrentBatchId != null
60
60
  ? bulkUpload.batchDetailsById[effectiveCurrentBatchId]
61
61
  : undefined;
62
- const resolvedFiles = currentBatchDetails?.files.map((file) => resolveBatchFile(file, transactionState));
63
- const hasMoreBatchDetails = completedBatchesSorted.some((b) => bulkUpload.batchDetailsById[b.batchId] == null);
62
+ const resolvedFiles = currentBatchDetails?.files.map((file) => resolveBatchFile(file, currentBatchDetails.batchId, transactionState));
63
+ const failedIds = new Set(bulkUpload.failedBatchDetailIds);
64
+ const hasMoreBatchDetails = completedBatchesSorted.some((b) => bulkUpload.batchDetailsById[b.batchId] == null &&
65
+ !failedIds.has(b.batchId));
64
66
  const getSortValue = (file) => {
65
67
  const t = file.matchedTransaction;
66
68
  if (t == null) {
@@ -107,7 +109,7 @@ export function getExpenseAutomationMissingReceiptsView(state) {
107
109
  }
108
110
  return details.files
109
111
  .filter((f) => f.status === 'un_matched' || f.status === 'no_match')
110
- .map((f) => resolveBatchFile(f, transactionState));
112
+ .map((f) => resolveBatchFile(f, b.batchId, transactionState));
111
113
  });
112
114
  const completedTransactionsForPeriod = monthYearPeriodId != null
113
115
  ? bulkUpload.completedTransactionsByPeriod[monthYearPeriodId]
@@ -164,7 +166,7 @@ export function getExpenseAutomationMissingReceiptsView(state) {
164
166
  },
165
167
  };
166
168
  }
167
- function resolveBatchFile(file, transactionState) {
169
+ function resolveBatchFile(file, batchId, transactionState) {
168
170
  const matchedTransaction = file.matchedTransactionId != null
169
171
  ? getSupportedTransactionById(transactionState, file.matchedTransactionId)
170
172
  : undefined;
@@ -178,6 +180,7 @@ function resolveBatchFile(file, transactionState) {
178
180
  .filter((c) => c != null);
179
181
  return {
180
182
  attachmentId: file.attachmentId,
183
+ batchId,
181
184
  fileDownloadUrl: file.fileDownloadUrl,
182
185
  fileId: file.fileId,
183
186
  filename: file.filename,
@@ -3,6 +3,6 @@ import { Observable } from 'rxjs';
3
3
  import { updateTransactions } from '../../../../entity/transaction/transactionReducer';
4
4
  import { RootState } from '../../../../reducer';
5
5
  import { ZeniAPI } from '../../../../zeniAPI';
6
- import { fetchBulkUploadBatchesSuccess, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, storeBatchDetails } from '../../reducers/missingReceiptsViewReducer';
7
- export type ActionType = ReturnType<typeof fetchBulkUploadBatchesSuccess> | ReturnType<typeof fetchMoreBatchDetails> | ReturnType<typeof fetchMoreBatchDetailsComplete> | ReturnType<typeof fetchMoreBatchDetailsFailure> | ReturnType<typeof storeBatchDetails> | ReturnType<typeof updateTransactions>;
6
+ import { batchDetailFetchFailed, fetchBulkUploadBatchesSuccess, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, setInitialBatchDetailsLoading, storeBatchDetails } from '../../reducers/missingReceiptsViewReducer';
7
+ export type ActionType = ReturnType<typeof fetchBulkUploadBatchesSuccess> | ReturnType<typeof fetchMoreBatchDetails> | ReturnType<typeof fetchMoreBatchDetailsComplete> | ReturnType<typeof fetchMoreBatchDetailsFailure> | ReturnType<typeof batchDetailFetchFailed> | ReturnType<typeof setInitialBatchDetailsLoading> | ReturnType<typeof storeBatchDetails> | ReturnType<typeof updateTransactions>;
8
8
  export declare const fetchMoreBatchDetailsEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -19,9 +19,11 @@ const fetchMoreBatchDetailsEpic = (actions$, state$, zeniAPI) => actions$.pipe((
19
19
  }
20
20
  const periodId = (0, timePeriod_1.toMonthYearPeriodId)(selectedPeriod);
21
21
  const batchList = bulkUpload.batchListByPeriod[periodId] ?? [];
22
+ const failedIds = new Set(bulkUpload.failedBatchDetailIds);
22
23
  const unfetchedBatchIds = batchList
23
24
  .filter((batch) => batch.status === 'completed' &&
24
- bulkUpload.batchDetailsById[batch.batchId] == null)
25
+ bulkUpload.batchDetailsById[batch.batchId] == null &&
26
+ !failedIds.has(batch.batchId))
25
27
  .map((batch) => batch.batchId);
26
28
  if (unfetchedBatchIds.length === 0) {
27
29
  return (0, rxjs_1.of)((0, missingReceiptsViewReducer_1.fetchMoreBatchDetailsComplete)());
@@ -3,7 +3,7 @@ import { Observable } from 'rxjs';
3
3
  import { updateTransactions } from '../../../../entity/transaction/transactionReducer';
4
4
  import { RootState } from '../../../../reducer';
5
5
  import { ZeniAPI } from '../../../../zeniAPI';
6
- import { fetchBulkUploadBatchesSuccess, storeBatchDetails } from '../../reducers/missingReceiptsViewReducer';
7
- export type ActionType = ReturnType<typeof fetchBulkUploadBatchesSuccess> | ReturnType<typeof updateTransactions> | ReturnType<typeof storeBatchDetails>;
6
+ import { batchDetailFetchFailed, fetchBulkUploadBatchesSuccess, fetchMoreBatchDetailsComplete, setInitialBatchDetailsLoading, storeBatchDetails } from '../../reducers/missingReceiptsViewReducer';
7
+ export type ActionType = ReturnType<typeof fetchBulkUploadBatchesSuccess> | ReturnType<typeof updateTransactions> | ReturnType<typeof storeBatchDetails> | ReturnType<typeof batchDetailFetchFailed> | ReturnType<typeof setInitialBatchDetailsLoading> | ReturnType<typeof fetchMoreBatchDetailsComplete>;
8
8
  export declare function fetchBatchDetailsByIds(batchIds: string[], zeniAPI: ZeniAPI): Observable<ActionType>;
9
9
  export declare const fetchMultipleBatchDetailsEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -29,7 +29,7 @@ function fetchBatchDetailsByIds(batchIds, zeniAPI) {
29
29
  }), (0, operators_1.catchError)((error) => {
30
30
  console.error(`Failed to fetch batch details for ${batchId}:`, (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Fetch batch details errored out: ' +
31
31
  JSON.stringify(error)));
32
- return rxjs_1.EMPTY;
32
+ return (0, rxjs_1.of)((0, missingReceiptsViewReducer_1.batchDetailFetchFailed)({ batchId }));
33
33
  })), 5));
34
34
  }
35
35
  const fetchMultipleBatchDetailsEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.fetchBulkUploadBatchesSuccess.match), (0, operators_1.mergeMap)((action) => {
@@ -39,6 +39,10 @@ const fetchMultipleBatchDetailsEpic = (actions$, state$, zeniAPI) => actions$.pi
39
39
  .filter((batch) => batch.status === 'completed' &&
40
40
  batchDetailsById[batch.batchId] == null)
41
41
  .map((batch) => batch.batchId);
42
- return fetchBatchDetailsByIds(completedBatchIds.slice(0, INITIAL_BATCH_PAGE_SIZE), zeniAPI);
42
+ const batchIdsToFetch = completedBatchIds.slice(0, INITIAL_BATCH_PAGE_SIZE);
43
+ if (batchIdsToFetch.length === 0) {
44
+ return rxjs_1.EMPTY;
45
+ }
46
+ return (0, rxjs_1.concat)((0, rxjs_1.of)((0, missingReceiptsViewReducer_1.setInitialBatchDetailsLoading)()), fetchBatchDetailsByIds(batchIdsToFetch, zeniAPI), (0, rxjs_1.of)((0, missingReceiptsViewReducer_1.fetchMoreBatchDetailsComplete)()));
43
47
  }));
44
48
  exports.fetchMultipleBatchDetailsEpic = fetchMultipleBatchDetailsEpic;
@@ -1,8 +1,9 @@
1
1
  import { ActionsObservable, StateObservable } from 'redux-observable';
2
2
  import { Observable } from 'rxjs';
3
+ import { updateTransactions } from '../../../../entity/transaction/transactionReducer';
3
4
  import { RootState } from '../../../../reducer';
4
5
  import { ZeniAPI } from '../../../../zeniAPI';
5
- import { bulkUploadReceiptsSuccess, clearBulkUpload, fetchBulkUploadBatchDetails, fetchBulkUploadBatchesSuccess, pusherBatchStatusUpdate } from '../../reducers/missingReceiptsViewReducer';
6
- export type ActionType = ReturnType<typeof bulkUploadReceiptsSuccess> | ReturnType<typeof pusherBatchStatusUpdate> | ReturnType<typeof fetchBulkUploadBatchDetails> | ReturnType<typeof fetchBulkUploadBatchesSuccess> | ReturnType<typeof clearBulkUpload>;
6
+ import { bulkUploadReceiptsSuccess, clearBulkUpload, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatches, pusherBatchStatusUpdate } from '../../reducers/missingReceiptsViewReducer';
7
+ export type ActionType = ReturnType<typeof bulkUploadReceiptsSuccess> | ReturnType<typeof pusherBatchStatusUpdate> | ReturnType<typeof fetchBulkUploadBatchDetails> | ReturnType<typeof fetchBulkUploadBatchDetailsSuccess> | ReturnType<typeof fetchBulkUploadBatches> | ReturnType<typeof updateTransactions> | ReturnType<typeof clearBulkUpload>;
7
8
  export declare const pusherBatchStatusCompletionEpic: (actions$: ActionsObservable<ActionType>) => Observable<ActionType>;
8
- export declare const pollBulkUploadBatchStatusEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
9
+ export declare const pollBulkUploadBatchStatusEpic: (actions$: ActionsObservable<ActionType>, _state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -3,49 +3,37 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.pollBulkUploadBatchStatusEpic = exports.pusherBatchStatusCompletionEpic = void 0;
4
4
  const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
- const timePeriod_1 = require("../../../../commonStateTypes/timePeriod");
7
- const tenantSelector_1 = require("../../../../entity/tenant/tenantSelector");
6
+ const transactionReducer_1 = require("../../../../entity/transaction/transactionReducer");
8
7
  const responsePayload_1 = require("../../../../responsePayload");
9
8
  const missingReceiptsPayload_1 = require("../../payload/missingReceiptsPayload");
10
9
  const missingReceiptsViewReducer_1 = require("../../reducers/missingReceiptsViewReducer");
11
10
  const pusherBatchStatusCompletionEpic = (actions$) => actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.pusherBatchStatusUpdate.match), (0, operators_1.filter)((action) => action.payload.status === 'completed'), (0, operators_1.mergeMap)(() => (0, rxjs_1.of)((0, missingReceiptsViewReducer_1.fetchBulkUploadBatchDetails)())));
12
11
  exports.pusherBatchStatusCompletionEpic = pusherBatchStatusCompletionEpic;
13
12
  const FALLBACK_POLL_INTERVAL_MS = 10000;
14
- const pollBulkUploadBatchStatusEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.bulkUploadReceiptsSuccess.match), (0, operators_1.switchMap)((action) => {
13
+ const pollBulkUploadBatchStatusEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.bulkUploadReceiptsSuccess.match), (0, operators_1.switchMap)((action) => {
15
14
  const { batchId } = action.payload;
16
15
  return (0, rxjs_1.timer)(0, FALLBACK_POLL_INTERVAL_MS).pipe((0, operators_1.takeUntil)(actions$.pipe((0, operators_1.filter)((a) => missingReceiptsViewReducer_1.clearBulkUpload.match(a) ||
17
16
  (missingReceiptsViewReducer_1.pusherBatchStatusUpdate.match(a) &&
18
17
  a.payload.status === 'completed')))), (0, operators_1.switchMap)(() => {
19
- const state = state$.value;
20
- const { expenseAutomationViewState: { selectedPeriodByTenantId }, } = state;
21
- const currentTenant = (0, tenantSelector_1.getCurrentTenant)(state);
22
- const selectedPeriod = selectedPeriodByTenantId[currentTenant.tenantId];
23
- const period = (0, timePeriod_1.convertToPeriod)(selectedPeriod);
24
- const queryParam = {
25
- start_date: period.start,
26
- end_date: period.end,
27
- sort_order: 'desc',
28
- };
29
18
  return zeniAPI
30
- .getJSON(`${zeniAPI.apiEndPoints.communicationAgentMicroServiceBaseUrl}/1.0/batches?query=${encodeURIComponent(JSON.stringify(queryParam))}`)
19
+ .getJSON(`${zeniAPI.apiEndPoints.communicationAgentMicroServiceBaseUrl}/1.0/batches/${batchId}`)
31
20
  .pipe((0, operators_1.mergeMap)((response) => {
32
21
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
33
- const batchList = response.data.batches.map(missingReceiptsPayload_1.toBatchListItem);
34
- const currentBatch = batchList.find((b) => b.batchId === batchId);
35
- if (currentBatch?.status === 'completed') {
36
- return [
37
- (0, missingReceiptsViewReducer_1.fetchBulkUploadBatchesSuccess)({
38
- batchList,
39
- selectedPeriod,
40
- }),
41
- (0, missingReceiptsViewReducer_1.fetchBulkUploadBatchDetails)(),
42
- ];
22
+ if (response.data.status === 'completed') {
23
+ const actions = [];
24
+ const transactionPayloads = (0, missingReceiptsPayload_1.extractTransactionPayloadsFromBatchFiles)(response.data.files);
25
+ if (transactionPayloads.length > 0) {
26
+ actions.push((0, transactionReducer_1.updateTransactions)(transactionPayloads, (value) => value.transaction_id));
27
+ }
28
+ actions.push((0, missingReceiptsViewReducer_1.fetchBulkUploadBatchDetailsSuccess)((0, missingReceiptsPayload_1.toBatchDetails)(response.data, zeniAPI.apiEndPoints.fileMicroServiceBaseUrl)));
29
+ actions.push((0, missingReceiptsViewReducer_1.fetchBulkUploadBatches)(true));
30
+ return (0, rxjs_1.from)(actions);
43
31
  }
44
32
  }
45
33
  return [];
46
34
  }), (0, operators_1.catchError)(() => (0, rxjs_1.of)()));
47
35
  }), (0, operators_1.takeWhile)((emittedAction) => {
48
- if (missingReceiptsViewReducer_1.fetchBulkUploadBatchDetails.match(emittedAction)) {
36
+ if (missingReceiptsViewReducer_1.fetchBulkUploadBatchDetailsSuccess.match(emittedAction)) {
49
37
  return false;
50
38
  }
51
39
  return true;
@@ -36,7 +36,9 @@ export declare const fetchMissingReceipts: import("@reduxjs/toolkit").ActionCrea
36
36
  error: ZeniAPIStatus;
37
37
  }, "expenseAutomationMissingReceiptsView/bulkUploadReceiptsFailure">, pusherBatchStatusUpdate: import("@reduxjs/toolkit").ActionCreatorWithPayload<BatchStatus, "expenseAutomationMissingReceiptsView/pusherBatchStatusUpdate">, fetchBulkUploadBatchDetails: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationMissingReceiptsView/fetchBulkUploadBatchDetails">, fetchBulkUploadBatchDetailsSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<BatchDetails, "expenseAutomationMissingReceiptsView/fetchBulkUploadBatchDetailsSuccess">, fetchBulkUploadBatchDetailsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
38
38
  error: ZeniAPIStatus;
39
- }, "expenseAutomationMissingReceiptsView/fetchBulkUploadBatchDetailsFailure">, storeBatchDetails: import("@reduxjs/toolkit").ActionCreatorWithPayload<BatchDetails, "expenseAutomationMissingReceiptsView/storeBatchDetails">, fetchMoreBatchDetails: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationMissingReceiptsView/fetchMoreBatchDetails">, fetchMoreBatchDetailsComplete: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationMissingReceiptsView/fetchMoreBatchDetailsComplete">, fetchMoreBatchDetailsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
39
+ }, "expenseAutomationMissingReceiptsView/fetchBulkUploadBatchDetailsFailure">, storeBatchDetails: import("@reduxjs/toolkit").ActionCreatorWithPayload<BatchDetails, "expenseAutomationMissingReceiptsView/storeBatchDetails">, batchDetailFetchFailed: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
40
+ batchId: ID;
41
+ }, "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<{
40
42
  error: ZeniAPIStatus;
41
43
  }, "expenseAutomationMissingReceiptsView/fetchMoreBatchDetailsFailure">, fetchBulkUploadBatches: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[cacheOverride?: any], {
42
44
  cacheOverride: any;
@@ -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.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.storeBatchDetails = exports.fetchBulkUploadBatchDetailsFailure = exports.fetchBulkUploadBatchDetailsSuccess = exports.fetchBulkUploadBatchDetails = 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.initialState = exports.initialBulkUploadState = void 0;
4
+ exports.fetchCompletedTransactionsFailure = exports.fetchCompletedTransactionsSuccess = exports.fetchCompletedTransactions = 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.fetchBulkUploadBatchDetails = 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.initialState = exports.initialBulkUploadState = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
7
7
  exports.initialBulkUploadState = {
@@ -15,6 +15,7 @@ exports.initialBulkUploadState = {
15
15
  confirmMatchStatus: { fetchState: 'Not-Started', error: undefined },
16
16
  currentBatchId: undefined,
17
17
  currentResultsTab: 'unmatched',
18
+ failedBatchDetailIds: [],
18
19
  manualSearch: {
19
20
  fetchState: { fetchState: 'Not-Started', error: undefined },
20
21
  results: [],
@@ -201,6 +202,18 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
201
202
  const details = action.payload;
202
203
  draft.bulkUpload.batchDetailsById[details.batchId] = details;
203
204
  },
205
+ batchDetailFetchFailed(draft, action) {
206
+ const { batchId } = action.payload;
207
+ if (!draft.bulkUpload.failedBatchDetailIds.includes(batchId)) {
208
+ draft.bulkUpload.failedBatchDetailIds.push(batchId);
209
+ }
210
+ },
211
+ setInitialBatchDetailsLoading(draft) {
212
+ draft.bulkUpload.batchDetailsPaginationState = {
213
+ fetchState: 'In-Progress',
214
+ error: undefined,
215
+ };
216
+ },
204
217
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
205
218
  fetchMoreBatchDetails(_draft) {
206
219
  _draft.bulkUpload.batchDetailsPaginationState = {
@@ -403,7 +416,7 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
403
416
  });
404
417
  _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,
405
418
  // Bulk Upload
406
- exports.bulkUploadReceipts = _a.bulkUploadReceipts, exports.updateBulkUploadProgress = _a.updateBulkUploadProgress, exports.bulkUploadReceiptsSuccess = _a.bulkUploadReceiptsSuccess, exports.bulkUploadReceiptsFailure = _a.bulkUploadReceiptsFailure, exports.pusherBatchStatusUpdate = _a.pusherBatchStatusUpdate, exports.fetchBulkUploadBatchDetails = _a.fetchBulkUploadBatchDetails, exports.fetchBulkUploadBatchDetailsSuccess = _a.fetchBulkUploadBatchDetailsSuccess, exports.fetchBulkUploadBatchDetailsFailure = _a.fetchBulkUploadBatchDetailsFailure, exports.storeBatchDetails = _a.storeBatchDetails, 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,
419
+ exports.bulkUploadReceipts = _a.bulkUploadReceipts, exports.updateBulkUploadProgress = _a.updateBulkUploadProgress, exports.bulkUploadReceiptsSuccess = _a.bulkUploadReceiptsSuccess, exports.bulkUploadReceiptsFailure = _a.bulkUploadReceiptsFailure, exports.pusherBatchStatusUpdate = _a.pusherBatchStatusUpdate, exports.fetchBulkUploadBatchDetails = _a.fetchBulkUploadBatchDetails, 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,
407
420
  // Completed Transactions
408
421
  exports.fetchCompletedTransactions = _a.fetchCompletedTransactions, exports.fetchCompletedTransactionsSuccess = _a.fetchCompletedTransactionsSuccess, exports.fetchCompletedTransactionsFailure = _a.fetchCompletedTransactionsFailure;
409
422
  exports.default = expenseAutomationMissingReceiptsView.reducer;
@@ -15,6 +15,7 @@ export interface ResolvedCandidate {
15
15
  }
16
16
  export interface ResolvedBatchFile {
17
17
  attachmentId: ID;
18
+ batchId: ID;
18
19
  fileDownloadUrl: string | null;
19
20
  fileId: ID;
20
21
  filename: string;
@@ -65,8 +65,10 @@ function getExpenseAutomationMissingReceiptsView(state) {
65
65
  const currentBatchDetails = effectiveCurrentBatchId != null
66
66
  ? bulkUpload.batchDetailsById[effectiveCurrentBatchId]
67
67
  : undefined;
68
- const resolvedFiles = currentBatchDetails?.files.map((file) => resolveBatchFile(file, transactionState));
69
- const hasMoreBatchDetails = completedBatchesSorted.some((b) => bulkUpload.batchDetailsById[b.batchId] == null);
68
+ const resolvedFiles = currentBatchDetails?.files.map((file) => resolveBatchFile(file, currentBatchDetails.batchId, transactionState));
69
+ const failedIds = new Set(bulkUpload.failedBatchDetailIds);
70
+ const hasMoreBatchDetails = completedBatchesSorted.some((b) => bulkUpload.batchDetailsById[b.batchId] == null &&
71
+ !failedIds.has(b.batchId));
70
72
  const getSortValue = (file) => {
71
73
  const t = file.matchedTransaction;
72
74
  if (t == null) {
@@ -113,7 +115,7 @@ function getExpenseAutomationMissingReceiptsView(state) {
113
115
  }
114
116
  return details.files
115
117
  .filter((f) => f.status === 'un_matched' || f.status === 'no_match')
116
- .map((f) => resolveBatchFile(f, transactionState));
118
+ .map((f) => resolveBatchFile(f, b.batchId, transactionState));
117
119
  });
118
120
  const completedTransactionsForPeriod = monthYearPeriodId != null
119
121
  ? bulkUpload.completedTransactionsByPeriod[monthYearPeriodId]
@@ -170,7 +172,7 @@ function getExpenseAutomationMissingReceiptsView(state) {
170
172
  },
171
173
  };
172
174
  }
173
- function resolveBatchFile(file, transactionState) {
175
+ function resolveBatchFile(file, batchId, transactionState) {
174
176
  const matchedTransaction = file.matchedTransactionId != null
175
177
  ? (0, transactionSelector_1.getSupportedTransactionById)(transactionState, file.matchedTransactionId)
176
178
  : undefined;
@@ -184,6 +186,7 @@ function resolveBatchFile(file, transactionState) {
184
186
  .filter((c) => c != null);
185
187
  return {
186
188
  attachmentId: file.attachmentId,
189
+ batchId,
187
190
  fileDownloadUrl: file.fileDownloadUrl,
188
191
  fileId: file.fileId,
189
192
  filename: file.filename,
@@ -109,6 +109,7 @@ export interface BulkUploadState {
109
109
  completedTransactionsByPeriod: Record<MonthYearPeriodId, CompletedTransactionsState>;
110
110
  confirmMatchStatus: FetchStateAndError;
111
111
  currentResultsTab: BulkUploadResultsTab;
112
+ failedBatchDetailIds: ID[];
112
113
  manualSearch: ManualSearchState;
113
114
  phase: BulkUploadPhase;
114
115
  sortKey: BulkUploadSortKey;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "4.19.37-betaVR11",
3
+ "version": "4.19.37-betaVR13",
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",