@zeniai/client-epic-state 5.2.69-betaAK0 → 5.2.70

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 (157) hide show
  1. package/lib/entity/actualMatching/actualMatchingReducer.d.ts +1 -3
  2. package/lib/entity/actualMatching/actualMatchingReducer.js +2 -11
  3. package/lib/entity/aiCfo/aiCfoState.d.ts +2 -2
  4. package/lib/entity/billPay/billTransaction/billTransactionState.d.ts +2 -2
  5. package/lib/entity/chargeCardTransaction/chargeCardTransaction.d.ts +1 -1
  6. package/lib/entity/depositAccountTransaction/depositAccountTransaction.d.ts +1 -1
  7. package/lib/entity/invoicing/plan/planPayload.d.ts +40 -0
  8. package/lib/entity/invoicing/plan/planPayload.js +51 -0
  9. package/lib/entity/invoicing/plan/planReducer.d.ts +14 -0
  10. package/lib/entity/invoicing/{invoicingCatalog/invoicingCatalogReducer.js → plan/planReducer.js} +21 -20
  11. package/lib/entity/invoicing/{invoicingCatalog/invoicingCatalogSelector.d.ts → plan/planSelector.d.ts} +6 -5
  12. package/lib/entity/invoicing/{invoicingCatalog/invoicingCatalogSelector.js → plan/planSelector.js} +12 -12
  13. package/lib/entity/invoicing/plan/planState.d.ts +43 -0
  14. package/lib/entity/invoicing/{invoicingCatalog/invoicingCatalogPayload.d.ts → product/productPayload.d.ts} +6 -44
  15. package/lib/entity/invoicing/{invoicingCatalog/invoicingCatalogPayload.js → product/productPayload.js} +6 -50
  16. package/lib/entity/invoicing/product/productReducer.d.ts +9 -0
  17. package/lib/entity/invoicing/product/productReducer.js +50 -0
  18. package/lib/entity/invoicing/product/productSelector.d.ts +4 -0
  19. package/lib/entity/invoicing/product/productSelector.js +17 -0
  20. package/lib/entity/invoicing/{invoicingCatalog/invoicingCatalogState.d.ts → product/productState.d.ts} +6 -42
  21. package/lib/entity/invoicing/product/productState.js +2 -0
  22. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +0 -2
  23. package/lib/entity/jeSchedules/jeSchedulesPayload.js +0 -2
  24. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +0 -2
  25. package/lib/entity/jeSchedules/jeSchedulesTypes.d.ts +4 -4
  26. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  27. package/lib/entity/snackbar/snackbarTypes.js +0 -3
  28. package/lib/epic.d.ts +2 -4
  29. package/lib/epic.js +1 -5
  30. package/lib/esm/entity/actualMatching/actualMatchingReducer.js +1 -9
  31. package/lib/esm/entity/invoicing/plan/planPayload.js +47 -0
  32. package/lib/esm/entity/invoicing/{invoicingCatalog/invoicingCatalogReducer.js → plan/planReducer.js} +20 -19
  33. package/lib/esm/entity/invoicing/{invoicingCatalog/invoicingCatalogSelector.js → plan/planSelector.js} +8 -8
  34. package/lib/esm/entity/invoicing/{invoicingCatalog/invoicingCatalogPayload.js → product/productPayload.js} +3 -46
  35. package/lib/esm/entity/invoicing/product/productReducer.js +43 -0
  36. package/lib/esm/entity/invoicing/product/productSelector.js +10 -0
  37. package/lib/esm/entity/invoicing/product/productState.js +1 -0
  38. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +0 -2
  39. package/lib/esm/entity/snackbar/snackbarTypes.js +0 -3
  40. package/lib/esm/epic.js +1 -5
  41. package/lib/esm/index.js +11 -9
  42. package/lib/esm/reducer.js +7 -4
  43. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.js +2 -4
  44. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.js +13 -26
  45. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchTransactionsEpic.js +23 -2
  46. package/lib/esm/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +38 -89
  47. package/lib/esm/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +62 -68
  48. package/lib/esm/view/expenseAutomationView/types/actualMatchingViewState.js +0 -15
  49. package/lib/esm/view/invoicing/createInvoice/createInvoiceEpic.js +1 -9
  50. package/lib/esm/view/invoicing/createInvoice/createInvoiceSelector.js +1 -1
  51. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +3 -5
  52. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/fetchInvoicingCatalogItemDetailEpic.js +2 -2
  53. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/runInvoicingCatalogPlanActionEpic.js +2 -2
  54. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/runInvoicingCatalogProductActionEpic.js +4 -4
  55. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +7 -3
  56. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/seedInvoicingCatalogItemFormDraftEpic.js +2 -2
  57. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer.js +1 -5
  58. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +1 -5
  59. package/lib/esm/view/invoicing/invoiceList/invoiceListReducer.js +1 -8
  60. package/lib/esm/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogPlanListEpic.js +2 -2
  61. package/lib/esm/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogProductListEpic.js +2 -2
  62. package/lib/esm/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewSelector.js +20 -56
  63. package/lib/esm/view/invoicing/settingsView/settingsViewSelector.js +9 -18
  64. package/lib/esm/view/invoicing/settingsView/submitInvoicingBrandingFormEpic.js +2 -11
  65. package/lib/esm/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewEpic.js +11 -31
  66. package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewReducer.js +1 -2
  67. package/lib/esm/view/spendManagement/billPay/editBillView/editBillViewSelector.js +30 -4
  68. package/lib/esm/view/spendManagement/commonSetup/setupViewReducer.js +1 -21
  69. package/lib/esm/view/spendManagement/commonSetup/setupViewSelector.js +1 -2
  70. package/lib/index.d.ts +17 -14
  71. package/lib/index.js +60 -65
  72. package/lib/reducer.d.ts +2 -1
  73. package/lib/reducer.js +7 -4
  74. package/lib/rootStateTypes.d.ts +5 -3
  75. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.d.ts +2 -2
  76. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.js +1 -3
  77. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.js +11 -24
  78. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchTransactionsEpic.js +22 -1
  79. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  80. package/lib/view/expenseAutomationView/payload/actualMatchingPayload.d.ts +1 -12
  81. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.d.ts +8 -19
  82. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +39 -90
  83. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +2 -2
  84. package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.d.ts +10 -24
  85. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.d.ts +4 -7
  86. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +62 -71
  87. package/lib/view/expenseAutomationView/types/actualMatchingViewState.d.ts +4 -19
  88. package/lib/view/expenseAutomationView/types/actualMatchingViewState.js +1 -18
  89. package/lib/view/invoicing/createInvoice/createInvoiceEpic.d.ts +2 -3
  90. package/lib/view/invoicing/createInvoice/createInvoiceEpic.js +0 -8
  91. package/lib/view/invoicing/createInvoice/createInvoiceSelector.d.ts +2 -2
  92. package/lib/view/invoicing/createInvoice/createInvoiceSelector.js +2 -2
  93. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.d.ts +9 -8
  94. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.d.ts +2 -2
  95. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +3 -5
  96. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/fetchInvoicingCatalogItemDetailEpic.d.ts +2 -2
  97. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/fetchInvoicingCatalogItemDetailEpic.js +2 -2
  98. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/invoicingCatalogItemFormHelper.d.ts +4 -3
  99. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/runInvoicingCatalogPlanActionEpic.d.ts +2 -2
  100. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/runInvoicingCatalogPlanActionEpic.js +2 -2
  101. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/runInvoicingCatalogProductActionEpic.d.ts +3 -2
  102. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/runInvoicingCatalogProductActionEpic.js +4 -4
  103. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.d.ts +3 -2
  104. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +7 -3
  105. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/seedInvoicingCatalogItemFormDraftEpic.js +2 -2
  106. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer.d.ts +1 -3
  107. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer.js +2 -6
  108. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewSelector.d.ts +2 -2
  109. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.d.ts +1 -3
  110. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +1 -5
  111. package/lib/view/invoicing/invoiceList/invoiceListReducer.d.ts +1 -3
  112. package/lib/view/invoicing/invoiceList/invoiceListReducer.js +2 -9
  113. package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogListPageEpic.d.ts +2 -2
  114. package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogPlanListEpic.d.ts +2 -2
  115. package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogPlanListEpic.js +2 -2
  116. package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogProductListEpic.d.ts +2 -2
  117. package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogProductListEpic.js +2 -2
  118. package/lib/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewPayload.d.ts +3 -3
  119. package/lib/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewSelector.d.ts +5 -29
  120. package/lib/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewSelector.js +21 -58
  121. package/lib/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewState.d.ts +1 -1
  122. package/lib/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewReducer.d.ts +1 -1
  123. package/lib/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewState.d.ts +1 -1
  124. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewReducer.d.ts +1 -1
  125. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewState.d.ts +1 -1
  126. package/lib/view/invoicing/settingsView/settingsViewSelector.d.ts +3 -12
  127. package/lib/view/invoicing/settingsView/settingsViewSelector.js +8 -17
  128. package/lib/view/invoicing/settingsView/submitInvoicingBrandingFormEpic.js +2 -11
  129. package/lib/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewEpic.js +11 -31
  130. package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.d.ts +2 -3
  131. package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.js +1 -2
  132. package/lib/view/onboardingView/customerView/onboardingCustomerViewState.d.ts +0 -4
  133. package/lib/view/scheduleView/scheduleListView/scheduleListTypes.d.ts +1 -1
  134. package/lib/view/spendManagement/billPay/billList/billListReducer.d.ts +5 -5
  135. package/lib/view/spendManagement/billPay/billList/billListState.d.ts +1 -1
  136. package/lib/view/spendManagement/billPay/editBillView/editBillViewReducer.d.ts +2 -2
  137. package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.d.ts +1 -1
  138. package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.js +30 -4
  139. package/lib/view/spendManagement/commonSetup/setupViewReducer.d.ts +1 -1
  140. package/lib/view/spendManagement/commonSetup/setupViewReducer.js +2 -22
  141. package/lib/view/spendManagement/commonSetup/setupViewSelector.d.ts +0 -1
  142. package/lib/view/spendManagement/commonSetup/setupViewSelector.js +1 -2
  143. package/lib/view/spendManagement/commonSetup/setupViewState.d.ts +0 -1
  144. package/lib/view/spendManagement/commonSetup/types/businessVerification.d.ts +1 -2
  145. package/lib/view/spendManagement/reimbursement/editRemiView/editRemiViewReducer.d.ts +2 -2
  146. package/lib/view/spendManagement/reimbursement/remiListView/remiListReducer.d.ts +5 -5
  147. package/lib/view/spendManagement/reimbursement/remiListView/remiListState.d.ts +2 -2
  148. package/package.json +1 -1
  149. package/lib/entity/invoicing/invoicingCatalog/invoicingCatalogReducer.d.ts +0 -12
  150. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.js +0 -50
  151. package/lib/esm/view/spendManagement/commonSetup/epic/setup/resetKycKybEpic.js +0 -37
  152. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.d.ts +0 -10
  153. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.js +0 -54
  154. package/lib/view/spendManagement/commonSetup/epic/setup/resetKycKybEpic.d.ts +0 -8
  155. package/lib/view/spendManagement/commonSetup/epic/setup/resetKycKybEpic.js +0 -41
  156. /package/lib/entity/invoicing/{invoicingCatalog/invoicingCatalogState.js → plan/planState.js} +0 -0
  157. /package/lib/esm/entity/invoicing/{invoicingCatalog/invoicingCatalogState.js → plan/planState.js} +0 -0
@@ -22,6 +22,9 @@ export const initialAccrualSearchState = {
22
22
  };
23
23
  export const initialMatchModalState = {
24
24
  isOpen: false,
25
+ openedFromMatchId: undefined,
26
+ didPinPrefillTransactions: false,
27
+ pinnedTransactionResults: [],
25
28
  transactionSearch: initialTransactionSearchState,
26
29
  accrualSearch: initialAccrualSearchState,
27
30
  confirmStatus: { fetchState: 'Not-Started', error: undefined },
@@ -41,28 +44,16 @@ export const initialState = {
41
44
  sortOrder: 'descending',
42
45
  searchString: '',
43
46
  scrollPosition: { scrollTop: 0, scrollLeft: undefined },
44
- statusFilter: 'all',
45
47
  },
46
48
  matchModal: initialMatchModalState,
47
49
  undoReversalStatusByMatchId: {},
48
- ignoreStatusByMatchId: {},
49
- confirmStatusByMatchId: {},
50
- closeMatchAfterUndoMatchIds: [],
51
- closeMatchAfterIgnoreMatchIds: [],
50
+ closeMatchAfterUndo: false,
52
51
  lastMatchResultsByMatchId: {},
53
52
  lastUndoResultsByMatchId: {},
54
53
  hasValidState() {
55
54
  return this.fetchState == 'Completed';
56
55
  },
57
56
  };
58
- function enqueueCloseMatchId(ids, matchId) {
59
- if (!ids.includes(matchId)) {
60
- ids.push(matchId);
61
- }
62
- }
63
- function dropCloseMatchId(ids, matchId) {
64
- return ids.filter((id) => id !== matchId);
65
- }
66
57
  function pruneLastMatchResultsForUndone(draft, matchId, results) {
67
58
  const undoneIds = new Set(results
68
59
  .filter((result) => result.status === 'undone')
@@ -105,6 +96,9 @@ function resetMatchModalSearches(draft) {
105
96
  error: undefined,
106
97
  };
107
98
  draft.matchModal.lastBatchResults = undefined;
99
+ draft.matchModal.openedFromMatchId = undefined;
100
+ draft.matchModal.didPinPrefillTransactions = false;
101
+ draft.matchModal.pinnedTransactionResults = [];
108
102
  }
109
103
  const expenseAutomationActualMatchingView = createSlice({
110
104
  name: 'expenseAutomationActualMatchingView',
@@ -245,13 +239,21 @@ const expenseAutomationActualMatchingView = createSlice({
245
239
  if (action.payload.scrollPosition != null) {
246
240
  draft.uiState.scrollPosition = action.payload.scrollPosition;
247
241
  }
248
- if (action.payload.statusFilter != null) {
249
- draft.uiState.statusFilter = action.payload.statusFilter;
250
- }
251
242
  },
252
- openMatchNewModal(draft) {
253
- resetMatchModalSearches(draft);
254
- draft.matchModal.isOpen = true;
243
+ openMatchNewModal: {
244
+ prepare(matchId) {
245
+ return { payload: { matchId } };
246
+ },
247
+ reducer(draft, action) {
248
+ resetMatchModalSearches(draft);
249
+ draft.matchModal.isOpen = true;
250
+ const matchId = action.payload.matchId;
251
+ draft.matchModal.openedFromMatchId =
252
+ matchId != null && matchId !== '' ? matchId : undefined;
253
+ if (draft.matchModal.openedFromMatchId != null) {
254
+ draft.matchModal.accrualSearch.fetchState = 'Completed';
255
+ }
256
+ },
255
257
  },
256
258
  // Dismiss (Cancel / overlay). Store reset matches `clearMatchNewModal`;
257
259
  // the actions stay distinct so confirm-success vs user-dismiss stay observable.
@@ -306,6 +308,11 @@ const expenseAutomationActualMatchingView = createSlice({
306
308
  }
307
309
  else {
308
310
  draft.matchModal.transactionSearch.results = results;
311
+ if (draft.matchModal.openedFromMatchId != null &&
312
+ !draft.matchModal.didPinPrefillTransactions) {
313
+ draft.matchModal.didPinPrefillTransactions = true;
314
+ draft.matchModal.pinnedTransactionResults = results;
315
+ }
309
316
  }
310
317
  draft.matchModal.transactionSearch.nextPageToken = nextPageToken;
311
318
  draft.matchModal.transactionSearch.isLoadingMore = false;
@@ -358,27 +365,21 @@ const expenseAutomationActualMatchingView = createSlice({
358
365
  draft.matchModal.accrualSearch.error = action.payload.error;
359
366
  },
360
367
  matchAndReverseAccruals: {
361
- reducer(draft, action) {
362
- const inProgress = {
368
+ reducer(draft) {
369
+ draft.matchModal.confirmStatus = {
363
370
  fetchState: 'In-Progress',
364
371
  error: undefined,
365
372
  };
366
- if (action.payload.forMatchModal === true) {
367
- draft.matchModal.confirmStatus = inProgress;
368
- }
369
- const matchId = `${action.payload.transactionType.toLowerCase()}:${action.payload.transactionIntegrationId}`;
370
- draft.confirmStatusByMatchId[matchId] = inProgress;
371
373
  },
372
- prepare(transactionId, transactionIntegrationId, transactionType, lineIds, transactionSyncToken, accrualIds, forMatchModal) {
374
+ prepare(transactionId, transactionIntegrationId, transactionType, lineIds, transactionSyncToken, accrualIds) {
373
375
  return {
374
376
  payload: {
375
- accrualIds,
376
- lineIds,
377
377
  transactionId,
378
378
  transactionIntegrationId,
379
- transactionSyncToken,
380
379
  transactionType,
381
- forMatchModal,
380
+ lineIds,
381
+ transactionSyncToken,
382
+ accrualIds,
382
383
  },
383
384
  };
384
385
  },
@@ -387,33 +388,23 @@ const expenseAutomationActualMatchingView = createSlice({
387
388
  const { results } = action.payload;
388
389
  const allComplete = results.length > 0 &&
389
390
  results.every((result) => isMatchAndReverseCompleteStatus(result.status));
390
- const confirmStatus = allComplete
391
+ draft.matchModal.confirmStatus = allComplete
391
392
  ? { fetchState: 'Completed', error: undefined }
392
393
  : {
393
394
  fetchState: 'Error',
394
395
  error: createZeniAPIStatus('Partial match-and-reverse', 'Some accruals were not reversed'),
395
396
  };
396
- if (action.payload.forMatchModal === true) {
397
- draft.matchModal.confirmStatus = confirmStatus;
398
- draft.matchModal.lastBatchResults = results;
399
- }
397
+ draft.matchModal.lastBatchResults = results;
400
398
  if (action.payload.matchId != null) {
401
- draft.confirmStatusByMatchId[action.payload.matchId] = confirmStatus;
402
399
  draft.lastMatchResultsByMatchId[action.payload.matchId] = results;
403
400
  pruneLastUndoResultsForMatched(draft, action.payload.matchId, action.payload.results);
404
401
  }
405
402
  },
406
403
  matchAndReverseAccrualsFailure(draft, action) {
407
- const failed = {
404
+ draft.matchModal.confirmStatus = {
408
405
  fetchState: 'Error',
409
406
  error: action.payload.status,
410
407
  };
411
- if (action.payload.forMatchModal === true) {
412
- draft.matchModal.confirmStatus = failed;
413
- }
414
- if (action.payload.matchId != null) {
415
- draft.confirmStatusByMatchId[action.payload.matchId] = failed;
416
- }
417
408
  },
418
409
  undoReversalAccruals: {
419
410
  reducer(draft, action) {
@@ -435,12 +426,7 @@ const expenseAutomationActualMatchingView = createSlice({
435
426
  };
436
427
  const allUndone = results.length > 0 &&
437
428
  results.every((result) => result.status === 'undone');
438
- if (allUndone) {
439
- enqueueCloseMatchId(draft.closeMatchAfterUndoMatchIds, matchId);
440
- }
441
- else {
442
- draft.closeMatchAfterUndoMatchIds = dropCloseMatchId(draft.closeMatchAfterUndoMatchIds, matchId);
443
- }
429
+ draft.closeMatchAfterUndo = allUndone;
444
430
  pruneLastMatchResultsForUndone(draft, matchId, results);
445
431
  if (allUndone) {
446
432
  delete draft.lastUndoResultsByMatchId[matchId];
@@ -454,44 +440,7 @@ const expenseAutomationActualMatchingView = createSlice({
454
440
  },
455
441
  },
456
442
  ackCloseMatchAfterUndo(draft) {
457
- draft.closeMatchAfterUndoMatchIds.shift();
458
- },
459
- ignoreActualMatchingSuggestion: {
460
- prepare(matchId, reason, note) {
461
- return { payload: { matchId, reason, note } };
462
- },
463
- reducer(draft, action) {
464
- draft.ignoreStatusByMatchId[action.payload.matchId] = {
465
- fetchState: 'In-Progress',
466
- error: undefined,
467
- };
468
- },
469
- },
470
- ignoreActualMatchingSuggestionSuccess(draft, action) {
471
- const { matchId } = action.payload;
472
- draft.ignoreStatusByMatchId[matchId] = {
473
- fetchState: 'Completed',
474
- error: undefined,
475
- };
476
- enqueueCloseMatchId(draft.closeMatchAfterIgnoreMatchIds, matchId);
477
- delete draft.lastMatchResultsByMatchId[matchId];
478
- delete draft.lastUndoResultsByMatchId[matchId];
479
- delete draft.detailFetchStateByMatchId[matchId];
480
- delete draft.detailRefreshStatusByMatchId[matchId];
481
- delete draft.undoReversalStatusByMatchId[matchId];
482
- delete draft.confirmStatusByMatchId[matchId];
483
- Object.keys(draft.matchIdsByPeriod).forEach((periodId) => {
484
- draft.matchIdsByPeriod[periodId] = draft.matchIdsByPeriod[periodId].filter((id) => id !== matchId);
485
- });
486
- },
487
- ignoreActualMatchingSuggestionFailure(draft, action) {
488
- draft.ignoreStatusByMatchId[action.payload.matchId] = {
489
- fetchState: 'Error',
490
- error: action.payload.status,
491
- };
492
- },
493
- ackCloseMatchAfterIgnore(draft) {
494
- draft.closeMatchAfterIgnoreMatchIds.shift();
443
+ draft.closeMatchAfterUndo = false;
495
444
  },
496
445
  undoReversalAccrualsFailure(draft, action) {
497
446
  draft.undoReversalStatusByMatchId[action.payload.matchId] = {
@@ -509,5 +458,5 @@ const expenseAutomationActualMatchingView = createSlice({
509
458
  });
510
459
  },
511
460
  });
512
- export const { ackCloseMatchAfterIgnore, ackCloseMatchAfterUndo, clearActualMatchingView, clearMatchNewModal, closeMatchNewModal, fetchActualMatching, fetchActualMatchingFailure, fetchActualMatchingMatch, fetchActualMatchingMatchFailure, fetchActualMatchingMatchSuccess, fetchActualMatchingPage, fetchActualMatchingSuccess, ignoreActualMatchingSuggestion, ignoreActualMatchingSuggestionFailure, ignoreActualMatchingSuggestionSuccess, matchAndReverseAccruals, matchAndReverseAccrualsFailure, matchAndReverseAccrualsSuccess, openMatchNewModal, searchMatchAccruals, searchMatchAccrualsFailure, searchMatchAccrualsSuccess, searchMatchTransactions, searchMatchTransactionsFailure, searchMatchTransactionsSuccess, undoReversalAccruals, undoReversalAccrualsFailure, undoReversalAccrualsSuccess, updateActualMatchingUIState, } = expenseAutomationActualMatchingView.actions;
461
+ export const { ackCloseMatchAfterUndo, clearActualMatchingView, clearMatchNewModal, closeMatchNewModal, fetchActualMatching, fetchActualMatchingFailure, fetchActualMatchingMatch, fetchActualMatchingMatchFailure, fetchActualMatchingMatchSuccess, fetchActualMatchingPage, fetchActualMatchingSuccess, matchAndReverseAccruals, matchAndReverseAccrualsFailure, matchAndReverseAccrualsSuccess, openMatchNewModal, searchMatchAccruals, searchMatchAccrualsFailure, searchMatchAccrualsSuccess, searchMatchTransactions, searchMatchTransactionsFailure, searchMatchTransactionsSuccess, undoReversalAccruals, undoReversalAccrualsFailure, undoReversalAccrualsSuccess, updateActualMatchingUIState, } = expenseAutomationActualMatchingView.actions;
513
462
  export default expenseAutomationActualMatchingView.reducer;
@@ -1,4 +1,3 @@
1
- import { createSelector } from '@reduxjs/toolkit';
2
1
  import orderBy from 'lodash/orderBy';
3
2
  import { toMonthYearPeriodId, } from '../../../commonStateTypes/timePeriod';
4
3
  import { getActualMatchingMatchById } from '../../../entity/actualMatching/actualMatchingSelector';
@@ -6,6 +5,7 @@ import { generateJEOneTimeAccrualKey } from '../../../entity/jeSchedules/jeSched
6
5
  import { getJEOneTimeAccrualByKey, } from '../../../entity/jeSchedules/jeSchedulesSelector';
7
6
  import { getCurrentTenant } from '../../../entity/tenant/tenantSelector';
8
7
  import { date } from '../../../zeniDayJS';
8
+ import { actualMatchingTransactionLineKey, } from '../types/actualMatchingViewState';
9
9
  export function getSelectedMonthYearForCurrentTenant(state) {
10
10
  const tenantId = getCurrentTenant(state)?.tenantId;
11
11
  if (tenantId == null) {
@@ -34,6 +34,27 @@ function toMatchModalAccrual(member) {
34
34
  jeOneTimeAccrualKey: generateJEOneTimeAccrualKey(member.accrualId),
35
35
  };
36
36
  }
37
+ function uniqueMatchModalAccruals(pinned, searched) {
38
+ const byId = new Map();
39
+ pinned.forEach((row) => byId.set(row.accrualId, row));
40
+ searched.forEach((row) => {
41
+ if (!byId.has(row.accrualId)) {
42
+ byId.set(row.accrualId, row);
43
+ }
44
+ });
45
+ return Array.from(byId.values());
46
+ }
47
+ function uniqueTransactionSearchResults(pinned, searched) {
48
+ const byKey = new Map();
49
+ pinned.forEach((row) => byKey.set(actualMatchingTransactionLineKey(row.transactionType, row.transactionIntegrationId, row.lineId), row));
50
+ searched.forEach((row) => {
51
+ const key = actualMatchingTransactionLineKey(row.transactionType, row.transactionIntegrationId, row.lineId);
52
+ if (!byKey.has(key)) {
53
+ byKey.set(key, row);
54
+ }
55
+ });
56
+ return Array.from(byKey.values());
57
+ }
37
58
  export function parseActualMatchingMatchId(matchId) {
38
59
  const separator = matchId.indexOf(':');
39
60
  if (separator <= 0 || separator === matchId.length - 1) {
@@ -94,18 +115,13 @@ function collectGroupedMembers(members) {
94
115
  estimatedAmount: member.estimatedAmount,
95
116
  jeDebitAccountName: member.jeDebitAccountName,
96
117
  memo: member.memo,
97
- reversalTransactionId: member.reversalTransactionId,
98
- reversalTransactionIntegrationId: member.reversalTransactionIntegrationId,
99
118
  serviceMonth: member.serviceMonth,
100
- transactionId: member.transactionId,
101
- transactionIntegrationId: member.transactionIntegrationId,
102
119
  }));
103
120
  }
104
121
  function collectLeftoverMembers(leftovers) {
105
122
  if (leftovers == null || leftovers.length === 0) {
106
123
  return undefined;
107
124
  }
108
- // Leftover accruals did not post, so they have no journal-entry ids to open.
109
125
  return leftovers.map((member) => ({
110
126
  accrualId: member.accrualId,
111
127
  estimatedAmount: member.estimatedAmount,
@@ -211,7 +227,6 @@ function emptyKpiSummary() {
211
227
  actualsReceived: { count: 0, expectedCount: 0, vendorsPending: 0 },
212
228
  autoReversed: { count: 0, percent: 0, clearedAmount: 0 },
213
229
  pendingReview: { count: 0, amount: 0, estimatedMinutesToClear: 0 },
214
- reversed: { count: 0 },
215
230
  variance: { percent: 0, averagePercentPerMatch: 0, netAmount: 0 },
216
231
  };
217
232
  }
@@ -267,7 +282,6 @@ export function buildActualMatchingKpiSummary(rows, displayCurrencyCode) {
267
282
  }
268
283
  const autoReversed = kpiRows.filter((row) => row.kind === 'auto_reversed');
269
284
  const pendingReview = kpiRows.filter((row) => row.kind === 'pending_review');
270
- const reversed = kpiRows.filter((row) => isReversedMatchKind(row.kind));
271
285
  const receivedCount = kpiRows.length;
272
286
  const rowsWithActual = kpiRows.filter((row) => row.actualAmount?.amount != null);
273
287
  const accruedTotal = rowsWithActual.reduce((sum, row) => sum + (row.accruedAmount?.amount ?? row.estimatedAmount.amount), 0);
@@ -293,9 +307,6 @@ export function buildActualMatchingKpiSummary(rows, displayCurrencyCode) {
293
307
  amount: sumRowAmounts(pendingReview, displayCurrencyCode),
294
308
  estimatedMinutesToClear: pendingReview.length * ESTIMATED_MINUTES_PER_PENDING_MATCH,
295
309
  },
296
- reversed: {
297
- count: reversed.length,
298
- },
299
310
  variance: {
300
311
  percent: accruedTotal === 0
301
312
  ? 0
@@ -308,66 +319,23 @@ export function buildActualMatchingKpiSummary(rows, displayCurrencyCode) {
308
319
  },
309
320
  };
310
321
  }
311
- function toActualMatchingMatchView(match) {
322
+ export function getExpenseAutomationActualMatchingMatchView(state, matchId) {
323
+ const view = state.expenseAutomationActualMatchingViewState;
312
324
  return {
313
- ...match,
314
- members: match.members.map(toMatchModalAccrual),
315
- leftovers: match.leftovers == null
316
- ? undefined
317
- : match.leftovers.map(toMatchModalAccrual),
325
+ match: getActualMatchingMatchById(state.actualMatchingState, matchId),
326
+ detailFetchState: view.detailFetchStateByMatchId[matchId] ?? NOT_STARTED,
327
+ refreshStatus: view.detailRefreshStatusByMatchId[matchId] ?? NOT_STARTED,
328
+ undoReversalStatus: view.undoReversalStatusByMatchId[matchId] ?? NOT_STARTED,
329
+ lastMatchResults: view.lastMatchResultsByMatchId?.[matchId],
330
+ lastUndoResults: view.lastUndoResultsByMatchId?.[matchId],
318
331
  };
319
332
  }
320
- const matchViewSelectorById = new Map();
321
- export function getExpenseAutomationActualMatchingMatchView(state, matchId) {
322
- let selector = matchViewSelectorById.get(matchId);
323
- if (selector == null) {
324
- selector = createSelector([
325
- (root) => root.expenseAutomationActualMatchingViewState
326
- .detailFetchStateByMatchId[matchId] ?? NOT_STARTED,
327
- (root) => root.expenseAutomationActualMatchingViewState.ignoreStatusByMatchId[matchId] ?? NOT_STARTED,
328
- (root) => root.expenseAutomationActualMatchingViewState
329
- .lastMatchResultsByMatchId?.[matchId],
330
- (root) => root.expenseAutomationActualMatchingViewState
331
- .lastUndoResultsByMatchId?.[matchId],
332
- (root) => root.expenseAutomationActualMatchingViewState
333
- .detailRefreshStatusByMatchId[matchId] ?? NOT_STARTED,
334
- (root) => root.expenseAutomationActualMatchingViewState
335
- .undoReversalStatusByMatchId[matchId] ?? NOT_STARTED,
336
- (root) => getActualMatchingMatchById(root.actualMatchingState, matchId),
337
- ], (detailFetchState, ignoreStatus, lastMatchResults, lastUndoResults, refreshStatus, undoReversalStatus, match) => ({
338
- detailFetchState,
339
- ignoreStatus,
340
- lastMatchResults,
341
- lastUndoResults,
342
- match: match == null ? undefined : toActualMatchingMatchView(match),
343
- refreshStatus,
344
- undoReversalStatus,
345
- }));
346
- matchViewSelectorById.set(matchId, selector);
347
- }
348
- return selector(state);
349
- }
350
333
  export function getCloseMatchAfterUndo(state) {
351
- return state.expenseAutomationActualMatchingViewState
352
- .closeMatchAfterUndoMatchIds[0];
353
- }
354
- export function getCloseMatchAfterUndoMatchId(state) {
355
- return getCloseMatchAfterUndo(state);
356
- }
357
- export function getCloseMatchAfterIgnoreMatchId(state) {
358
- return state.expenseAutomationActualMatchingViewState
359
- .closeMatchAfterIgnoreMatchIds[0];
360
- }
361
- export function getActualMatchingMatchModalConfirmStatus(state, matchId) {
362
- if (matchId != null && matchId !== '') {
363
- return (state.expenseAutomationActualMatchingViewState.confirmStatusByMatchId[matchId] ?? NOT_STARTED);
364
- }
365
- return state.expenseAutomationActualMatchingViewState.matchModal
366
- .confirmStatus;
334
+ return state.expenseAutomationActualMatchingViewState.closeMatchAfterUndo;
367
335
  }
368
336
  export function getExpenseAutomationActualMatchingView(state) {
369
337
  const { expenseAutomationActualMatchingViewState } = state;
370
- const { matchIdsByPeriod, fetchState, error, refreshStatus, uiState, matchModal, ignoreStatusByMatchId, undoReversalStatusByMatchId, } = expenseAutomationActualMatchingViewState;
338
+ const { matchIdsByPeriod, fetchState, error, refreshStatus, uiState, matchModal, } = expenseAutomationActualMatchingViewState;
371
339
  const selectedPeriod = getSelectedMonthYearForCurrentTenant(state);
372
340
  const monthYearPeriodId = selectedPeriod != null ? toMonthYearPeriodId(selectedPeriod) : undefined;
373
341
  const matchIds = monthYearPeriodId != null ? matchIdsByPeriod[monthYearPeriodId] : undefined;
@@ -383,6 +351,32 @@ export function getExpenseAutomationActualMatchingView(state) {
383
351
  const searchedAccruals = matchModal.accrualSearch.results
384
352
  .map((key) => getJEOneTimeAccrualByKey(key, state.jeSchedulesState))
385
353
  .filter((accrual) => accrual != null);
354
+ const openedMatch = matchModal.openedFromMatchId != null
355
+ ? getActualMatchingMatchById(state.actualMatchingState, matchModal.openedFromMatchId)
356
+ : undefined;
357
+ const pinnedAccruals = [
358
+ ...(openedMatch?.members ?? []),
359
+ ...(openedMatch?.leftovers ?? []),
360
+ ].map(toMatchModalAccrual);
361
+ const firstMember = openedMatch?.members[0];
362
+ const cleared = firstMember?.cleared;
363
+ const suggestion = firstMember?.matchSuggestion;
364
+ const stamp = cleared ?? suggestion;
365
+ const consumedLineIds = cleared?.consumedLineIds;
366
+ const prefill = openedMatch == null
367
+ ? undefined
368
+ : {
369
+ selectedAccrualIds: [
370
+ ...openedMatch.members.map((member) => member.accrualId),
371
+ ...(openedMatch.leftovers ?? []).map((leftover) => leftover.accrualId),
372
+ ],
373
+ actualAmount: openedMatch.actualAmount.amount,
374
+ matchedTransactionId: stamp?.matchedTransactionId,
375
+ matchedLineId: cleared == null ? suggestion?.matchedLineId : undefined,
376
+ ...(consumedLineIds != null && consumedLineIds.length > 0
377
+ ? { consumedLineIds }
378
+ : {}),
379
+ };
386
380
  // `fetchState` is a flat slice field that survives a period switch. Until this
387
381
  // month's ids land, leftover Completed/Error is the previous month. Report
388
382
  // Not-Started so chrome matches Review's "cache slot missing" skeleton, not
@@ -400,16 +394,16 @@ export function getExpenseAutomationActualMatchingView(state) {
400
394
  kpiSummary,
401
395
  uiState,
402
396
  refreshStatus,
403
- ignoreStatusByMatchId,
404
- undoReversalStatusByMatchId,
405
397
  hasLoadedForSelectedPeriod: matchIds != null,
406
398
  matchModal: {
407
399
  isOpen: matchModal.isOpen,
400
+ openedFromMatchId: matchModal.openedFromMatchId,
401
+ prefill,
408
402
  confirmStatus: matchModal.confirmStatus,
409
403
  lastBatchResults: matchModal.lastBatchResults,
410
404
  transactionSearch: {
411
405
  query: matchModal.transactionSearch.query,
412
- results: matchModal.transactionSearch.results,
406
+ results: uniqueTransactionSearchResults(matchModal.pinnedTransactionResults, matchModal.transactionSearch.results),
413
407
  fetchState: {
414
408
  fetchState: matchModal.transactionSearch.fetchState,
415
409
  error: matchModal.transactionSearch.error,
@@ -419,7 +413,7 @@ export function getExpenseAutomationActualMatchingView(state) {
419
413
  },
420
414
  accrualSearch: {
421
415
  query: matchModal.accrualSearch.query,
422
- results: searchedAccruals,
416
+ results: uniqueMatchModalAccruals(pinnedAccruals, searchedAccruals),
423
417
  fetchState: {
424
418
  fetchState: matchModal.accrualSearch.fetchState,
425
419
  error: matchModal.accrualSearch.error,
@@ -13,12 +13,6 @@ const ACTUAL_MATCHING_SORT_KEYS = [
13
13
  'variance',
14
14
  ];
15
15
  export const toActualMatchingSortKey = (v) => stringToUnion(v, ACTUAL_MATCHING_SORT_KEYS);
16
- const ACTUAL_MATCHING_STATUS_FILTERS = [
17
- 'all',
18
- 'pending_review',
19
- 'reversed',
20
- ];
21
- export const toActualMatchingStatusFilter = (v) => stringToUnion(v, ACTUAL_MATCHING_STATUS_FILTERS);
22
16
  export const MATCH_TRANSACTION_SEARCH_PAGE_SIZE = 50;
23
17
  export const MATCH_ACCRUAL_SEARCH_LIMIT = 50;
24
18
  export const MATCH_SEARCH_DEBOUNCE_MS = 300;
@@ -39,15 +33,6 @@ const UNDO_REVERSAL_RESULT_STATUSES = [
39
33
  'error',
40
34
  ];
41
35
  export const toUndoReversalResultStatus = (v) => stringToUnion(v, UNDO_REVERSAL_RESULT_STATUSES);
42
- const ACTUAL_MATCHING_IGNORE_REASONS = [
43
- 'wrong_bill',
44
- 'wrong_period',
45
- 'amount_off',
46
- 'already_handled',
47
- 'other_ignore',
48
- ];
49
- export const toActualMatchingIgnoreReasonType = (v) => stringToUnion(v, ACTUAL_MATCHING_IGNORE_REASONS);
50
- export const ALL_ACTUAL_MATCHING_IGNORE_REASONS = ACTUAL_MATCHING_IGNORE_REASONS;
51
36
  export function actualMatchingTransactionLineKey(transactionType, transactionIntegrationId, lineId) {
52
37
  return `${transactionType}:${transactionIntegrationId}:${lineId}`;
53
38
  }
@@ -6,8 +6,7 @@ import { updateInvoices } from '../../../entity/invoicing/invoice/invoiceReducer
6
6
  import { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
7
7
  import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
8
8
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
9
- import { invalidateInvoicingCustomerDetail } from '../editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer';
10
- import { addInvoiceToList, invalidateInvoiceListForCustomer, } from '../invoiceList/invoiceListReducer';
9
+ import { addInvoiceToList } from '../invoiceList/invoiceListReducer';
11
10
  import { createInvoice, createInvoiceFailure, createInvoiceSuccess, } from './createInvoiceReducer';
12
11
  export const createInvoiceEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(createInvoice.match), mergeMap((action) => {
13
12
  const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/invoices`;
@@ -24,13 +23,6 @@ export const createInvoiceEpic = (actions$, _state$, zeniAPI) => actions$.pipe(f
24
23
  id: response.data.id,
25
24
  status: response.data.status,
26
25
  }),
27
- // The customer's page caches their invoices and totals.
28
- invalidateInvoicingCustomerDetail({
29
- id: response.data.customer_id,
30
- }),
31
- invalidateInvoiceListForCustomer({
32
- customerId: response.data.customer_id,
33
- }),
34
26
  createInvoiceSuccess({ invoiceId: response.data.id }),
35
27
  openSnackbar({
36
28
  messageSection: 'invoicing_invoice_saved',
@@ -1,5 +1,5 @@
1
1
  import { getAddressByAddressId } from '../../../entity/address/addressSelector';
2
- import { invoicingPricePointDisplayAmount } from '../../../entity/invoicing/invoicingCatalog/invoicingCatalogSelector';
2
+ import { invoicingPricePointDisplayAmount } from '../../../entity/invoicing/plan/planSelector';
3
3
  import { getInvoicingCatalogListView, getInvoicingCatalogPrices, } from '../invoicingCatalogListView/invoicingCatalogListViewSelector';
4
4
  import { invoicingFieldHelpForGroup } from '../invoicingConfigView/invoicingConfigViewSelector';
5
5
  import { getInvoicingCustomerListView } from '../invoicingCustomerListView/invoicingCustomerListViewSelector';
@@ -1,6 +1,6 @@
1
1
  import { createSelector } from '@reduxjs/toolkit';
2
2
  import { reduceAllFetchState } from '../../../commonStateTypes/reduceFetchState';
3
- import { getInvoicingCatalogItemById, getInvoicingCatalogItemsByIds, } from '../../../entity/invoicing/invoicingCatalog/invoicingCatalogSelector';
3
+ import { getInvoicingPlanById, getInvoicingPlansByIds, } from '../../../entity/invoicing/plan/planSelector';
4
4
  import { getInvoicingConfigView, invoicingFieldHelpForGroup, } from '../invoicingConfigView/invoicingConfigViewSelector';
5
5
  import { getInvoicingFormDraftLocalData, isInvoicingFormDraftPending, } from '../invoicingFormDraft';
6
6
  import { INVOICING_DEFAULT_INCOME_ACCOUNT_TYPES, INVOICING_INCOME_ACCOUNT_MAPPING_SLOT, NO_INVOICING_ACCOUNT_HIERARCHY, NO_INVOICING_ACCOUNT_IDS, NO_INVOICING_CLASS_HIERARCHY, getInvoicingQboAccountOptions, getInvoicingQboView, invoicingQboAccountIdsForMappingSlot, isInvoicingAccountingPickerDataLoading, isInvoicingQboConnected, } from '../invoicingQboView/invoicingQboViewSelector';
@@ -36,7 +36,7 @@ const buildApplicableCatalogItemOptions = (plans) => {
36
36
  * Kept referentially stable across unrelated dispatches; the form view filters
37
37
  * out the item being edited (see `getInvoicingCatalogItemFormView`).
38
38
  */
39
- export const getInvoicingApplicableCatalogItemOptions = createSelector((state) => state.invoicingCatalogState, (state) => state.invoicingCatalogListViewState, (catalogState, listViewState) => buildApplicableCatalogItemOptions(getInvoicingCatalogItemsByIds(catalogState, [
39
+ export const getInvoicingApplicableCatalogItemOptions = createSelector((state) => state.invoicingPlanState, (state) => state.invoicingCatalogListViewState, (planState, listViewState) => buildApplicableCatalogItemOptions(getInvoicingPlansByIds(planState, [
40
40
  ...listViewState.planIds,
41
41
  ...listViewState.productIds,
42
42
  ])));
@@ -61,9 +61,7 @@ const getInvoicingCatalogIncomeAccountIds = createSelector([
61
61
  : NO_INVOICING_ACCOUNT_IDS);
62
62
  export const getInvoicingCatalogItemFormView = (state, id) => {
63
63
  const { editDraftById, error, fetchState, newItemDraft, savedItemId, savedKind, } = state.editInvoicingCatalogItemDetailViewState;
64
- const plan = id != null
65
- ? getInvoicingCatalogItemById(state.invoicingCatalogState, id)
66
- : undefined;
64
+ const plan = id != null ? getInvoicingPlanById(state.invoicingPlanState, id) : undefined;
67
65
  const kind = plan != null ? 'plan' : undefined;
68
66
  // No entity fallback: the draft is the one source of form values, seeded from
69
67
  // the record by `seedInvoicingCatalogItemFormDraftEpic` when the detail load
@@ -1,6 +1,6 @@
1
1
  import { of } from 'rxjs';
2
2
  import { catchError, filter, switchMap } from 'rxjs/operators';
3
- import { updateInvoicingCatalogItems } from '../../../entity/invoicing/invoicingCatalog/invoicingCatalogReducer';
3
+ import { updateInvoicingPlans } from '../../../entity/invoicing/plan/planReducer';
4
4
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
5
5
  import { fetchInvoicingCatalogItemDetail, updateInvoicingCatalogItemDetail, updateInvoicingCatalogItemDetailFailure, } from './editInvoicingCatalogItemDetailViewReducer';
6
6
  export const fetchInvoicingCatalogItemDetailEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(fetchInvoicingCatalogItemDetail.match), switchMap((action) => {
@@ -9,7 +9,7 @@ export const fetchInvoicingCatalogItemDetailEpic = (actions$, _state$, zeniAPI)
9
9
  return zeniAPI.getJSON(apiUrl).pipe(switchMap((response) => {
10
10
  if (isSuccessResponse(response) && response.data != null) {
11
11
  return [
12
- updateInvoicingCatalogItems([response.data], 'merge'),
12
+ updateInvoicingPlans([response.data], 'merge'),
13
13
  updateInvoicingCatalogItemDetail({ id: response.data.id, kind }),
14
14
  ];
15
15
  }
@@ -1,6 +1,6 @@
1
1
  import { of } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
- import { updateInvoicingCatalogItems } from '../../../entity/invoicing/invoicingCatalog/invoicingCatalogReducer';
3
+ import { updateInvoicingPlans } from '../../../entity/invoicing/plan/planReducer';
4
4
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
5
5
  import { runInvoicingCatalogPlanAction, runInvoicingCatalogPlanActionFailure, runInvoicingCatalogPlanActionSuccess, } from './editInvoicingCatalogItemDetailViewReducer';
6
6
  export const runInvoicingCatalogPlanActionEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(runInvoicingCatalogPlanAction.match), mergeMap((action) => {
@@ -12,7 +12,7 @@ export const runInvoicingCatalogPlanActionEpic = (actions$, _state$, zeniAPI) =>
12
12
  .pipe(mergeMap((response) => {
13
13
  if (isSuccessResponse(response) && response.data != null) {
14
14
  return [
15
- updateInvoicingCatalogItems([response.data], 'merge'),
15
+ updateInvoicingPlans([response.data], 'merge'),
16
16
  runInvoicingCatalogPlanActionSuccess({ id }),
17
17
  ];
18
18
  }
@@ -1,6 +1,7 @@
1
1
  import { of } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
- import { mergeInvoicingCatalogPricePoint } from '../../../entity/invoicing/invoicingCatalog/invoicingCatalogReducer';
3
+ import { mergeInvoicingPlanSubFamily } from '../../../entity/invoicing/plan/planReducer';
4
+ import { updateInvoicingProducts } from '../../../entity/invoicing/product/productReducer';
4
5
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
5
6
  import { runInvoicingCatalogProductAction, runInvoicingCatalogProductActionFailure, runInvoicingCatalogProductActionSuccess, } from './editInvoicingCatalogItemDetailViewReducer';
6
7
  export const runInvoicingCatalogProductActionEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(runInvoicingCatalogProductAction.match), mergeMap((action) => {
@@ -15,10 +16,9 @@ export const runInvoicingCatalogProductActionEpic = (actions$, _state$, zeniAPI)
15
16
  .pipe(mergeMap((response) => {
16
17
  if (isSuccessResponse(response) && response.data != null) {
17
18
  return [
19
+ updateInvoicingProducts([response.data], 'merge'),
18
20
  ...(parentItemId != null
19
- ? [
20
- mergeInvoicingCatalogPricePoint(parentItemId, response.data),
21
- ]
21
+ ? [mergeInvoicingPlanSubFamily(parentItemId, response.data)]
22
22
  : []),
23
23
  runInvoicingCatalogProductActionSuccess({ id: stateKey }),
24
24
  ];
@@ -1,6 +1,7 @@
1
1
  import { forkJoin, from } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
- import { mergeInvoicingCatalogPricePoint, updateInvoicingCatalogItems, } from '../../../entity/invoicing/invoicingCatalog/invoicingCatalogReducer';
3
+ import { mergeInvoicingPlanSubFamily, updateInvoicingPlans, } from '../../../entity/invoicing/plan/planReducer';
4
+ import { updateInvoicingProducts } from '../../../entity/invoicing/product/productReducer';
4
5
  import { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
5
6
  import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
6
7
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
@@ -50,8 +51,11 @@ export const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actio
50
51
  }
51
52
  const savedProducts = productResponses.flatMap((productResponse) => productResponse.data != null ? [productResponse.data] : []);
52
53
  const resultActions = [
53
- updateInvoicingCatalogItems([savedItem], 'merge'),
54
- ...savedProducts.map((product) => mergeInvoicingCatalogPricePoint(savedItem.id, product)),
54
+ updateInvoicingPlans([savedItem], 'merge'),
55
+ ...(savedProducts.length > 0
56
+ ? [updateInvoicingProducts(savedProducts, 'merge')]
57
+ : []),
58
+ ...savedProducts.map((product) => mergeInvoicingPlanSubFamily(savedItem.id, product)),
55
59
  submitInvoicingCatalogItemFormSuccess({
56
60
  itemId: savedItem.id,
57
61
  kind: 'plan',
@@ -1,6 +1,6 @@
1
1
  import { EMPTY, of } from 'rxjs';
2
2
  import { filter, mergeMap, withLatestFrom } from 'rxjs/operators';
3
- import { getInvoicingCatalogItemById } from '../../../entity/invoicing/invoicingCatalog/invoicingCatalogSelector';
3
+ import { getInvoicingPlanById } from '../../../entity/invoicing/plan/planSelector';
4
4
  import { fetchInvoicingCatalogItemDetailPage, seedInvoicingCatalogItemFormDraft, updateInvoicingCatalogItemDetail, } from './editInvoicingCatalogItemDetailViewReducer';
5
5
  import { entityToInvoicingCatalogItemFormLocalData } from './invoicingCatalogItemFormHelper';
6
6
  /**
@@ -34,7 +34,7 @@ export const seedInvoicingCatalogItemFormDraftEpic = (actions$, state$) => actio
34
34
  }
35
35
  // Nothing to seed from on a cold open; the detail response triggers this
36
36
  // again once it lands.
37
- const plan = getInvoicingCatalogItemById(state.invoicingCatalogState, id);
37
+ const plan = getInvoicingPlanById(state.invoicingPlanState, id);
38
38
  if (plan == null) {
39
39
  return EMPTY;
40
40
  }