@zeniai/client-epic-state 5.2.69 → 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 (161) 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 -1
  23. package/lib/entity/jeSchedules/jeSchedulesPayload.js +0 -1
  24. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +0 -1
  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/entity/transaction/payloadTypes/transactionLinePayload.js +10 -2
  29. package/lib/epic.d.ts +2 -4
  30. package/lib/epic.js +1 -5
  31. package/lib/esm/entity/actualMatching/actualMatchingReducer.js +1 -9
  32. package/lib/esm/entity/invoicing/plan/planPayload.js +47 -0
  33. package/lib/esm/entity/invoicing/{invoicingCatalog/invoicingCatalogReducer.js → plan/planReducer.js} +20 -19
  34. package/lib/esm/entity/invoicing/{invoicingCatalog/invoicingCatalogSelector.js → plan/planSelector.js} +8 -8
  35. package/lib/esm/entity/invoicing/{invoicingCatalog/invoicingCatalogPayload.js → product/productPayload.js} +3 -46
  36. package/lib/esm/entity/invoicing/product/productReducer.js +43 -0
  37. package/lib/esm/entity/invoicing/product/productSelector.js +10 -0
  38. package/lib/esm/entity/invoicing/product/productState.js +1 -0
  39. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +0 -1
  40. package/lib/esm/entity/snackbar/snackbarTypes.js +0 -3
  41. package/lib/esm/entity/transaction/payloadTypes/transactionLinePayload.js +10 -2
  42. package/lib/esm/epic.js +1 -5
  43. package/lib/esm/index.js +11 -9
  44. package/lib/esm/reducer.js +7 -4
  45. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.js +2 -4
  46. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.js +13 -26
  47. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchTransactionsEpic.js +23 -2
  48. package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +2 -1
  49. package/lib/esm/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +38 -89
  50. package/lib/esm/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +64 -66
  51. package/lib/esm/view/expenseAutomationView/types/actualMatchingViewState.js +0 -15
  52. package/lib/esm/view/invoicing/createInvoice/createInvoiceEpic.js +1 -9
  53. package/lib/esm/view/invoicing/createInvoice/createInvoiceSelector.js +1 -1
  54. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +3 -5
  55. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/fetchInvoicingCatalogItemDetailEpic.js +2 -2
  56. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/runInvoicingCatalogPlanActionEpic.js +2 -2
  57. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/runInvoicingCatalogProductActionEpic.js +4 -4
  58. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +7 -3
  59. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/seedInvoicingCatalogItemFormDraftEpic.js +2 -2
  60. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer.js +1 -5
  61. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +1 -5
  62. package/lib/esm/view/invoicing/invoiceList/invoiceListReducer.js +1 -8
  63. package/lib/esm/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogPlanListEpic.js +2 -2
  64. package/lib/esm/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogProductListEpic.js +2 -2
  65. package/lib/esm/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewSelector.js +4 -4
  66. package/lib/esm/view/invoicing/settingsView/settingsViewSelector.js +9 -18
  67. package/lib/esm/view/invoicing/settingsView/submitInvoicingBrandingFormEpic.js +2 -11
  68. package/lib/esm/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewEpic.js +11 -31
  69. package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewReducer.js +1 -2
  70. package/lib/esm/view/spendManagement/billPay/editBillView/editBillViewSelector.js +30 -4
  71. package/lib/esm/view/spendManagement/commonSetup/setupViewReducer.js +1 -21
  72. package/lib/esm/view/spendManagement/commonSetup/setupViewSelector.js +1 -2
  73. package/lib/index.d.ts +16 -13
  74. package/lib/index.js +60 -65
  75. package/lib/reducer.d.ts +2 -1
  76. package/lib/reducer.js +7 -4
  77. package/lib/rootStateTypes.d.ts +5 -3
  78. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.d.ts +2 -2
  79. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/fetchActualMatchingMatchEpic.js +1 -3
  80. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/matchAndReverseAccrualsEpic.js +11 -24
  81. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/searchMatchTransactionsEpic.js +22 -1
  82. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  83. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +2 -1
  84. package/lib/view/expenseAutomationView/payload/actualMatchingPayload.d.ts +1 -12
  85. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.d.ts +8 -19
  86. package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +39 -90
  87. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +2 -2
  88. package/lib/view/expenseAutomationView/selectorTypes/actualMatchingViewSelectorTypes.d.ts +8 -20
  89. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.d.ts +4 -7
  90. package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +64 -69
  91. package/lib/view/expenseAutomationView/types/actualMatchingViewState.d.ts +4 -20
  92. package/lib/view/expenseAutomationView/types/actualMatchingViewState.js +1 -18
  93. package/lib/view/invoicing/createInvoice/createInvoiceEpic.d.ts +2 -3
  94. package/lib/view/invoicing/createInvoice/createInvoiceEpic.js +0 -8
  95. package/lib/view/invoicing/createInvoice/createInvoiceSelector.d.ts +2 -2
  96. package/lib/view/invoicing/createInvoice/createInvoiceSelector.js +2 -2
  97. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.d.ts +9 -8
  98. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.d.ts +2 -2
  99. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +3 -5
  100. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/fetchInvoicingCatalogItemDetailEpic.d.ts +2 -2
  101. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/fetchInvoicingCatalogItemDetailEpic.js +2 -2
  102. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/invoicingCatalogItemFormHelper.d.ts +4 -3
  103. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/runInvoicingCatalogPlanActionEpic.d.ts +2 -2
  104. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/runInvoicingCatalogPlanActionEpic.js +2 -2
  105. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/runInvoicingCatalogProductActionEpic.d.ts +3 -2
  106. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/runInvoicingCatalogProductActionEpic.js +4 -4
  107. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.d.ts +3 -2
  108. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +7 -3
  109. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/seedInvoicingCatalogItemFormDraftEpic.js +2 -2
  110. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer.d.ts +1 -3
  111. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer.js +2 -6
  112. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewSelector.d.ts +2 -2
  113. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.d.ts +1 -3
  114. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +1 -5
  115. package/lib/view/invoicing/invoiceList/invoiceListReducer.d.ts +1 -3
  116. package/lib/view/invoicing/invoiceList/invoiceListReducer.js +2 -9
  117. package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogListPageEpic.d.ts +2 -2
  118. package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogPlanListEpic.d.ts +2 -2
  119. package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogPlanListEpic.js +2 -2
  120. package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogProductListEpic.d.ts +2 -2
  121. package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogProductListEpic.js +2 -2
  122. package/lib/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewPayload.d.ts +3 -3
  123. package/lib/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewSelector.d.ts +5 -4
  124. package/lib/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewSelector.js +4 -4
  125. package/lib/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewState.d.ts +1 -1
  126. package/lib/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewReducer.d.ts +1 -1
  127. package/lib/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewState.d.ts +1 -1
  128. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewReducer.d.ts +1 -1
  129. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewState.d.ts +1 -1
  130. package/lib/view/invoicing/settingsView/settingsViewSelector.d.ts +3 -12
  131. package/lib/view/invoicing/settingsView/settingsViewSelector.js +8 -17
  132. package/lib/view/invoicing/settingsView/submitInvoicingBrandingFormEpic.js +2 -11
  133. package/lib/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewEpic.js +11 -31
  134. package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.d.ts +2 -3
  135. package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.js +1 -2
  136. package/lib/view/onboardingView/customerView/onboardingCustomerViewState.d.ts +0 -4
  137. package/lib/view/scheduleView/scheduleListView/scheduleListTypes.d.ts +1 -1
  138. package/lib/view/spendManagement/billPay/billList/billListReducer.d.ts +5 -5
  139. package/lib/view/spendManagement/billPay/billList/billListState.d.ts +1 -1
  140. package/lib/view/spendManagement/billPay/editBillView/editBillViewReducer.d.ts +2 -2
  141. package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.d.ts +1 -1
  142. package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.js +30 -4
  143. package/lib/view/spendManagement/commonSetup/setupViewReducer.d.ts +1 -1
  144. package/lib/view/spendManagement/commonSetup/setupViewReducer.js +2 -22
  145. package/lib/view/spendManagement/commonSetup/setupViewSelector.d.ts +0 -1
  146. package/lib/view/spendManagement/commonSetup/setupViewSelector.js +1 -2
  147. package/lib/view/spendManagement/commonSetup/setupViewState.d.ts +0 -1
  148. package/lib/view/spendManagement/commonSetup/types/businessVerification.d.ts +1 -2
  149. package/lib/view/spendManagement/reimbursement/editRemiView/editRemiViewReducer.d.ts +2 -2
  150. package/lib/view/spendManagement/reimbursement/remiListView/remiListReducer.d.ts +5 -5
  151. package/lib/view/spendManagement/reimbursement/remiListView/remiListState.d.ts +2 -2
  152. package/package.json +1 -1
  153. package/lib/entity/invoicing/invoicingCatalog/invoicingCatalogReducer.d.ts +0 -12
  154. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.js +0 -50
  155. package/lib/esm/view/spendManagement/commonSetup/epic/setup/resetKycKybEpic.js +0 -37
  156. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.d.ts +0 -10
  157. package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.js +0 -54
  158. package/lib/view/spendManagement/commonSetup/epic/setup/resetKycKybEpic.d.ts +0 -8
  159. package/lib/view/spendManagement/commonSetup/epic/setup/resetKycKybEpic.js +0 -41
  160. /package/lib/entity/invoicing/{invoicingCatalog/invoicingCatalogState.js → plan/planState.js} +0 -0
  161. /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,11 +1,11 @@
1
1
  import orderBy from 'lodash/orderBy';
2
- import { createSelector } from '@reduxjs/toolkit';
3
2
  import { toMonthYearPeriodId, } from '../../../commonStateTypes/timePeriod';
4
3
  import { getActualMatchingMatchById } from '../../../entity/actualMatching/actualMatchingSelector';
5
4
  import { generateJEOneTimeAccrualKey } from '../../../entity/jeSchedules/jeScheduleHelper';
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) {
@@ -206,7 +227,6 @@ function emptyKpiSummary() {
206
227
  actualsReceived: { count: 0, expectedCount: 0, vendorsPending: 0 },
207
228
  autoReversed: { count: 0, percent: 0, clearedAmount: 0 },
208
229
  pendingReview: { count: 0, amount: 0, estimatedMinutesToClear: 0 },
209
- reversed: { count: 0 },
210
230
  variance: { percent: 0, averagePercentPerMatch: 0, netAmount: 0 },
211
231
  };
212
232
  }
@@ -262,7 +282,6 @@ export function buildActualMatchingKpiSummary(rows, displayCurrencyCode) {
262
282
  }
263
283
  const autoReversed = kpiRows.filter((row) => row.kind === 'auto_reversed');
264
284
  const pendingReview = kpiRows.filter((row) => row.kind === 'pending_review');
265
- const reversed = kpiRows.filter((row) => isReversedMatchKind(row.kind));
266
285
  const receivedCount = kpiRows.length;
267
286
  const rowsWithActual = kpiRows.filter((row) => row.actualAmount?.amount != null);
268
287
  const accruedTotal = rowsWithActual.reduce((sum, row) => sum + (row.accruedAmount?.amount ?? row.estimatedAmount.amount), 0);
@@ -288,9 +307,6 @@ export function buildActualMatchingKpiSummary(rows, displayCurrencyCode) {
288
307
  amount: sumRowAmounts(pendingReview, displayCurrencyCode),
289
308
  estimatedMinutesToClear: pendingReview.length * ESTIMATED_MINUTES_PER_PENDING_MATCH,
290
309
  },
291
- reversed: {
292
- count: reversed.length,
293
- },
294
310
  variance: {
295
311
  percent: accruedTotal === 0
296
312
  ? 0
@@ -303,61 +319,23 @@ export function buildActualMatchingKpiSummary(rows, displayCurrencyCode) {
303
319
  },
304
320
  };
305
321
  }
306
- function toActualMatchingMatchView(match) {
322
+ export function getExpenseAutomationActualMatchingMatchView(state, matchId) {
323
+ const view = state.expenseAutomationActualMatchingViewState;
307
324
  return {
308
- ...match,
309
- members: match.members.map(toMatchModalAccrual),
310
- leftovers: match.leftovers == null
311
- ? undefined
312
- : 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],
313
331
  };
314
332
  }
315
- const EMPTY_ACTUAL_MATCHING_ROWS = [];
316
- const matchViewSelectorById = new Map();
317
- export function getExpenseAutomationActualMatchingMatchView(state, matchId) {
318
- let selector = matchViewSelectorById.get(matchId);
319
- if (selector == null) {
320
- selector = createSelector([
321
- (root) => root.expenseAutomationActualMatchingViewState.detailFetchStateByMatchId[matchId] ?? NOT_STARTED,
322
- (root) => root.expenseAutomationActualMatchingViewState.ignoreStatusByMatchId[matchId] ?? NOT_STARTED,
323
- (root) => root.expenseAutomationActualMatchingViewState.lastMatchResultsByMatchId?.[matchId],
324
- (root) => root.expenseAutomationActualMatchingViewState.lastUndoResultsByMatchId?.[matchId],
325
- (root) => root.expenseAutomationActualMatchingViewState.detailRefreshStatusByMatchId[matchId] ?? NOT_STARTED,
326
- (root) => root.expenseAutomationActualMatchingViewState.undoReversalStatusByMatchId[matchId] ?? NOT_STARTED,
327
- (root) => getActualMatchingMatchById(root.actualMatchingState, matchId),
328
- ], (detailFetchState, ignoreStatus, lastMatchResults, lastUndoResults, refreshStatus, undoReversalStatus, match) => ({
329
- detailFetchState,
330
- ignoreStatus,
331
- lastMatchResults,
332
- lastUndoResults,
333
- match: match == null ? undefined : toActualMatchingMatchView(match),
334
- refreshStatus,
335
- undoReversalStatus,
336
- }));
337
- matchViewSelectorById.set(matchId, selector);
338
- }
339
- return selector(state);
340
- }
341
333
  export function getCloseMatchAfterUndo(state) {
342
- return state.expenseAutomationActualMatchingViewState
343
- .closeMatchAfterUndoMatchIds[0];
344
- }
345
- export function getCloseMatchAfterUndoMatchId(state) {
346
- return getCloseMatchAfterUndo(state);
347
- }
348
- export function getCloseMatchAfterIgnoreMatchId(state) {
349
- return state.expenseAutomationActualMatchingViewState
350
- .closeMatchAfterIgnoreMatchIds[0];
351
- }
352
- export function getActualMatchingMatchModalConfirmStatus(state, matchId) {
353
- if (matchId != null && matchId !== '') {
354
- return (state.expenseAutomationActualMatchingViewState.confirmStatusByMatchId[matchId] ?? NOT_STARTED);
355
- }
356
- return state.expenseAutomationActualMatchingViewState.matchModal.confirmStatus;
334
+ return state.expenseAutomationActualMatchingViewState.closeMatchAfterUndo;
357
335
  }
358
336
  export function getExpenseAutomationActualMatchingView(state) {
359
337
  const { expenseAutomationActualMatchingViewState } = state;
360
- const { matchIdsByPeriod, fetchState, error, refreshStatus, uiState, matchModal, ignoreStatusByMatchId, undoReversalStatusByMatchId, } = expenseAutomationActualMatchingViewState;
338
+ const { matchIdsByPeriod, fetchState, error, refreshStatus, uiState, matchModal, } = expenseAutomationActualMatchingViewState;
361
339
  const selectedPeriod = getSelectedMonthYearForCurrentTenant(state);
362
340
  const monthYearPeriodId = selectedPeriod != null ? toMonthYearPeriodId(selectedPeriod) : undefined;
363
341
  const matchIds = monthYearPeriodId != null ? matchIdsByPeriod[monthYearPeriodId] : undefined;
@@ -367,18 +345,38 @@ export function getExpenseAutomationActualMatchingView(state) {
367
345
  .filter((match) => match.members.length > 0)
368
346
  .map(toActualMatchingRow);
369
347
  const rows = allRows.filter((row) => matchesSearch(row, uiState.searchString));
370
- const includePendingReview = uiState.statusFilter !== 'reversed';
371
- const includeReversed = uiState.statusFilter !== 'pending_review';
372
- const reversed = includeReversed
373
- ? sortActualMatchingRows(rows.filter((row) => isReversedMatchKind(row.kind)), uiState)
374
- : EMPTY_ACTUAL_MATCHING_ROWS;
375
- const pendingReview = includePendingReview
376
- ? sortActualMatchingRows(rows.filter((row) => row.kind === 'pending_review'), uiState)
377
- : EMPTY_ACTUAL_MATCHING_ROWS;
348
+ const reversed = sortActualMatchingRows(rows.filter((row) => isReversedMatchKind(row.kind)), uiState);
349
+ const pendingReview = sortActualMatchingRows(rows.filter((row) => row.kind === 'pending_review'), uiState);
378
350
  const kpiSummary = buildActualMatchingKpiSummary(allRows, getTenantDisplayCurrency(state)?.currencyCode);
379
351
  const searchedAccruals = matchModal.accrualSearch.results
380
352
  .map((key) => getJEOneTimeAccrualByKey(key, state.jeSchedulesState))
381
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
+ };
382
380
  // `fetchState` is a flat slice field that survives a period switch. Until this
383
381
  // month's ids land, leftover Completed/Error is the previous month. Report
384
382
  // Not-Started so chrome matches Review's "cache slot missing" skeleton, not
@@ -396,16 +394,16 @@ export function getExpenseAutomationActualMatchingView(state) {
396
394
  kpiSummary,
397
395
  uiState,
398
396
  refreshStatus,
399
- ignoreStatusByMatchId,
400
- undoReversalStatusByMatchId,
401
397
  hasLoadedForSelectedPeriod: matchIds != null,
402
398
  matchModal: {
403
399
  isOpen: matchModal.isOpen,
400
+ openedFromMatchId: matchModal.openedFromMatchId,
401
+ prefill,
404
402
  confirmStatus: matchModal.confirmStatus,
405
403
  lastBatchResults: matchModal.lastBatchResults,
406
404
  transactionSearch: {
407
405
  query: matchModal.transactionSearch.query,
408
- results: matchModal.transactionSearch.results,
406
+ results: uniqueTransactionSearchResults(matchModal.pinnedTransactionResults, matchModal.transactionSearch.results),
409
407
  fetchState: {
410
408
  fetchState: matchModal.transactionSearch.fetchState,
411
409
  error: matchModal.transactionSearch.error,
@@ -415,7 +413,7 @@ export function getExpenseAutomationActualMatchingView(state) {
415
413
  },
416
414
  accrualSearch: {
417
415
  query: matchModal.accrualSearch.query,
418
- results: searchedAccruals,
416
+ results: uniqueMatchModalAccruals(pinnedAccruals, searchedAccruals),
419
417
  fetchState: {
420
418
  fetchState: matchModal.accrualSearch.fetchState,
421
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
  }