@zeniai/client-epic-state 5.3.13 → 5.3.14-beta0MM

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 (30) hide show
  1. package/lib/commonStateTypes/animations.d.ts +1 -1
  2. package/lib/commonStateTypes/animations.js +0 -2
  3. package/lib/entity/actualMatching/actualMatchingPayload.d.ts +1 -0
  4. package/lib/entity/actualMatching/actualMatchingPayload.js +3 -0
  5. package/lib/entity/actualMatching/actualMatchingReducer.js +2 -1
  6. package/lib/entity/actualMatching/actualMatchingState.d.ts +1 -0
  7. package/lib/entity/actualMatching/actualMatchingTypes.d.ts +2 -0
  8. package/lib/entity/actualMatching/actualMatchingTypes.js +9 -0
  9. package/lib/esm/commonStateTypes/animations.js +0 -2
  10. package/lib/esm/entity/actualMatching/actualMatchingPayload.js +3 -0
  11. package/lib/esm/entity/actualMatching/actualMatchingReducer.js +2 -1
  12. package/lib/esm/entity/actualMatching/actualMatchingTypes.js +8 -1
  13. package/lib/esm/index.js +1 -0
  14. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingEpic.js +2 -1
  15. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.js +8 -2
  16. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.js +7 -3
  17. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/undoReversalAccrualsEpic.js +12 -7
  18. package/lib/esm/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +30 -23
  19. package/lib/esm/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +1 -0
  20. package/lib/index.d.ts +1 -0
  21. package/lib/index.js +4 -2
  22. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingEpic.js +2 -1
  23. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.js +8 -2
  24. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.js +7 -3
  25. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/undoReversalAccrualsEpic.js +12 -7
  26. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.d.ts +9 -3
  27. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +30 -23
  28. package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.d.ts +1 -0
  29. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +1 -0
  30. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- export declare const toAnimationsFileName: (v: string) => "Success" | "AiAgent" | "AiIconEntry" | "AiIconExit" | "AiIconLoop" | "AiStar" | "AiStarIcon" | "AiStarPlain" | "AIPoweredInvoiceDark" | "AIPoweredInvoiceLight" | "Angry" | "AutoTransfer" | "CloseCard" | "Confetti" | "ConfettiSuccess" | "DashboardChristmasSnow" | "DashboardHalloweenBats" | "DashboardNewYearShow" | "DashboardSidebarBottomChristmas" | "DashboardSidebarBottomHalloween" | "DashboardSidebarBottomNewYear" | "DashboardSidebarBottomThanksgiving" | "DashboardSidebarTopChristmas" | "DashboardSidebarTopHalloween" | "DashboardSidebarTopNewYear" | "DashboardSidebarTopThanksgiving" | "Distribution" | "DistributionDark" | "EarnYield" | "FastestWayDark" | "FastestWayLight" | "FinanceTeamDark" | "FinanceTeamLight" | "Happy" | "Liquidity" | "LockCard" | "MoneyTransferSuccess" | "MultiLevelApprovalDark" | "MultiLevelApprovalLight" | "NotHappy" | "Protection" | "ReceiptDark" | "ReceiptLight" | "Recurring" | "RecurringDark" | "ReimburseDark" | "ReimburseLight" | "RewardsDark" | "RewardsDarkHover" | "RewardsLight" | "RewardsLightHover" | "Ripple" | "Secure" | "Target" | "TargetDark" | "UnlockCard" | "VeryHappy" | "Welcome" | "ZeniAssist";
1
+ export declare const toAnimationsFileName: (v: string) => "Success" | "AiAgent" | "AiIconEntry" | "AiIconExit" | "AiIconLoop" | "AiStar" | "AiStarIcon" | "AiStarPlain" | "AIPoweredInvoiceDark" | "AIPoweredInvoiceLight" | "Angry" | "AutoTransfer" | "CloseCard" | "Confetti" | "ConfettiSuccess" | "DashboardChristmasSnow" | "DashboardHalloweenBats" | "DashboardNewYearShow" | "DashboardSidebarBottomChristmas" | "DashboardSidebarBottomNewYear" | "DashboardSidebarBottomThanksgiving" | "DashboardSidebarTopChristmas" | "DashboardSidebarTopNewYear" | "DashboardSidebarTopThanksgiving" | "Distribution" | "DistributionDark" | "EarnYield" | "FastestWayDark" | "FastestWayLight" | "FinanceTeamDark" | "FinanceTeamLight" | "Happy" | "Liquidity" | "LockCard" | "MoneyTransferSuccess" | "MultiLevelApprovalDark" | "MultiLevelApprovalLight" | "NotHappy" | "Protection" | "ReceiptDark" | "ReceiptLight" | "Recurring" | "RecurringDark" | "ReimburseDark" | "ReimburseLight" | "RewardsDark" | "RewardsDarkHover" | "RewardsLight" | "RewardsLightHover" | "Ripple" | "Secure" | "Target" | "TargetDark" | "UnlockCard" | "VeryHappy" | "Welcome" | "ZeniAssist";
2
2
  export type AnimationFileName = ReturnType<typeof toAnimationsFileName>;
@@ -21,11 +21,9 @@ const ALL_ANIMATIONS_FILE_NAMES = [
21
21
  'DashboardHalloweenBats',
22
22
  'DashboardNewYearShow',
23
23
  'DashboardSidebarBottomChristmas',
24
- 'DashboardSidebarBottomHalloween',
25
24
  'DashboardSidebarBottomNewYear',
26
25
  'DashboardSidebarBottomThanksgiving',
27
26
  'DashboardSidebarTopChristmas',
28
- 'DashboardSidebarTopHalloween',
29
27
  'DashboardSidebarTopNewYear',
30
28
  'DashboardSidebarTopThanksgiving',
31
29
  'Distribution',
@@ -17,6 +17,7 @@ export interface ActualMatchingMatchPayload {
17
17
  currency_code?: string | null;
18
18
  currency_symbol?: string | null;
19
19
  leftovers?: JEOneTimeAccrualPayload[];
20
+ match_batch_id?: string | null;
20
21
  match_shape?: string | null;
21
22
  match_tier?: string | null;
22
23
  transaction_date?: string | null;
@@ -34,6 +34,9 @@ function toActualMatchingMatch(payload, fallbackCurrency) {
34
34
  : currencyCode;
35
35
  return {
36
36
  matchId: payload.match_id,
37
+ matchBatchId: payload.match_batch_id != null && payload.match_batch_id !== ''
38
+ ? payload.match_batch_id
39
+ : undefined,
37
40
  transactionType: (payload.transaction_type || '').toLowerCase(),
38
41
  transactionIntegrationId: payload.transaction_integration_id,
39
42
  transactionDate: payload.transaction_date ?? undefined,
@@ -5,6 +5,7 @@ exports.updateActualMatchingMatches = exports.removeActualMatchingMatch = export
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  const rootActions_1 = require("../../rootActions");
7
7
  const actualMatchingPayload_1 = require("./actualMatchingPayload");
8
+ const actualMatchingTypes_1 = require("./actualMatchingTypes");
8
9
  exports.initialState = {
9
10
  byMatchId: {},
10
11
  };
@@ -19,7 +20,7 @@ const actualMatching = (0, toolkit_1.createSlice)({
19
20
  reducer(draft, action) {
20
21
  action.payload.matches.forEach((payload) => {
21
22
  const match = (0, actualMatchingPayload_1.toActualMatchingMatch)(payload, action.payload.fallbackCurrency);
22
- draft.byMatchId[match.matchId] = match;
23
+ draft.byMatchId[(0, actualMatchingTypes_1.actualMatchingRowKey)(match.matchId, match.matchBatchId)] = match;
23
24
  });
24
25
  },
25
26
  },
@@ -12,6 +12,7 @@ export interface ActualMatchingMatch {
12
12
  transactionIntegrationId: ID;
13
13
  transactionType: string;
14
14
  leftovers?: JEOneTimeAccrualState[];
15
+ matchBatchId?: string;
15
16
  matchShape?: string;
16
17
  matchTier?: string;
17
18
  transactionDate?: string;
@@ -1 +1,3 @@
1
1
  export type ActualMatchingMatchId = string;
2
+ /** Store and status key. The route match id stays ``type:id``; the batch is separate. */
3
+ export declare function actualMatchingRowKey(matchId: string, matchBatchId?: string | null): string;
@@ -1,2 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.actualMatchingRowKey = actualMatchingRowKey;
4
+ /** Store and status key. The route match id stays ``type:id``; the batch is separate. */
5
+ function actualMatchingRowKey(matchId, matchBatchId) {
6
+ const batch = (matchBatchId ?? '').trim();
7
+ if (batch === '') {
8
+ return matchId;
9
+ }
10
+ return `${matchId}\u0000${batch}`;
11
+ }
@@ -18,11 +18,9 @@ const ALL_ANIMATIONS_FILE_NAMES = [
18
18
  'DashboardHalloweenBats',
19
19
  'DashboardNewYearShow',
20
20
  'DashboardSidebarBottomChristmas',
21
- 'DashboardSidebarBottomHalloween',
22
21
  'DashboardSidebarBottomNewYear',
23
22
  'DashboardSidebarBottomThanksgiving',
24
23
  'DashboardSidebarTopChristmas',
25
- 'DashboardSidebarTopHalloween',
26
24
  'DashboardSidebarTopNewYear',
27
25
  'DashboardSidebarTopThanksgiving',
28
26
  'Distribution',
@@ -30,6 +30,9 @@ export function toActualMatchingMatch(payload, fallbackCurrency) {
30
30
  : currencyCode;
31
31
  return {
32
32
  matchId: payload.match_id,
33
+ matchBatchId: payload.match_batch_id != null && payload.match_batch_id !== ''
34
+ ? payload.match_batch_id
35
+ : undefined,
33
36
  transactionType: (payload.transaction_type || '').toLowerCase(),
34
37
  transactionIntegrationId: payload.transaction_integration_id,
35
38
  transactionDate: payload.transaction_date ?? undefined,
@@ -1,6 +1,7 @@
1
1
  import { createSlice } from '@reduxjs/toolkit';
2
2
  import { clearAll } from '../../rootActions';
3
3
  import { toActualMatchingMatch, } from './actualMatchingPayload';
4
+ import { actualMatchingRowKey, } from './actualMatchingTypes';
4
5
  export const initialState = {
5
6
  byMatchId: {},
6
7
  };
@@ -15,7 +16,7 @@ const actualMatching = createSlice({
15
16
  reducer(draft, action) {
16
17
  action.payload.matches.forEach((payload) => {
17
18
  const match = toActualMatchingMatch(payload, action.payload.fallbackCurrency);
18
- draft.byMatchId[match.matchId] = match;
19
+ draft.byMatchId[actualMatchingRowKey(match.matchId, match.matchBatchId)] = match;
19
20
  });
20
21
  },
21
22
  },
@@ -1 +1,8 @@
1
- export {};
1
+ /** Store and status key. The route match id stays ``type:id``; the batch is separate. */
2
+ export function actualMatchingRowKey(matchId, matchBatchId) {
3
+ const batch = (matchBatchId ?? '').trim();
4
+ if (batch === '') {
5
+ return matchId;
6
+ }
7
+ return `${matchId}\u0000${batch}`;
8
+ }
package/lib/esm/index.js CHANGED
@@ -875,6 +875,7 @@ export { getInvoicingOnboardingGateView } from './view/invoicing/invoicingConfig
875
875
  // narrow a JEScheduleRow before reading baseTransaction / recurringAmount.
876
876
  export { getExpenseAutomationJEOneTimeAccrualDetailView, getJEScheduleRowType, isAccruedScheduleRow, isAiAccountantSchedule, isExistingTabRow, isOneTimeAccrualRow, isRenderableOneTimeAccrual, isPendingReviewRow, } from './view/expenseAutomationView/selectors/jeSchedulesViewSelector';
877
877
  export { getActualMatchingAmount, getActualMatchingReversalDate, getActualMatchingMatchModalConfirmStatus, getCloseMatchAfterIgnoreMatchId, getCloseMatchAfterUndo, getCloseMatchAfterUndoMatchId, parseActualMatchingMatchId, getExpenseAutomationActualMatchingMatchView, getExpenseAutomationActualMatchingView, isAutoReversedAccrual, isManuallyReversedAccrual, isPendingReviewAccrual, } from './view/expenseAutomationView/selectors/actualMatchingViewSelector';
878
+ export { actualMatchingRowKey } from './entity/actualMatching/actualMatchingTypes';
878
879
  export { fetchCustomerSummaryDetail, fetchCustomerSummaryList, resetCustomerSummaryDetailUiState, saveCustomerSummaryDetail, updateCustomerAllTransactionsTabData, updateCustomerDetailSelectedTab, updateCustomerSummaryRevenueSelection, updateCustomerSummaryScrollYOffset, updateCustomerSummarySortUiState, updateCustomerTrendFilter, } from './view/customerSummaryView/customerSummaryViewReducer';
879
880
  export { getCustomerSummaryAllTransactionsTabData, getCustomerSummaryDetail, getCustomerSummaryList, getCustomerSummarySelectedTabType, getCustomerSummaryTrendFilter, isCustomersTabVisible, } from './view/customerSummaryView/customerSummaryViewSelector';
880
881
  export { CUSTOMER_REVENUE_KEYS } from './view/customerSummaryView/customerSummaryViewState';
@@ -1,6 +1,7 @@
1
1
  import { from, of } from 'rxjs';
2
2
  import { catchError, filter, mergeMap, switchMap, takeUntil, } from 'rxjs/operators';
3
3
  import { updateActualMatchingMatches } from '../../../../../entity/actualMatching/actualMatchingReducer';
4
+ import { actualMatchingRowKey } from '../../../../../entity/actualMatching/actualMatchingTypes';
4
5
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
5
6
  import { clearAll } from '../../../../../rootActions';
6
7
  import { toServiceMonthFromPeriod, } from '../../../payload/actualMatchingPayload';
@@ -26,7 +27,7 @@ export const fetchActualMatchingEpic = (actions$, state$, zeniAPI) => actions$.p
26
27
  updateActions.push(updateActualMatchingMatches(matches, getTenantDisplayCurrency(state)));
27
28
  }
28
29
  updateActions.push(fetchActualMatchingSuccess({
29
- matchIds: matches.map((match) => match.match_id),
30
+ matchIds: matches.map((match) => actualMatchingRowKey(match.match_id, match.match_batch_id)),
30
31
  selectedPeriod: requestPeriod,
31
32
  refreshViewInBackground,
32
33
  }));
@@ -6,15 +6,19 @@ import { clearAll } from '../../../../../rootActions';
6
6
  import { fetchActualMatchingMatch, fetchActualMatchingMatchFailure, fetchActualMatchingMatchSuccess, } from '../../../reducers/actualMatchingViewReducer';
7
7
  import { getTenantDisplayCurrency } from '../../../selectors/actualMatchingViewSelector';
8
8
  export const fetchActualMatchingMatchEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchActualMatchingMatch.match), mergeMap((action) => {
9
- const { matchId, refreshViewInBackground } = action.payload;
9
+ const { matchId, matchBatchId, refreshViewInBackground } = action.payload;
10
+ const batchQuery = matchBatchId != null && matchBatchId !== ''
11
+ ? `?batch_id=${encodeURIComponent(matchBatchId)}`
12
+ : '';
10
13
  return zeniAPI
11
- .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals/actual-matching/${encodeURIComponent(matchId)}`)
14
+ .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals/actual-matching/${encodeURIComponent(matchId)}${batchQuery}`)
12
15
  .pipe(mergeMap((response) => {
13
16
  if (isSuccessResponse(response) && response.data != null) {
14
17
  return from([
15
18
  updateActualMatchingMatches([response.data], getTenantDisplayCurrency(state$.value)),
16
19
  fetchActualMatchingMatchSuccess({
17
20
  matchId,
21
+ matchBatchId,
18
22
  refreshViewInBackground,
19
23
  }),
20
24
  ]);
@@ -22,6 +26,7 @@ export const fetchActualMatchingMatchEpic = (actions$, state$, zeniAPI) => actio
22
26
  return from([
23
27
  fetchActualMatchingMatchFailure({
24
28
  matchId,
29
+ matchBatchId,
25
30
  refreshViewInBackground,
26
31
  status: response.status,
27
32
  }),
@@ -29,6 +34,7 @@ export const fetchActualMatchingMatchEpic = (actions$, state$, zeniAPI) => actio
29
34
  }), catchError((error) => from([
30
35
  fetchActualMatchingMatchFailure({
31
36
  matchId,
37
+ matchBatchId,
32
38
  refreshViewInBackground,
33
39
  status: createZeniAPIStatus('Unexpected Error', `Fetch actual matching match REST API call errored out ${JSON.stringify(error)}`),
34
40
  }),
@@ -56,8 +56,12 @@ function matchAndReverseHttpFailSnackbar(vendorName) {
56
56
  });
57
57
  }
58
58
  function matchVendorName(state, matchId) {
59
- return (getActualMatchingMatchById(state.actualMatchingState, matchId)
60
- ?.vendorName ?? '');
59
+ const stored = getActualMatchingMatchById(state.actualMatchingState, matchId);
60
+ if (stored?.vendorName != null && stored.vendorName !== '') {
61
+ return stored.vendorName;
62
+ }
63
+ const sameBill = Object.values(state.actualMatchingState.byMatchId).find((match) => match.matchId === matchId);
64
+ return sameBill?.vendorName ?? '';
61
65
  }
62
66
  export const matchAndReverseAccrualsEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(matchAndReverseAccruals.match),
63
67
  // Per-match exhaust: a second click on the same match drops while HTTP is in
@@ -96,7 +100,7 @@ groupBy((action) => `${action.payload.transactionType.toLowerCase()}:${action.pa
96
100
  // List + detail: list can omit leftovers; detail GET always
97
101
  // writes intended occupancy so leftover retry can join C
98
102
  // onto the occupied bill instead of a stale cached row.
99
- successActions.push(...refreshActualMatchingList(state$.value), fetchActualMatchingMatch(matchId, true));
103
+ successActions.push(...refreshActualMatchingList(state$.value), fetchActualMatchingMatch(matchId, true, response.data.match_batch_id));
100
104
  }
101
105
  const snackbar = matchAndReverseSnackbar(results, vendorName);
102
106
  if (snackbar != null) {
@@ -1,6 +1,7 @@
1
1
  import { from, of } from 'rxjs';
2
2
  import { catchError, exhaustMap, filter, groupBy, mergeMap, takeUntil, } from 'rxjs/operators';
3
3
  import { getActualMatchingMatchById } from '../../../../../entity/actualMatching/actualMatchingSelector';
4
+ import { actualMatchingRowKey } from '../../../../../entity/actualMatching/actualMatchingTypes';
4
5
  import { openSnackbar } from '../../../../../entity/snackbar/snackbarReducer';
5
6
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
6
7
  import { clearAll } from '../../../../../rootActions';
@@ -37,41 +38,45 @@ function undoReversalSnackbar(results, vendorName) {
37
38
  variables,
38
39
  });
39
40
  }
40
- function matchVendorName(state, matchId) {
41
- return (getActualMatchingMatchById(state.actualMatchingState, matchId)?.vendorName ??
41
+ function matchVendorName(state, matchId, matchBatchId) {
42
+ const rowKey = actualMatchingRowKey(matchId, matchBatchId);
43
+ return (getActualMatchingMatchById(state.actualMatchingState, rowKey)?.vendorName ??
44
+ getActualMatchingMatchById(state.actualMatchingState, matchId)?.vendorName ??
42
45
  '');
43
46
  }
44
47
  export const undoReversalAccrualsEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(undoReversalAccruals.match),
45
48
  // Per-match exhaust: a second click on the same match drops while HTTP is in
46
49
  // flight. A different match must still run — a global exhaustMap left the
47
50
  // other match's reducer In-Progress with no request.
48
- groupBy((action) => action.payload.matchId), mergeMap((perMatch$) => perMatch$.pipe(exhaustMap((action) => {
49
- const { accrualIds, matchId } = action.payload;
51
+ groupBy((action) => actualMatchingRowKey(action.payload.matchId, action.payload.matchBatchId)), mergeMap((perMatch$) => perMatch$.pipe(exhaustMap((action) => {
52
+ const { accrualIds, matchId, matchBatchId } = action.payload;
50
53
  const body = {
51
54
  accrual_ids: accrualIds,
52
55
  };
53
- const vendorName = matchVendorName(state$.value, matchId);
56
+ const vendorName = matchVendorName(state$.value, matchId, matchBatchId);
54
57
  return zeniAPI
55
58
  .postAndGetJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals/undo-reversal`, body)
56
59
  .pipe(mergeMap((response) => {
57
60
  if (isSuccessResponse(response) && response.data != null) {
58
61
  const results = response.data.results.map(toUndoReversalResult);
59
62
  const successActions = [
60
- undoReversalAccrualsSuccess(matchId, results),
63
+ undoReversalAccrualsSuccess(matchId, results, matchBatchId),
61
64
  ];
62
65
  const anyUndone = results.some((result) => result.status === 'undone');
63
66
  if (anyUndone) {
64
- successActions.push(...refreshActualMatchingList(state$.value), fetchActualMatchingMatch(matchId, true));
67
+ successActions.push(...refreshActualMatchingList(state$.value), fetchActualMatchingMatch(matchId, true, matchBatchId));
65
68
  }
66
69
  successActions.push(undoReversalSnackbar(results, vendorName));
67
70
  return from(successActions);
68
71
  }
69
72
  return of(undoReversalAccrualsFailure({
70
73
  matchId,
74
+ matchBatchId,
71
75
  status: response.status,
72
76
  }), undoReversalSnackbar([], vendorName));
73
77
  }), catchError((error) => of(undoReversalAccrualsFailure({
74
78
  matchId,
79
+ matchBatchId,
75
80
  status: createZeniAPIStatus('Unexpected Error', 'Undo reversal accruals REST API call errored out' +
76
81
  JSON.stringify(error)),
77
82
  }), undoReversalSnackbar([], vendorName))), takeUntil(actions$.pipe(filter(clearAll.match))));
@@ -1,5 +1,6 @@
1
1
  import { createSlice } from '@reduxjs/toolkit';
2
2
  import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
3
+ import { actualMatchingRowKey } from '../../../entity/actualMatching/actualMatchingTypes';
3
4
  import { generateJEOneTimeAccrualKey } from '../../../entity/jeSchedules/jeScheduleHelper';
4
5
  import { createZeniAPIStatus } from '../../../responsePayload';
5
6
  import { clearAll } from '../../../rootActions';
@@ -183,19 +184,20 @@ const expenseAutomationActualMatchingView = createSlice({
183
184
  }
184
185
  },
185
186
  fetchActualMatchingMatch: {
186
- prepare(matchId, refreshViewInBackground = false) {
187
- return { payload: { matchId, refreshViewInBackground } };
187
+ prepare(matchId, refreshViewInBackground = false, matchBatchId) {
188
+ return { payload: { matchId, matchBatchId, refreshViewInBackground } };
188
189
  },
189
190
  reducer(draft, action) {
190
- const { matchId, refreshViewInBackground } = action.payload;
191
+ const { matchId, matchBatchId, refreshViewInBackground } = action.payload;
192
+ const rowKey = actualMatchingRowKey(matchId, matchBatchId);
191
193
  if (refreshViewInBackground) {
192
- draft.detailRefreshStatusByMatchId[matchId] = {
194
+ draft.detailRefreshStatusByMatchId[rowKey] = {
193
195
  fetchState: 'In-Progress',
194
196
  error: undefined,
195
197
  };
196
198
  }
197
199
  else {
198
- draft.detailFetchStateByMatchId[matchId] = {
200
+ draft.detailFetchStateByMatchId[rowKey] = {
199
201
  fetchState: 'In-Progress',
200
202
  error: undefined,
201
203
  };
@@ -203,30 +205,32 @@ const expenseAutomationActualMatchingView = createSlice({
203
205
  },
204
206
  },
205
207
  fetchActualMatchingMatchSuccess(draft, action) {
206
- const { matchId, refreshViewInBackground } = action.payload;
208
+ const { matchId, matchBatchId, refreshViewInBackground } = action.payload;
209
+ const rowKey = actualMatchingRowKey(matchId, matchBatchId);
207
210
  if (refreshViewInBackground) {
208
- draft.detailRefreshStatusByMatchId[matchId] = {
211
+ draft.detailRefreshStatusByMatchId[rowKey] = {
209
212
  fetchState: 'Completed',
210
213
  error: undefined,
211
214
  };
212
215
  }
213
216
  else {
214
- draft.detailFetchStateByMatchId[matchId] = {
217
+ draft.detailFetchStateByMatchId[rowKey] = {
215
218
  fetchState: 'Completed',
216
219
  error: undefined,
217
220
  };
218
221
  }
219
222
  },
220
223
  fetchActualMatchingMatchFailure(draft, action) {
221
- const { matchId, refreshViewInBackground, status } = action.payload;
224
+ const { matchId, matchBatchId, refreshViewInBackground, status } = action.payload;
225
+ const rowKey = actualMatchingRowKey(matchId, matchBatchId);
222
226
  if (refreshViewInBackground) {
223
- draft.detailRefreshStatusByMatchId[matchId] = {
227
+ draft.detailRefreshStatusByMatchId[rowKey] = {
224
228
  fetchState: 'Error',
225
229
  error: status,
226
230
  };
227
231
  }
228
232
  else {
229
- draft.detailFetchStateByMatchId[matchId] = {
233
+ draft.detailFetchStateByMatchId[rowKey] = {
230
234
  fetchState: 'Error',
231
235
  error: status,
232
236
  };
@@ -417,40 +421,42 @@ const expenseAutomationActualMatchingView = createSlice({
417
421
  },
418
422
  undoReversalAccruals: {
419
423
  reducer(draft, action) {
420
- draft.undoReversalStatusByMatchId[action.payload.matchId] = {
424
+ const rowKey = actualMatchingRowKey(action.payload.matchId, action.payload.matchBatchId);
425
+ draft.undoReversalStatusByMatchId[rowKey] = {
421
426
  fetchState: 'In-Progress',
422
427
  error: undefined,
423
428
  };
424
429
  },
425
- prepare(matchId, accrualIds) {
426
- return { payload: { matchId, accrualIds } };
430
+ prepare(matchId, accrualIds, matchBatchId) {
431
+ return { payload: { matchId, accrualIds, matchBatchId } };
427
432
  },
428
433
  },
429
434
  undoReversalAccrualsSuccess: {
430
435
  reducer(draft, action) {
431
- const { matchId, results } = action.payload;
432
- draft.undoReversalStatusByMatchId[matchId] = {
436
+ const { matchId, matchBatchId, results } = action.payload;
437
+ const rowKey = actualMatchingRowKey(matchId, matchBatchId);
438
+ draft.undoReversalStatusByMatchId[rowKey] = {
433
439
  fetchState: 'Completed',
434
440
  error: undefined,
435
441
  };
436
442
  const allUndone = results.length > 0 &&
437
443
  results.every((result) => result.status === 'undone');
438
444
  if (allUndone) {
439
- enqueueCloseMatchId(draft.closeMatchAfterUndoMatchIds, matchId);
445
+ enqueueCloseMatchId(draft.closeMatchAfterUndoMatchIds, rowKey);
440
446
  }
441
447
  else {
442
- draft.closeMatchAfterUndoMatchIds = dropCloseMatchId(draft.closeMatchAfterUndoMatchIds, matchId);
448
+ draft.closeMatchAfterUndoMatchIds = dropCloseMatchId(draft.closeMatchAfterUndoMatchIds, rowKey);
443
449
  }
444
450
  pruneLastMatchResultsForUndone(draft, matchId, results);
445
451
  if (allUndone) {
446
- delete draft.lastUndoResultsByMatchId[matchId];
452
+ delete draft.lastUndoResultsByMatchId[rowKey];
447
453
  }
448
454
  else {
449
- draft.lastUndoResultsByMatchId[matchId] = results;
455
+ draft.lastUndoResultsByMatchId[rowKey] = results;
450
456
  }
451
457
  },
452
- prepare(matchId, results) {
453
- return { payload: { matchId, results } };
458
+ prepare(matchId, results, matchBatchId) {
459
+ return { payload: { matchId, results, matchBatchId } };
454
460
  },
455
461
  },
456
462
  ackCloseMatchAfterUndo(draft) {
@@ -494,7 +500,8 @@ const expenseAutomationActualMatchingView = createSlice({
494
500
  draft.closeMatchAfterIgnoreMatchIds.shift();
495
501
  },
496
502
  undoReversalAccrualsFailure(draft, action) {
497
- draft.undoReversalStatusByMatchId[action.payload.matchId] = {
503
+ const rowKey = actualMatchingRowKey(action.payload.matchId, action.payload.matchBatchId);
504
+ draft.undoReversalStatusByMatchId[rowKey] = {
498
505
  fetchState: 'Error',
499
506
  error: action.payload.status,
500
507
  };
@@ -131,6 +131,7 @@ function toActualMatchingRow(match) {
131
131
  return {
132
132
  ...first,
133
133
  matchId: match.matchId,
134
+ matchBatchId: match.matchBatchId,
134
135
  kind: match.kind,
135
136
  accruedAmount: match.accruedAmount,
136
137
  actualAmount: match.actualAmount,
package/lib/index.d.ts CHANGED
@@ -1274,6 +1274,7 @@ export type { ExpenseAutomationActualMatchingMatchView } from './view/expenseAut
1274
1274
  export type { ActualMatchingMatch, ActualMatchingMatchKind, } from './entity/actualMatching/actualMatchingState';
1275
1275
  export type { ActualMatchingMatchId } from './entity/actualMatching/actualMatchingTypes';
1276
1276
  export type { SessionEndpointsLoader } from './sessionEndpointsLoader';
1277
+ export { actualMatchingRowKey } from './entity/actualMatching/actualMatchingTypes';
1277
1278
  export type { DisplayCurrencyFallback } from './entity/actualMatching/actualMatchingPayload';
1278
1279
  export { fetchCustomerSummaryDetail, fetchCustomerSummaryList, resetCustomerSummaryDetailUiState, saveCustomerSummaryDetail, updateCustomerAllTransactionsTabData, updateCustomerDetailSelectedTab, updateCustomerSummaryRevenueSelection, updateCustomerSummaryScrollYOffset, updateCustomerSummarySortUiState, updateCustomerTrendFilter, } from './view/customerSummaryView/customerSummaryViewReducer';
1279
1280
  export { getCustomerSummaryAllTransactionsTabData, getCustomerSummaryDetail, getCustomerSummaryList, getCustomerSummarySelectedTabType, getCustomerSummaryTrendFilter, isCustomersTabVisible, } from './view/customerSummaryView/customerSummaryViewSelector';
package/lib/index.js CHANGED
@@ -86,8 +86,8 @@ exports.startInvoicingMigration = exports.rollbackInvoicingMigration = exports.r
86
86
  exports.updateInvoicingTransactionFilters = exports.setInvoicingTransactionActiveTab = exports.fetchInvoicingTransactionListPage = exports.fetchInvoicingTransactionList = exports.updateInvoicingTransactions = exports.removeInvoicingTransaction = exports.getInvoicingSubscriptionById = exports.fetchInvoicingSubscriptionDetailPage = exports.fetchInvoicingSubscriptionDetail = exports.getInvoicingSubscriptionListView = exports.INVOICING_SUBSCRIPTION_COLUMNS = exports.ALL_INVOICING_SUBSCRIPTION_TAB_IDS = exports.ALL_INVOICING_SUBSCRIPTION_SORT_KEYS = exports.updateInvoicingSubscriptionFilters = exports.setInvoicingSubscriptionActiveTab = exports.fetchInvoicingSubscriptionListPage = exports.fetchInvoicingSubscriptionList = exports.fetchInvoicingSubscriptionCounts = exports.updateInvoicingSubscriptions = exports.removeInvoicingSubscription = exports.resetPromotionalCreditAction = exports.submitAddPromotionalCredits = exports.getInvoicingSetupIntentFetchState = exports.getInvoicingSetupIntent = exports.getInvoicingSentPaymentLinkMagicUrl = exports.getInvoicingSentPaymentLinkEmail = exports.getInvoicingPlaidLinkToken = exports.getInvoicingPaymentMethodSaveState = exports.getInvoicingPaymentLinkSendState = exports.sendInvoicingPaymentLink = exports.saveInvoicingPaymentMethod = exports.resetInvoicingCustomerPaymentMethod = exports.fetchInvoicingPlaidLinkToken = exports.createInvoicingSetupIntent = exports.fetchInvoicingPaymentLinkEmailPreviewPage = exports.fetchInvoicingCustomerDetailPage = exports.fetchInvoicingCustomerDetail = exports.getInvoicingCustomerListView = exports.INVOICING_CUSTOMER_COLUMNS = exports.ALL_INVOICING_CUSTOMER_TAB_IDS = exports.ALL_INVOICING_CUSTOMER_SORT_KEYS = exports.updateInvoicingCustomerFilters = exports.setInvoicingCustomerActiveTab = exports.fetchInvoicingCustomerListPage = exports.fetchInvoicingCustomerList = exports.fetchInvoicingCustomerCounts = exports.updateInvoicingCustomers = exports.removeInvoicingCustomer = exports.INVOICING_LIST_PAGE_SIZE = exports.uploadInvoicingMigrationFiles = void 0;
87
87
  exports.INVOICING_DUNNING_CASE_COLUMNS = exports.ALL_INVOICING_DUNNING_CASE_TAB_IDS = exports.ALL_INVOICING_DUNNING_CASE_SORT_KEYS = exports.updateInvoicingDunningCaseFilters = exports.setInvoicingDunningCaseActiveTab = exports.fetchInvoicingDunningCaseListPage = exports.fetchInvoicingDunningCaseList = exports.fetchInvoicingDunningCaseCounts = exports.updateInvoicingDunningCases = exports.removeInvoicingDunningCase = exports.fetchInvoicingCouponDetail = exports.getInvoicingCouponById = exports.getInvoicingCouponListView = exports.getInvoicingCouponListNextCursor = exports.getInvoicingCouponListItems = exports.getInvoicingCouponListHasMore = exports.getInvoicingCouponListFilters = exports.getInvoicingCouponListFetchState = exports.getInvoicingCouponCounts = exports.INVOICING_COUPON_COLUMNS = exports.ALL_INVOICING_COUPON_TAB_IDS = exports.ALL_INVOICING_COUPON_SORT_KEYS = exports.updateInvoicingCouponFilters = exports.setInvoicingCouponActiveTab = exports.fetchInvoicingCouponListPage = exports.fetchInvoicingCouponList = exports.fetchInvoicingCouponCounts = exports.updateInvoicingCoupons = exports.removeInvoicingCoupon = exports.getInvoicingCreditNoteDetail = exports.getInvoicingCreditNoteById = exports.fetchInvoicingCreditNoteDetail = exports.getInvoicingCreditNoteListView = exports.INVOICING_CREDIT_NOTE_COLUMNS = exports.ALL_INVOICING_CREDIT_NOTE_TAB_IDS = exports.ALL_INVOICING_CREDIT_NOTE_SORT_KEYS = exports.updateInvoicingCreditNoteFilters = exports.setInvoicingCreditNoteActiveTab = exports.fetchInvoicingCreditNoteListPage = exports.fetchInvoicingCreditNoteList = exports.fetchInvoicingCreditNoteCounts = exports.updateInvoicingCreditNotes = exports.removeInvoicingCreditNote = exports.getInvoicingTransactionDetail = exports.getInvoicingTransactionById = exports.fetchInvoicingTransactionDetail = exports.getInvoicingTransactionListView = exports.INVOICING_TRANSACTION_COLUMNS = exports.ALL_INVOICING_TRANSACTION_TAB_IDS = exports.ALL_INVOICING_TRANSACTION_SORT_KEYS = void 0;
88
88
  exports.fetchInvoicingQboSyncHealth = exports.fetchInvoicingQboConnection = exports.fetchInvoicingAccountingPickers = exports.isStripeConnectedFromSettings = exports.initialInvoicingBrandingFormLocalData = exports.entityToInvoicingBrandingFormLocalData = exports.INVOICING_BUSINESS_ADDRESS_TYPE = exports.invoicingQboSettingsLocalDataToPayload = exports.initialInvoicingQboSettingsLocalData = exports.entityToInvoicingQboSettingsLocalData = exports.getInvoicingSettingsView = exports.getInvoicingSettingsHubView = exports.getInvoicingSettingsFetchState = exports.getInvoicingSettings = exports.getInvoicingQboSettingsFormView = exports.getInvoicingBrandingFormView = exports.updateInvoicingSettings = exports.updateInvoicingQboSettingsDraft = exports.updateInvoicingBrandingFormDraft = exports.submitInvoicingQboSettings = exports.submitInvoicingBrandingForm = exports.saveInvoicingSettings = exports.resetSaveInvoicingSettings = exports.resetInvoicingQboSettingsDraft = exports.resetInvoicingBrandingFormDraft = exports.fetchInvoicingSettings = exports.disconnectInvoicingStripe = exports.connectInvoicingStripe = exports.getLowestInvoicingCatalogPricePointAmount = exports.getInvoicingCatalogItemById = exports.fetchInvoicingCatalogItemDetail = exports.getInvoicingCatalogListView = exports.updateInvoicingCatalogProductFilters = exports.updateInvoicingCatalogPlanFilters = exports.fetchInvoicingCatalogProductList = exports.fetchInvoicingCatalogPlanList = exports.fetchInvoicingCatalogListPage = exports.fetchInvoicingCatalogCounts = exports.updateInvoicingCatalogItems = exports.removeInvoicingCatalogItem = exports.mergeInvoicingCatalogPricePoint = exports.getInvoicingDunningEmailPreview = exports.getInvoicingDunningCaseDetail = exports.getInvoicingDunningCaseById = exports.invalidateInvoicingDunningEmailPreview = exports.fetchInvoicingDunningEmailPreviewPage = exports.fetchInvoicingDunningCaseDetailPage = exports.fetchInvoicingDunningCaseDetail = exports.clearInvoicingDunningCaseDetailView = exports.getInvoicingDunningCaseListView = void 0;
89
- exports.getCustomerSummaryTrendFilter = exports.getCustomerSummarySelectedTabType = exports.getCustomerSummaryList = exports.getCustomerSummaryDetail = exports.getCustomerSummaryAllTransactionsTabData = exports.updateCustomerTrendFilter = exports.updateCustomerSummarySortUiState = exports.updateCustomerSummaryScrollYOffset = exports.updateCustomerSummaryRevenueSelection = exports.updateCustomerDetailSelectedTab = exports.updateCustomerAllTransactionsTabData = exports.saveCustomerSummaryDetail = exports.resetCustomerSummaryDetailUiState = exports.fetchCustomerSummaryList = exports.fetchCustomerSummaryDetail = exports.isPendingReviewAccrual = exports.isManuallyReversedAccrual = exports.isAutoReversedAccrual = exports.getExpenseAutomationActualMatchingView = exports.getExpenseAutomationActualMatchingMatchView = exports.parseActualMatchingMatchId = exports.getCloseMatchAfterUndoMatchId = exports.getCloseMatchAfterUndo = exports.getCloseMatchAfterIgnoreMatchId = exports.getActualMatchingMatchModalConfirmStatus = exports.getActualMatchingReversalDate = exports.getActualMatchingAmount = exports.isPendingReviewRow = exports.isRenderableOneTimeAccrual = exports.isOneTimeAccrualRow = exports.isExistingTabRow = exports.isAiAccountantSchedule = exports.isAccruedScheduleRow = exports.getJEScheduleRowType = exports.getExpenseAutomationJEOneTimeAccrualDetailView = exports.getInvoicingOnboardingGateView = exports.getInvoicingConfigView = exports.updateInvoicingConfig = exports.resetInvoicingConfigActionStates = exports.fetchInvoicingConfig = exports.enableInvoicing = exports.acceptInvoicingTerms = exports.toInvoicingQboCustomerMatchingMode = exports.toInvoicingNamedOptionsByKey = exports.getInvoicingQboAccountMappingId = exports.INVOICING_QBO_CUSTOMER_MATCHING_MODES = exports.getInvoicingQboView = exports.invoicingAccountsForQboAccountTypes = exports.startInvoicingQboBackfill = exports.retryInvoicingQboSyncTask = void 0;
90
- exports.CUSTOMER_REVENUE_KEYS = exports.isCustomersTabVisible = void 0;
89
+ exports.getCustomerSummarySelectedTabType = exports.getCustomerSummaryList = exports.getCustomerSummaryDetail = exports.getCustomerSummaryAllTransactionsTabData = exports.updateCustomerTrendFilter = exports.updateCustomerSummarySortUiState = exports.updateCustomerSummaryScrollYOffset = exports.updateCustomerSummaryRevenueSelection = exports.updateCustomerDetailSelectedTab = exports.updateCustomerAllTransactionsTabData = exports.saveCustomerSummaryDetail = exports.resetCustomerSummaryDetailUiState = exports.fetchCustomerSummaryList = exports.fetchCustomerSummaryDetail = exports.actualMatchingRowKey = exports.isPendingReviewAccrual = exports.isManuallyReversedAccrual = exports.isAutoReversedAccrual = exports.getExpenseAutomationActualMatchingView = exports.getExpenseAutomationActualMatchingMatchView = exports.parseActualMatchingMatchId = exports.getCloseMatchAfterUndoMatchId = exports.getCloseMatchAfterUndo = exports.getCloseMatchAfterIgnoreMatchId = exports.getActualMatchingMatchModalConfirmStatus = exports.getActualMatchingReversalDate = exports.getActualMatchingAmount = exports.isPendingReviewRow = exports.isRenderableOneTimeAccrual = exports.isOneTimeAccrualRow = exports.isExistingTabRow = exports.isAiAccountantSchedule = exports.isAccruedScheduleRow = exports.getJEScheduleRowType = exports.getExpenseAutomationJEOneTimeAccrualDetailView = exports.getInvoicingOnboardingGateView = exports.getInvoicingConfigView = exports.updateInvoicingConfig = exports.resetInvoicingConfigActionStates = exports.fetchInvoicingConfig = exports.enableInvoicing = exports.acceptInvoicingTerms = exports.toInvoicingQboCustomerMatchingMode = exports.toInvoicingNamedOptionsByKey = exports.getInvoicingQboAccountMappingId = exports.INVOICING_QBO_CUSTOMER_MATCHING_MODES = exports.getInvoicingQboView = exports.invoicingAccountsForQboAccountTypes = exports.startInvoicingQboBackfill = exports.retryInvoicingQboSyncTask = void 0;
90
+ exports.CUSTOMER_REVENUE_KEYS = exports.isCustomersTabVisible = exports.getCustomerSummaryTrendFilter = void 0;
91
91
  const allowedValue_1 = require("./commonStateTypes/allowedValue");
92
92
  Object.defineProperty(exports, "isAllowedValueWithCode", { enumerable: true, get: function () { return allowedValue_1.isAllowedValueWithCode; } });
93
93
  Object.defineProperty(exports, "isAllowedValueWithID", { enumerable: true, get: function () { return allowedValue_1.isAllowedValueWithID; } });
@@ -3297,6 +3297,8 @@ Object.defineProperty(exports, "getExpenseAutomationActualMatchingView", { enume
3297
3297
  Object.defineProperty(exports, "isAutoReversedAccrual", { enumerable: true, get: function () { return actualMatchingViewSelector_1.isAutoReversedAccrual; } });
3298
3298
  Object.defineProperty(exports, "isManuallyReversedAccrual", { enumerable: true, get: function () { return actualMatchingViewSelector_1.isManuallyReversedAccrual; } });
3299
3299
  Object.defineProperty(exports, "isPendingReviewAccrual", { enumerable: true, get: function () { return actualMatchingViewSelector_1.isPendingReviewAccrual; } });
3300
+ var actualMatchingTypes_1 = require("./entity/actualMatching/actualMatchingTypes");
3301
+ Object.defineProperty(exports, "actualMatchingRowKey", { enumerable: true, get: function () { return actualMatchingTypes_1.actualMatchingRowKey; } });
3300
3302
  var customerSummaryViewReducer_1 = require("./view/customerSummaryView/customerSummaryViewReducer");
3301
3303
  Object.defineProperty(exports, "fetchCustomerSummaryDetail", { enumerable: true, get: function () { return customerSummaryViewReducer_1.fetchCustomerSummaryDetail; } });
3302
3304
  Object.defineProperty(exports, "fetchCustomerSummaryList", { enumerable: true, get: function () { return customerSummaryViewReducer_1.fetchCustomerSummaryList; } });
@@ -4,6 +4,7 @@ exports.fetchActualMatchingEpic = void 0;
4
4
  const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
6
  const actualMatchingReducer_1 = require("../../../../../entity/actualMatching/actualMatchingReducer");
7
+ const actualMatchingTypes_1 = require("../../../../../entity/actualMatching/actualMatchingTypes");
7
8
  const responsePayload_1 = require("../../../../../responsePayload");
8
9
  const rootActions_1 = require("../../../../../rootActions");
9
10
  const actualMatchingPayload_1 = require("../../../payload/actualMatchingPayload");
@@ -29,7 +30,7 @@ const fetchActualMatchingEpic = (actions$, state$, zeniAPI) => actions$.pipe((0,
29
30
  updateActions.push((0, actualMatchingReducer_1.updateActualMatchingMatches)(matches, (0, actualMatchingViewSelector_1.getTenantDisplayCurrency)(state)));
30
31
  }
31
32
  updateActions.push((0, actualMatchingViewReducer_1.fetchActualMatchingSuccess)({
32
- matchIds: matches.map((match) => match.match_id),
33
+ matchIds: matches.map((match) => (0, actualMatchingTypes_1.actualMatchingRowKey)(match.match_id, match.match_batch_id)),
33
34
  selectedPeriod: requestPeriod,
34
35
  refreshViewInBackground,
35
36
  }));
@@ -9,15 +9,19 @@ const rootActions_1 = require("../../../../../rootActions");
9
9
  const actualMatchingViewReducer_1 = require("../../../reducers/actualMatchingViewReducer");
10
10
  const actualMatchingViewSelector_1 = require("../../../selectors/actualMatchingViewSelector");
11
11
  const fetchActualMatchingMatchEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(actualMatchingViewReducer_1.fetchActualMatchingMatch.match), (0, operators_1.mergeMap)((action) => {
12
- const { matchId, refreshViewInBackground } = action.payload;
12
+ const { matchId, matchBatchId, refreshViewInBackground } = action.payload;
13
+ const batchQuery = matchBatchId != null && matchBatchId !== ''
14
+ ? `?batch_id=${encodeURIComponent(matchBatchId)}`
15
+ : '';
13
16
  return zeniAPI
14
- .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals/actual-matching/${encodeURIComponent(matchId)}`)
17
+ .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals/actual-matching/${encodeURIComponent(matchId)}${batchQuery}`)
15
18
  .pipe((0, operators_1.mergeMap)((response) => {
16
19
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
17
20
  return (0, rxjs_1.from)([
18
21
  (0, actualMatchingReducer_1.updateActualMatchingMatches)([response.data], (0, actualMatchingViewSelector_1.getTenantDisplayCurrency)(state$.value)),
19
22
  (0, actualMatchingViewReducer_1.fetchActualMatchingMatchSuccess)({
20
23
  matchId,
24
+ matchBatchId,
21
25
  refreshViewInBackground,
22
26
  }),
23
27
  ]);
@@ -25,6 +29,7 @@ const fetchActualMatchingMatchEpic = (actions$, state$, zeniAPI) => actions$.pip
25
29
  return (0, rxjs_1.from)([
26
30
  (0, actualMatchingViewReducer_1.fetchActualMatchingMatchFailure)({
27
31
  matchId,
32
+ matchBatchId,
28
33
  refreshViewInBackground,
29
34
  status: response.status,
30
35
  }),
@@ -32,6 +37,7 @@ const fetchActualMatchingMatchEpic = (actions$, state$, zeniAPI) => actions$.pip
32
37
  }), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
33
38
  (0, actualMatchingViewReducer_1.fetchActualMatchingMatchFailure)({
34
39
  matchId,
40
+ matchBatchId,
35
41
  refreshViewInBackground,
36
42
  status: (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', `Fetch actual matching match REST API call errored out ${JSON.stringify(error)}`),
37
43
  }),
@@ -59,8 +59,12 @@ function matchAndReverseHttpFailSnackbar(vendorName) {
59
59
  });
60
60
  }
61
61
  function matchVendorName(state, matchId) {
62
- return ((0, actualMatchingSelector_1.getActualMatchingMatchById)(state.actualMatchingState, matchId)
63
- ?.vendorName ?? '');
62
+ const stored = (0, actualMatchingSelector_1.getActualMatchingMatchById)(state.actualMatchingState, matchId);
63
+ if (stored?.vendorName != null && stored.vendorName !== '') {
64
+ return stored.vendorName;
65
+ }
66
+ const sameBill = Object.values(state.actualMatchingState.byMatchId).find((match) => match.matchId === matchId);
67
+ return sameBill?.vendorName ?? '';
64
68
  }
65
69
  const matchAndReverseAccrualsEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(actualMatchingViewReducer_1.matchAndReverseAccruals.match),
66
70
  // Per-match exhaust: a second click on the same match drops while HTTP is in
@@ -99,7 +103,7 @@ const matchAndReverseAccrualsEpic = (actions$, state$, zeniAPI) => actions$.pipe
99
103
  // List + detail: list can omit leftovers; detail GET always
100
104
  // writes intended occupancy so leftover retry can join C
101
105
  // onto the occupied bill instead of a stale cached row.
102
- successActions.push(...(0, refreshActualMatchingList_1.refreshActualMatchingList)(state$.value), (0, actualMatchingViewReducer_1.fetchActualMatchingMatch)(matchId, true));
106
+ successActions.push(...(0, refreshActualMatchingList_1.refreshActualMatchingList)(state$.value), (0, actualMatchingViewReducer_1.fetchActualMatchingMatch)(matchId, true, response.data.match_batch_id));
103
107
  }
104
108
  const snackbar = matchAndReverseSnackbar(results, vendorName);
105
109
  if (snackbar != null) {
@@ -4,6 +4,7 @@ exports.undoReversalAccrualsEpic = void 0;
4
4
  const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
6
  const actualMatchingSelector_1 = require("../../../../../entity/actualMatching/actualMatchingSelector");
7
+ const actualMatchingTypes_1 = require("../../../../../entity/actualMatching/actualMatchingTypes");
7
8
  const snackbarReducer_1 = require("../../../../../entity/snackbar/snackbarReducer");
8
9
  const responsePayload_1 = require("../../../../../responsePayload");
9
10
  const rootActions_1 = require("../../../../../rootActions");
@@ -40,41 +41,45 @@ function undoReversalSnackbar(results, vendorName) {
40
41
  variables,
41
42
  });
42
43
  }
43
- function matchVendorName(state, matchId) {
44
- return ((0, actualMatchingSelector_1.getActualMatchingMatchById)(state.actualMatchingState, matchId)?.vendorName ??
44
+ function matchVendorName(state, matchId, matchBatchId) {
45
+ const rowKey = (0, actualMatchingTypes_1.actualMatchingRowKey)(matchId, matchBatchId);
46
+ return ((0, actualMatchingSelector_1.getActualMatchingMatchById)(state.actualMatchingState, rowKey)?.vendorName ??
47
+ (0, actualMatchingSelector_1.getActualMatchingMatchById)(state.actualMatchingState, matchId)?.vendorName ??
45
48
  '');
46
49
  }
47
50
  const undoReversalAccrualsEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(actualMatchingViewReducer_1.undoReversalAccruals.match),
48
51
  // Per-match exhaust: a second click on the same match drops while HTTP is in
49
52
  // flight. A different match must still run — a global exhaustMap left the
50
53
  // other match's reducer In-Progress with no request.
51
- (0, operators_1.groupBy)((action) => action.payload.matchId), (0, operators_1.mergeMap)((perMatch$) => perMatch$.pipe((0, operators_1.exhaustMap)((action) => {
52
- const { accrualIds, matchId } = action.payload;
54
+ (0, operators_1.groupBy)((action) => (0, actualMatchingTypes_1.actualMatchingRowKey)(action.payload.matchId, action.payload.matchBatchId)), (0, operators_1.mergeMap)((perMatch$) => perMatch$.pipe((0, operators_1.exhaustMap)((action) => {
55
+ const { accrualIds, matchId, matchBatchId } = action.payload;
53
56
  const body = {
54
57
  accrual_ids: accrualIds,
55
58
  };
56
- const vendorName = matchVendorName(state$.value, matchId);
59
+ const vendorName = matchVendorName(state$.value, matchId, matchBatchId);
57
60
  return zeniAPI
58
61
  .postAndGetJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/accruals/undo-reversal`, body)
59
62
  .pipe((0, operators_1.mergeMap)((response) => {
60
63
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
61
64
  const results = response.data.results.map(actualMatchingPayload_1.toUndoReversalResult);
62
65
  const successActions = [
63
- (0, actualMatchingViewReducer_1.undoReversalAccrualsSuccess)(matchId, results),
66
+ (0, actualMatchingViewReducer_1.undoReversalAccrualsSuccess)(matchId, results, matchBatchId),
64
67
  ];
65
68
  const anyUndone = results.some((result) => result.status === 'undone');
66
69
  if (anyUndone) {
67
- successActions.push(...(0, refreshActualMatchingList_1.refreshActualMatchingList)(state$.value), (0, actualMatchingViewReducer_1.fetchActualMatchingMatch)(matchId, true));
70
+ successActions.push(...(0, refreshActualMatchingList_1.refreshActualMatchingList)(state$.value), (0, actualMatchingViewReducer_1.fetchActualMatchingMatch)(matchId, true, matchBatchId));
68
71
  }
69
72
  successActions.push(undoReversalSnackbar(results, vendorName));
70
73
  return (0, rxjs_1.from)(successActions);
71
74
  }
72
75
  return (0, rxjs_1.of)((0, actualMatchingViewReducer_1.undoReversalAccrualsFailure)({
73
76
  matchId,
77
+ matchBatchId,
74
78
  status: response.status,
75
79
  }), undoReversalSnackbar([], vendorName));
76
80
  }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, actualMatchingViewReducer_1.undoReversalAccrualsFailure)({
77
81
  matchId,
82
+ matchBatchId,
78
83
  status: (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Undo reversal accruals REST API call errored out' +
79
84
  JSON.stringify(error)),
80
85
  }), undoReversalSnackbar([], vendorName))), (0, operators_1.takeUntil)(actions$.pipe((0, operators_1.filter)(rootActions_1.clearAll.match))));
@@ -14,16 +14,19 @@ export declare const ackCloseMatchAfterIgnore: import("@reduxjs/toolkit").Action
14
14
  refreshViewInBackground: boolean;
15
15
  selectedPeriod: MonthYearPeriod;
16
16
  status: ZeniAPIStatus;
17
- }, "expenseAutomationActualMatchingView/fetchActualMatchingFailure">, fetchActualMatchingMatch: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[matchId: string, refreshViewInBackground?: any], {
17
+ }, "expenseAutomationActualMatchingView/fetchActualMatchingFailure">, fetchActualMatchingMatch: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[matchId: string, refreshViewInBackground?: any, matchBatchId?: string | undefined], {
18
18
  matchId: string;
19
+ matchBatchId: string | undefined;
19
20
  refreshViewInBackground: any;
20
21
  }, "expenseAutomationActualMatchingView/fetchActualMatchingMatch", never, never>, fetchActualMatchingMatchFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
21
22
  matchId: ActualMatchingMatchId;
22
23
  refreshViewInBackground: boolean;
23
24
  status: ZeniAPIStatus;
25
+ matchBatchId?: string;
24
26
  }, "expenseAutomationActualMatchingView/fetchActualMatchingMatchFailure">, fetchActualMatchingMatchSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
25
27
  matchId: ActualMatchingMatchId;
26
28
  refreshViewInBackground: boolean;
29
+ matchBatchId?: string;
27
30
  }, "expenseAutomationActualMatchingView/fetchActualMatchingMatchSuccess">, fetchActualMatchingPage: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[period: TimePeriod, refreshViewInBackground?: any], {
28
31
  period: TimePeriod;
29
32
  refreshViewInBackground: any;
@@ -76,15 +79,18 @@ export declare const ackCloseMatchAfterIgnore: import("@reduxjs/toolkit").Action
76
79
  append: boolean;
77
80
  nextPageToken: string | null;
78
81
  results: ActualMatchingTransactionSearchResult[];
79
- }, "expenseAutomationActualMatchingView/searchMatchTransactionsSuccess">, undoReversalAccruals: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[matchId: string, accrualIds: string[]], {
82
+ }, "expenseAutomationActualMatchingView/searchMatchTransactionsSuccess">, undoReversalAccruals: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[matchId: string, accrualIds: string[], matchBatchId?: string | undefined], {
80
83
  matchId: string;
81
84
  accrualIds: string[];
85
+ matchBatchId: string | undefined;
82
86
  }, "expenseAutomationActualMatchingView/undoReversalAccruals", never, never>, undoReversalAccrualsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
83
87
  matchId: ActualMatchingMatchId;
84
88
  status: ZeniAPIStatus;
85
- }, "expenseAutomationActualMatchingView/undoReversalAccrualsFailure">, undoReversalAccrualsSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[matchId: string, results: UndoReversalResult[]], {
89
+ matchBatchId?: string;
90
+ }, "expenseAutomationActualMatchingView/undoReversalAccrualsFailure">, undoReversalAccrualsSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[matchId: string, results: UndoReversalResult[], matchBatchId?: string | undefined], {
86
91
  matchId: string;
87
92
  results: UndoReversalResult[];
93
+ matchBatchId: string | undefined;
88
94
  }, "expenseAutomationActualMatchingView/undoReversalAccrualsSuccess", never, never>, updateActualMatchingUIState: import("@reduxjs/toolkit").ActionCreatorWithPayload<Partial<ActualMatchingViewUIState>, "expenseAutomationActualMatchingView/updateActualMatchingUIState">;
89
95
  declare const _default: import("redux").Reducer<ActualMatchingViewState>;
90
96
  export default _default;
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.updateActualMatchingUIState = exports.undoReversalAccrualsSuccess = exports.undoReversalAccrualsFailure = exports.undoReversalAccruals = exports.searchMatchTransactionsSuccess = exports.searchMatchTransactionsFailure = exports.searchMatchTransactions = exports.searchMatchAccrualsSuccess = exports.searchMatchAccrualsFailure = exports.searchMatchAccruals = exports.openMatchNewModal = exports.matchAndReverseAccrualsSuccess = exports.matchAndReverseAccrualsFailure = exports.matchAndReverseAccruals = exports.ignoreActualMatchingSuggestionSuccess = exports.ignoreActualMatchingSuggestionFailure = exports.ignoreActualMatchingSuggestion = exports.fetchActualMatchingSuccess = exports.fetchActualMatchingPage = exports.fetchActualMatchingMatchSuccess = exports.fetchActualMatchingMatchFailure = exports.fetchActualMatchingMatch = exports.fetchActualMatchingFailure = exports.fetchActualMatching = exports.closeMatchNewModal = exports.clearMatchNewModal = exports.clearActualMatchingView = exports.ackCloseMatchAfterUndo = exports.ackCloseMatchAfterIgnore = exports.initialState = exports.initialMatchModalState = exports.initialAccrualSearchState = exports.initialTransactionSearchState = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
7
+ const actualMatchingTypes_1 = require("../../../entity/actualMatching/actualMatchingTypes");
7
8
  const jeScheduleHelper_1 = require("../../../entity/jeSchedules/jeScheduleHelper");
8
9
  const responsePayload_1 = require("../../../responsePayload");
9
10
  const rootActions_1 = require("../../../rootActions");
@@ -187,19 +188,20 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
187
188
  }
188
189
  },
189
190
  fetchActualMatchingMatch: {
190
- prepare(matchId, refreshViewInBackground = false) {
191
- return { payload: { matchId, refreshViewInBackground } };
191
+ prepare(matchId, refreshViewInBackground = false, matchBatchId) {
192
+ return { payload: { matchId, matchBatchId, refreshViewInBackground } };
192
193
  },
193
194
  reducer(draft, action) {
194
- const { matchId, refreshViewInBackground } = action.payload;
195
+ const { matchId, matchBatchId, refreshViewInBackground } = action.payload;
196
+ const rowKey = (0, actualMatchingTypes_1.actualMatchingRowKey)(matchId, matchBatchId);
195
197
  if (refreshViewInBackground) {
196
- draft.detailRefreshStatusByMatchId[matchId] = {
198
+ draft.detailRefreshStatusByMatchId[rowKey] = {
197
199
  fetchState: 'In-Progress',
198
200
  error: undefined,
199
201
  };
200
202
  }
201
203
  else {
202
- draft.detailFetchStateByMatchId[matchId] = {
204
+ draft.detailFetchStateByMatchId[rowKey] = {
203
205
  fetchState: 'In-Progress',
204
206
  error: undefined,
205
207
  };
@@ -207,30 +209,32 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
207
209
  },
208
210
  },
209
211
  fetchActualMatchingMatchSuccess(draft, action) {
210
- const { matchId, refreshViewInBackground } = action.payload;
212
+ const { matchId, matchBatchId, refreshViewInBackground } = action.payload;
213
+ const rowKey = (0, actualMatchingTypes_1.actualMatchingRowKey)(matchId, matchBatchId);
211
214
  if (refreshViewInBackground) {
212
- draft.detailRefreshStatusByMatchId[matchId] = {
215
+ draft.detailRefreshStatusByMatchId[rowKey] = {
213
216
  fetchState: 'Completed',
214
217
  error: undefined,
215
218
  };
216
219
  }
217
220
  else {
218
- draft.detailFetchStateByMatchId[matchId] = {
221
+ draft.detailFetchStateByMatchId[rowKey] = {
219
222
  fetchState: 'Completed',
220
223
  error: undefined,
221
224
  };
222
225
  }
223
226
  },
224
227
  fetchActualMatchingMatchFailure(draft, action) {
225
- const { matchId, refreshViewInBackground, status } = action.payload;
228
+ const { matchId, matchBatchId, refreshViewInBackground, status } = action.payload;
229
+ const rowKey = (0, actualMatchingTypes_1.actualMatchingRowKey)(matchId, matchBatchId);
226
230
  if (refreshViewInBackground) {
227
- draft.detailRefreshStatusByMatchId[matchId] = {
231
+ draft.detailRefreshStatusByMatchId[rowKey] = {
228
232
  fetchState: 'Error',
229
233
  error: status,
230
234
  };
231
235
  }
232
236
  else {
233
- draft.detailFetchStateByMatchId[matchId] = {
237
+ draft.detailFetchStateByMatchId[rowKey] = {
234
238
  fetchState: 'Error',
235
239
  error: status,
236
240
  };
@@ -421,40 +425,42 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
421
425
  },
422
426
  undoReversalAccruals: {
423
427
  reducer(draft, action) {
424
- draft.undoReversalStatusByMatchId[action.payload.matchId] = {
428
+ const rowKey = (0, actualMatchingTypes_1.actualMatchingRowKey)(action.payload.matchId, action.payload.matchBatchId);
429
+ draft.undoReversalStatusByMatchId[rowKey] = {
425
430
  fetchState: 'In-Progress',
426
431
  error: undefined,
427
432
  };
428
433
  },
429
- prepare(matchId, accrualIds) {
430
- return { payload: { matchId, accrualIds } };
434
+ prepare(matchId, accrualIds, matchBatchId) {
435
+ return { payload: { matchId, accrualIds, matchBatchId } };
431
436
  },
432
437
  },
433
438
  undoReversalAccrualsSuccess: {
434
439
  reducer(draft, action) {
435
- const { matchId, results } = action.payload;
436
- draft.undoReversalStatusByMatchId[matchId] = {
440
+ const { matchId, matchBatchId, results } = action.payload;
441
+ const rowKey = (0, actualMatchingTypes_1.actualMatchingRowKey)(matchId, matchBatchId);
442
+ draft.undoReversalStatusByMatchId[rowKey] = {
437
443
  fetchState: 'Completed',
438
444
  error: undefined,
439
445
  };
440
446
  const allUndone = results.length > 0 &&
441
447
  results.every((result) => result.status === 'undone');
442
448
  if (allUndone) {
443
- enqueueCloseMatchId(draft.closeMatchAfterUndoMatchIds, matchId);
449
+ enqueueCloseMatchId(draft.closeMatchAfterUndoMatchIds, rowKey);
444
450
  }
445
451
  else {
446
- draft.closeMatchAfterUndoMatchIds = dropCloseMatchId(draft.closeMatchAfterUndoMatchIds, matchId);
452
+ draft.closeMatchAfterUndoMatchIds = dropCloseMatchId(draft.closeMatchAfterUndoMatchIds, rowKey);
447
453
  }
448
454
  pruneLastMatchResultsForUndone(draft, matchId, results);
449
455
  if (allUndone) {
450
- delete draft.lastUndoResultsByMatchId[matchId];
456
+ delete draft.lastUndoResultsByMatchId[rowKey];
451
457
  }
452
458
  else {
453
- draft.lastUndoResultsByMatchId[matchId] = results;
459
+ draft.lastUndoResultsByMatchId[rowKey] = results;
454
460
  }
455
461
  },
456
- prepare(matchId, results) {
457
- return { payload: { matchId, results } };
462
+ prepare(matchId, results, matchBatchId) {
463
+ return { payload: { matchId, results, matchBatchId } };
458
464
  },
459
465
  },
460
466
  ackCloseMatchAfterUndo(draft) {
@@ -498,7 +504,8 @@ const expenseAutomationActualMatchingView = (0, toolkit_1.createSlice)({
498
504
  draft.closeMatchAfterIgnoreMatchIds.shift();
499
505
  },
500
506
  undoReversalAccrualsFailure(draft, action) {
501
- draft.undoReversalStatusByMatchId[action.payload.matchId] = {
507
+ const rowKey = (0, actualMatchingTypes_1.actualMatchingRowKey)(action.payload.matchId, action.payload.matchBatchId);
508
+ draft.undoReversalStatusByMatchId[rowKey] = {
502
509
  fetchState: 'Error',
503
510
  error: action.payload.status,
504
511
  };
@@ -23,6 +23,7 @@ export interface ActualMatchingRow extends JEOneTimeAccrual {
23
23
  groupedMembers?: ActualMatchingGroupedAccrual[];
24
24
  intendedAccrualIds?: ID[];
25
25
  leftovers?: ActualMatchingLeftoverAccrual[];
26
+ matchBatchId?: string;
26
27
  matchShape?: string;
27
28
  matchTier?: string;
28
29
  reversalDate?: ZeniDate;
@@ -153,6 +153,7 @@ function toActualMatchingRow(match) {
153
153
  return {
154
154
  ...first,
155
155
  matchId: match.matchId,
156
+ matchBatchId: match.matchBatchId,
156
157
  kind: match.kind,
157
158
  accruedAmount: match.accruedAmount,
158
159
  actualAmount: match.actualAmount,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "5.3.13",
3
+ "version": "5.3.14-beta0MM",
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",