@zeniai/client-epic-state 5.1.86 → 5.1.87

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 (109) hide show
  1. package/lib/entity/aiCfo/aiCfoPayload.d.ts +7 -0
  2. package/lib/entity/aiCfo/aiCfoReducer.d.ts +3 -2
  3. package/lib/entity/aiCfo/aiCfoReducer.js +25 -2
  4. package/lib/entity/aiCfo/aiCfoState.d.ts +7 -0
  5. package/lib/entity/customerSatisfaction/customerSatisfactionReducer.d.ts +1 -1
  6. package/lib/entity/customerSatisfaction/customerSatisfactionReducer.js +6 -2
  7. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  8. package/lib/entity/snackbar/snackbarTypes.js +29 -0
  9. package/lib/esm/entity/aiCfo/aiCfoReducer.js +23 -1
  10. package/lib/esm/entity/customerSatisfaction/customerSatisfactionReducer.js +4 -1
  11. package/lib/esm/entity/snackbar/snackbarTypes.js +29 -0
  12. package/lib/esm/index.js +2 -2
  13. package/lib/esm/view/companyHealthMetricView/companyHealthMetricConfigReducer.js +4 -1
  14. package/lib/esm/view/invoicing/createCreditNote/createCreditNoteEpic.js +24 -4
  15. package/lib/esm/view/invoicing/createInvoice/createInvoiceEpic.js +24 -4
  16. package/lib/esm/view/invoicing/createInvoice/createInvoiceSelector.js +37 -10
  17. package/lib/esm/view/invoicing/discountAction/discountActionEpic.js +33 -9
  18. package/lib/esm/view/invoicing/dunningAction/dunningActionEpic.js +35 -9
  19. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js +5 -1
  20. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +32 -5
  21. package/lib/esm/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +23 -3
  22. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +24 -4
  23. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +24 -4
  24. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/syncInvoicingSubscriptionCouponsEpic.js +20 -3
  25. package/lib/esm/view/invoicing/invoiceAction/invoiceActionEpic.js +60 -17
  26. package/lib/esm/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.js +30 -0
  27. package/lib/esm/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.js +4 -29
  28. package/lib/esm/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +29 -10
  29. package/lib/esm/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +28 -5
  30. package/lib/esm/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +24 -4
  31. package/lib/esm/view/invoicing/issueCreditNote/issueCreditNoteSelector.js +22 -14
  32. package/lib/esm/view/invoicing/recordPayment/recordPaymentEpic.js +46 -7
  33. package/lib/esm/view/invoicing/settingsView/settingsViewEpics.js +26 -8
  34. package/lib/esm/view/invoicing/settingsView/settingsViewReducer.js +1 -1
  35. package/lib/esm/view/invoicing/settingsView/settingsViewSelector.js +4 -1
  36. package/lib/esm/view/invoicing/subscriptionAction/subscriptionActionEpic.js +41 -9
  37. package/lib/esm/view/vendorFiling1099/vendorFiling1099UploadDetails/vendorFiling1099UploadDetailsReducer.js +4 -1
  38. package/lib/esm/view/vendorTabView/vendorTabViewReducer.js +4 -1
  39. package/lib/index.d.ts +6 -5
  40. package/lib/index.js +7 -7
  41. package/lib/view/companyHealthMetricView/companyHealthMetricConfigReducer.d.ts +1 -1
  42. package/lib/view/companyHealthMetricView/companyHealthMetricConfigReducer.js +5 -2
  43. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  44. package/lib/view/invoicing/createCreditNote/createCreditNoteEpic.d.ts +2 -1
  45. package/lib/view/invoicing/createCreditNote/createCreditNoteEpic.js +23 -3
  46. package/lib/view/invoicing/createInvoice/createInvoiceEpic.d.ts +2 -1
  47. package/lib/view/invoicing/createInvoice/createInvoiceEpic.js +23 -3
  48. package/lib/view/invoicing/createInvoice/createInvoiceSelector.d.ts +22 -8
  49. package/lib/view/invoicing/createInvoice/createInvoiceSelector.js +37 -10
  50. package/lib/view/invoicing/discountAction/discountActionEpic.d.ts +2 -1
  51. package/lib/view/invoicing/discountAction/discountActionEpic.js +32 -8
  52. package/lib/view/invoicing/dunningAction/dunningActionEpic.d.ts +2 -1
  53. package/lib/view/invoicing/dunningAction/dunningActionEpic.js +34 -8
  54. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.d.ts +3 -1
  55. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js +5 -1
  56. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.d.ts +2 -1
  57. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +31 -4
  58. package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.d.ts +2 -1
  59. package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +22 -2
  60. package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.d.ts +2 -1
  61. package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +23 -3
  62. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.d.ts +2 -1
  63. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +23 -3
  64. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/syncInvoicingSubscriptionCouponsEpic.d.ts +2 -1
  65. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/syncInvoicingSubscriptionCouponsEpic.js +19 -2
  66. package/lib/view/invoicing/invoiceAction/invoiceActionEpic.d.ts +2 -1
  67. package/lib/view/invoicing/invoiceAction/invoiceActionEpic.js +59 -16
  68. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewPayload.d.ts +13 -0
  69. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.d.ts +1 -1
  70. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.js +30 -0
  71. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.d.ts +11 -31
  72. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.js +4 -29
  73. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewState.d.ts +15 -0
  74. package/lib/view/invoicing/invoicingQboView/epics/invoicingQboViewActionType.d.ts +2 -1
  75. package/lib/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +28 -9
  76. package/lib/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +27 -4
  77. package/lib/view/invoicing/issueCreditNote/issueCreditNoteEpic.d.ts +2 -1
  78. package/lib/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +23 -3
  79. package/lib/view/invoicing/issueCreditNote/issueCreditNoteSelector.d.ts +24 -7
  80. package/lib/view/invoicing/issueCreditNote/issueCreditNoteSelector.js +23 -16
  81. package/lib/view/invoicing/recordPayment/recordPaymentEpic.d.ts +2 -1
  82. package/lib/view/invoicing/recordPayment/recordPaymentEpic.js +45 -6
  83. package/lib/view/invoicing/settingsView/settingsViewEpics.d.ts +2 -1
  84. package/lib/view/invoicing/settingsView/settingsViewEpics.js +25 -7
  85. package/lib/view/invoicing/settingsView/settingsViewReducer.d.ts +10 -1
  86. package/lib/view/invoicing/settingsView/settingsViewReducer.js +1 -1
  87. package/lib/view/invoicing/settingsView/settingsViewSelector.d.ts +4 -2
  88. package/lib/view/invoicing/settingsView/settingsViewSelector.js +4 -1
  89. package/lib/view/invoicing/subscriptionAction/subscriptionActionEpic.d.ts +2 -1
  90. package/lib/view/invoicing/subscriptionAction/subscriptionActionEpic.js +40 -8
  91. package/lib/view/vendorFiling1099/vendorFiling1099UploadDetails/vendorFiling1099UploadDetailsReducer.d.ts +1 -1
  92. package/lib/view/vendorFiling1099/vendorFiling1099UploadDetails/vendorFiling1099UploadDetailsReducer.js +5 -2
  93. package/lib/view/vendorTabView/vendorTabViewReducer.d.ts +1 -1
  94. package/lib/view/vendorTabView/vendorTabViewReducer.js +5 -2
  95. package/package.json +1 -1
  96. package/lib/__testHelpers__/apiFailure.json +0 -6
  97. package/lib/entity/vendor/__mocks__/vendorMock.d.ts +0 -7
  98. package/lib/entity/vendor/__mocks__/vendorMock.js +0 -311
  99. package/lib/entity/vendor/__mocks__/vendorStateMocks.d.ts +0 -8
  100. package/lib/entity/vendor/__mocks__/vendorStateMocks.js +0 -415
  101. package/lib/view/accountMappingView/__mocks__/accountMappingSelectorMock.d.ts +0 -11
  102. package/lib/view/accountMappingView/__mocks__/accountMappingSelectorMock.js +0 -4659
  103. package/lib/view/addressView/__mocks__/addressViewMocks.d.ts +0 -35
  104. package/lib/view/addressView/__mocks__/addressViewMocks.js +0 -239
  105. package/lib/view/addressView/__mocks__/json/createAddressResponse.json +0 -23
  106. package/lib/view/addressView/__mocks__/json/createCompanyAddressSuccess.json +0 -258
  107. package/lib/view/addressView/__mocks__/json/createCompanyUserAddressSuccess.json +0 -418
  108. package/lib/view/addressView/__mocks__/json/fetchAddressResponse.json +0 -24
  109. package/lib/view/addressView/__mocks__/json/updateAddressResponse.json +0 -24
@@ -1,10 +1,29 @@
1
- import { of } from 'rxjs';
1
+ import { from } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { updateInvoicingDunningCases } from '../../../entity/invoicing/dunningCase/dunningCaseReducer';
4
+ import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
4
5
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
5
6
  import { runInvoicingDunningAction, runInvoicingDunningActionFailure, runInvoicingDunningActionSuccess, } from './dunningActionReducer';
7
+ /**
8
+ * Snackbar copy is per action kind; anything not listed here runs without one.
9
+ */
10
+ const SNACKBAR_SECTION_BY_KIND = {
11
+ cancel: 'invoicing_dunning_cancel',
12
+ resolve: 'invoicing_dunning_case_resolved',
13
+ retry: 'invoicing_dunning_retry',
14
+ };
6
15
  export const runInvoicingDunningActionEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(runInvoicingDunningAction.match), mergeMap((action) => {
7
16
  const { action: kind, body, id } = action.payload;
17
+ const snackbarSection = SNACKBAR_SECTION_BY_KIND[kind];
18
+ const snackbar = (messageText) => snackbarSection == null
19
+ ? []
20
+ : [
21
+ openSnackbar({
22
+ messageSection: snackbarSection,
23
+ messageText,
24
+ type: messageText === 'success' ? 'success' : 'error',
25
+ }),
26
+ ];
8
27
  const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/dunning/${encodeURIComponent(id)}/${kind}`;
9
28
  return zeniAPI
10
29
  .postAndGetJSON(apiUrl, (body ?? {}))
@@ -13,15 +32,22 @@ export const runInvoicingDunningActionEpic = (actions$, _state$, zeniAPI) => act
13
32
  return [
14
33
  updateInvoicingDunningCases([response.data], 'merge'),
15
34
  runInvoicingDunningActionSuccess({ id }),
35
+ ...snackbar('success'),
16
36
  ];
17
37
  }
18
- return of(runInvoicingDunningActionFailure({
19
- error: response.status,
38
+ return from([
39
+ runInvoicingDunningActionFailure({
40
+ error: response.status,
41
+ id,
42
+ }),
43
+ ...snackbar('failed'),
44
+ ]);
45
+ }), catchError((error) => from([
46
+ runInvoicingDunningActionFailure({
47
+ error: createZeniAPIStatus('Unexpected Error', 'Dunning action REST API call errored out ' +
48
+ JSON.stringify(error)),
20
49
  id,
21
- }));
22
- }), catchError((error) => of(runInvoicingDunningActionFailure({
23
- error: createZeniAPIStatus('Unexpected Error', 'Dunning action REST API call errored out ' +
24
- JSON.stringify(error)),
25
- id,
26
- }))));
50
+ }),
51
+ ...snackbar('failed'),
52
+ ])));
27
53
  }));
@@ -116,17 +116,21 @@ export const catalogDetailEditValuesToSavePayload = (values, itemType = 'plan',
116
116
  export const createSubFamilyFormToPayload = (itemId, itemType, values) => {
117
117
  const name = values.name.trim();
118
118
  const priceCode = trimOrUndefined(values.priceCode) ?? toProductCode(name);
119
+ const tiered = isTieredCatalogPricingModel(values.pricingModel);
119
120
  const payload = {
120
121
  currency_code: 'USD',
121
122
  free_quantity: Number(values.freeQuantity) || 0,
122
123
  is_taxable: true,
123
124
  item_id: itemId,
124
125
  name,
125
- price: values.priceDollars?.amount ?? 0,
126
+ price: tiered ? 0 : (values.priceDollars?.amount ?? 0),
126
127
  price_code: priceCode,
127
128
  pricing_model: values.pricingModel || 'flat_fee',
128
129
  show_description_in_invoices: true,
129
130
  };
131
+ if (tiered) {
132
+ payload.tiers = (values.tiers ?? []).map(tierToPayload);
133
+ }
130
134
  const description = trimOrUndefined(values.description);
131
135
  if (description != null) {
132
136
  payload.description = description;
@@ -1,7 +1,8 @@
1
- import { forkJoin, of } from 'rxjs';
1
+ import { forkJoin, from } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { mergeInvoicingPlanSubFamily, updateInvoicingPlans, } from '../../../entity/invoicing/plan/planReducer';
4
4
  import { updateInvoicingProducts } from '../../../entity/invoicing/product/productReducer';
5
+ import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
5
6
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
6
7
  import { addInvoicingCatalogItem } from '../invoicingCatalogListView/invoicingCatalogListViewReducer';
7
8
  import { localDataToSaveInvoicingCatalogItemPayload, } from './editInvoicingCatalogItemDetailViewPayload';
@@ -38,7 +39,14 @@ export const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actio
38
39
  const failedProductResponse = productResponses.find((productResponse) => !isSuccessResponse(productResponse) ||
39
40
  productResponse.data == null);
40
41
  if (failedProductResponse != null) {
41
- return of(submitInvoicingCatalogItemFormFailure(failedProductResponse.status));
42
+ return from([
43
+ submitInvoicingCatalogItemFormFailure(failedProductResponse.status),
44
+ openSnackbar({
45
+ messageSection: 'invoicing_catalog_item_saved',
46
+ messageText: 'failed',
47
+ type: 'error',
48
+ }),
49
+ ]);
42
50
  }
43
51
  const savedProducts = productResponses.flatMap((productResponse) => productResponse.data != null ? [productResponse.data] : []);
44
52
  const resultActions = [
@@ -65,6 +73,11 @@ export const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actio
65
73
  : 'plan';
66
74
  resultActions.push(addInvoicingCatalogItem({ id: savedItem.id, type: itemType }));
67
75
  }
76
+ resultActions.push(openSnackbar({
77
+ messageSection: 'invoicing_catalog_item_saved',
78
+ messageText: 'success',
79
+ type: 'success',
80
+ }));
68
81
  return resultActions;
69
82
  };
70
83
  const productUpdates = saveInvoicingCatalogItem.match(action)
@@ -75,7 +88,21 @@ export const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actio
75
88
  }
76
89
  return forkJoin(productUpdates.map((productUpdate) => zeniAPI.putAndGetJSON(`${baseUrl}/catalog/products/${encodeURIComponent(productUpdate.id)}`, productUpdate.data))).pipe(mergeMap(completeSave));
77
90
  }
78
- return of(submitInvoicingCatalogItemFormFailure(response.status));
79
- }), catchError((error) => of(submitInvoicingCatalogItemFormFailure(createZeniAPIStatus('Unexpected Error', 'Save catalog item REST API call errored out ' +
80
- JSON.stringify(error))))));
91
+ return from([
92
+ submitInvoicingCatalogItemFormFailure(response.status),
93
+ openSnackbar({
94
+ messageSection: 'invoicing_catalog_item_saved',
95
+ messageText: 'failed',
96
+ type: 'error',
97
+ }),
98
+ ]);
99
+ }), catchError((error) => from([
100
+ submitInvoicingCatalogItemFormFailure(createZeniAPIStatus('Unexpected Error', 'Save catalog item REST API call errored out ' +
101
+ JSON.stringify(error))),
102
+ openSnackbar({
103
+ messageSection: 'invoicing_catalog_item_saved',
104
+ messageText: 'failed',
105
+ type: 'error',
106
+ }),
107
+ ])));
81
108
  }));
@@ -1,6 +1,7 @@
1
- import { of } from 'rxjs';
1
+ import { from } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { updateInvoicingCoupons } from '../../../entity/invoicing/coupon/couponReducer';
4
+ import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
4
5
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
5
6
  import { addInvoicingCouponToList } from '../couponView/couponViewReducer';
6
7
  import { localDataToSaveInvoicingCouponPayload, } from './editInvoicingCouponDetailViewPayload';
@@ -43,8 +44,27 @@ export const saveInvoicingCouponEpic = (actions$, state$, zeniAPI) => actions$.p
43
44
  status: couponPayload.status,
44
45
  }));
45
46
  }
47
+ resultActions.push(openSnackbar({
48
+ messageSection: 'invoicing_coupon_saved',
49
+ messageText: 'success',
50
+ type: 'success',
51
+ }));
46
52
  return resultActions;
47
53
  }
48
- return of(submitInvoicingCouponFormFailure(response.status));
49
- }), catchError((error) => of(submitInvoicingCouponFormFailure(createZeniAPIStatus('Unexpected Error', 'Save coupon REST API call errored out ' + JSON.stringify(error))))));
54
+ return from([
55
+ submitInvoicingCouponFormFailure(response.status),
56
+ openSnackbar({
57
+ messageSection: 'invoicing_coupon_saved',
58
+ messageText: 'failed',
59
+ type: 'error',
60
+ }),
61
+ ]);
62
+ }), catchError((error) => from([
63
+ submitInvoicingCouponFormFailure(createZeniAPIStatus('Unexpected Error', 'Save coupon REST API call errored out ' + JSON.stringify(error))),
64
+ openSnackbar({
65
+ messageSection: 'invoicing_coupon_saved',
66
+ messageText: 'failed',
67
+ type: 'error',
68
+ }),
69
+ ])));
50
70
  }));
@@ -1,8 +1,9 @@
1
- import { of } from 'rxjs';
1
+ import { from } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { updateAddresses } from '../../../entity/address/addressReducer';
4
4
  import { extractInvoicingCustomerAddresses } from '../../../entity/invoicing/invoicingCustomer/invoicingCustomerPayload';
5
5
  import { updateInvoicingCustomers } from '../../../entity/invoicing/invoicingCustomer/invoicingCustomerReducer';
6
+ import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
6
7
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
7
8
  import { resetNewAddressDataInLocalStore } from '../../addressView/addressViewReducer';
8
9
  import { addInvoicingCustomerToList } from '../invoicingCustomerListView/invoicingCustomerListViewReducer';
@@ -45,9 +46,28 @@ export const saveInvoicingCustomerEpic = (actions$, state$, zeniAPI) => actions$
45
46
  status: response.data.status,
46
47
  }));
47
48
  }
49
+ resultActions.push(openSnackbar({
50
+ messageSection: 'invoicing_customer_saved',
51
+ messageText: 'success',
52
+ type: 'success',
53
+ }));
48
54
  return resultActions;
49
55
  }
50
- return of(submitInvoicingCustomerFormFailure(response.status));
51
- }), catchError((error) => of(submitInvoicingCustomerFormFailure(createZeniAPIStatus('Unexpected Error', 'Save customer REST API call errored out ' +
52
- JSON.stringify(error))))));
56
+ return from([
57
+ submitInvoicingCustomerFormFailure(response.status),
58
+ openSnackbar({
59
+ messageSection: 'invoicing_customer_saved',
60
+ messageText: 'failed',
61
+ type: 'error',
62
+ }),
63
+ ]);
64
+ }), catchError((error) => from([
65
+ submitInvoicingCustomerFormFailure(createZeniAPIStatus('Unexpected Error', 'Save customer REST API call errored out ' +
66
+ JSON.stringify(error))),
67
+ openSnackbar({
68
+ messageSection: 'invoicing_customer_saved',
69
+ messageText: 'failed',
70
+ type: 'error',
71
+ }),
72
+ ])));
53
73
  }));
@@ -1,8 +1,9 @@
1
- import { of } from 'rxjs';
1
+ import { from } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { updateAddresses } from '../../../entity/address/addressReducer';
4
4
  import { extractInvoicingSubscriptionAddresses } from '../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload';
5
5
  import { updateInvoicingSubscriptions } from '../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionReducer';
6
+ import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
6
7
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
7
8
  import { resetNewAddressDataInLocalStore } from '../../addressView/addressViewReducer';
8
9
  import { addInvoicingSubscriptionToList } from '../invoicingSubscriptionListView/invoicingSubscriptionListViewReducer';
@@ -38,7 +39,14 @@ export const saveInvoicingSubscriptionEpic = (actions$, state$, zeniAPI) => acti
38
39
  : zeniAPI.postAndGetJSON(`${baseUrl}/subscriptions`, { ...data });
39
40
  return request$.pipe(mergeMap((response) => {
40
41
  if (!isSuccessResponse(response) || response.data == null) {
41
- return [submitInvoicingSubscriptionFormFailure(response.status)];
42
+ return [
43
+ submitInvoicingSubscriptionFormFailure(response.status),
44
+ openSnackbar({
45
+ messageSection: 'invoicing_subscription_saved',
46
+ messageText: 'failed',
47
+ type: 'error',
48
+ }),
49
+ ];
42
50
  }
43
51
  const saved = response.data;
44
52
  const couponChanged = id != null &&
@@ -78,7 +86,19 @@ export const saveInvoicingSubscriptionEpic = (actions$, state$, zeniAPI) => acti
78
86
  status: saved.status,
79
87
  }));
80
88
  }
89
+ resultActions.push(openSnackbar({
90
+ messageSection: 'invoicing_subscription_saved',
91
+ messageText: 'success',
92
+ type: 'success',
93
+ }));
81
94
  return resultActions;
82
- }), catchError((error) => of(submitInvoicingSubscriptionFormFailure(createZeniAPIStatus('Unexpected Error', 'Save subscription REST API call errored out ' +
83
- JSON.stringify(error))))));
95
+ }), catchError((error) => from([
96
+ submitInvoicingSubscriptionFormFailure(createZeniAPIStatus('Unexpected Error', 'Save subscription REST API call errored out ' +
97
+ JSON.stringify(error))),
98
+ openSnackbar({
99
+ messageSection: 'invoicing_subscription_saved',
100
+ messageText: 'failed',
101
+ type: 'error',
102
+ }),
103
+ ])));
84
104
  }));
@@ -1,8 +1,9 @@
1
- import { EMPTY, of } from 'rxjs';
1
+ import { EMPTY, from, of } from 'rxjs';
2
2
  import { catchError, filter, map, mergeMap } from 'rxjs/operators';
3
3
  import { updateAddresses } from '../../../entity/address/addressReducer';
4
4
  import { extractInvoicingSubscriptionAddresses, } from '../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload';
5
5
  import { updateInvoicingSubscriptions } from '../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionReducer';
6
+ import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
6
7
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../responsePayload';
7
8
  import { resetNewAddressDataInLocalStore } from '../../addressView/addressViewReducer';
8
9
  import { submitInvoicingSubscriptionFormFailure, submitInvoicingSubscriptionFormSuccess, syncInvoicingSubscriptionCoupons, } from './editInvoicingSubscriptionDetailViewReducer';
@@ -39,7 +40,14 @@ export const syncInvoicingSubscriptionCouponsEpic = (actions$, _state$, zeniAPI)
39
40
  : couponMutation$(zeniAPI, baseUrl, subscriptionId, 'remove-coupon', prev);
40
41
  return removeStep$.pipe(mergeMap((removeResult) => {
41
42
  if (!removeResult.success) {
42
- return of(submitInvoicingSubscriptionFormFailure(failureStatus(removeResult)));
43
+ return from([
44
+ submitInvoicingSubscriptionFormFailure(failureStatus(removeResult)),
45
+ openSnackbar({
46
+ messageSection: 'invoicing_subscription_saved',
47
+ messageText: 'failed',
48
+ type: 'error',
49
+ }),
50
+ ]);
43
51
  }
44
52
  const applyStep$ = next === ''
45
53
  ? of({
@@ -51,6 +59,11 @@ export const syncInvoicingSubscriptionCouponsEpic = (actions$, _state$, zeniAPI)
51
59
  if (!applyResult.success) {
52
60
  return [
53
61
  submitInvoicingSubscriptionFormFailure(failureStatus(applyResult)),
62
+ openSnackbar({
63
+ messageSection: 'invoicing_subscription_saved',
64
+ messageText: 'failed',
65
+ type: 'error',
66
+ }),
54
67
  ];
55
68
  }
56
69
  const couponUpdated = applyResult.payload ?? removeResult.payload;
@@ -58,7 +71,11 @@ export const syncInvoicingSubscriptionCouponsEpic = (actions$, _state$, zeniAPI)
58
71
  if (couponUpdated != null) {
59
72
  resultActions.push(updateInvoicingSubscriptions([couponUpdated], 'merge'), updateAddresses(extractInvoicingSubscriptionAddresses([couponUpdated])));
60
73
  }
61
- resultActions.push(submitInvoicingSubscriptionFormSuccess({ subscriptionId }), resetNewAddressDataInLocalStore(INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE));
74
+ resultActions.push(submitInvoicingSubscriptionFormSuccess({ subscriptionId }), resetNewAddressDataInLocalStore(INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE), openSnackbar({
75
+ messageSection: 'invoicing_subscription_saved',
76
+ messageText: 'success',
77
+ type: 'success',
78
+ }));
62
79
  return resultActions;
63
80
  }));
64
81
  }));
@@ -1,13 +1,30 @@
1
- import { of } from 'rxjs';
1
+ import { from } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { updateAddresses } from '../../../entity/address/addressReducer';
4
4
  import { extractInvoicingInvoiceAddresses } from '../../../entity/invoicing/invoice/invoicePayload';
5
5
  import { updateInvoices } from '../../../entity/invoicing/invoice/invoiceReducer';
6
+ import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
6
7
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
7
8
  import { runInvoicingInvoiceAction, runInvoicingInvoiceActionFailure, runInvoicingInvoiceActionSuccess, updateInvoicingInvoice, } from './invoiceActionReducer';
9
+ /** Snackbar copy per action kind; unlisted kinds run without one. */
10
+ const SNACKBAR_SECTION_BY_KIND = {
11
+ regenerate: 'invoicing_invoice_regenerated',
12
+ 'send-reminder': 'invoicing_invoice_reminder_sent',
13
+ void: 'invoicing_invoice_voided',
14
+ };
8
15
  export const runInvoicingInvoiceActionEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter((action) => runInvoicingInvoiceAction.match(action) &&
9
16
  action.payload.action !== 'issue-credit-note'), mergeMap((action) => {
10
17
  const { action: kind, body, invoiceId } = action.payload;
18
+ const snackbarSection = SNACKBAR_SECTION_BY_KIND[kind];
19
+ const snackbar = (messageText) => snackbarSection == null
20
+ ? []
21
+ : [
22
+ openSnackbar({
23
+ messageSection: snackbarSection,
24
+ messageText,
25
+ type: messageText === 'success' ? 'success' : 'error',
26
+ }),
27
+ ];
11
28
  const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/invoices/${encodeURIComponent(invoiceId)}/${kind}`;
12
29
  return zeniAPI
13
30
  .postAndGetJSON(apiUrl, (body ?? {}))
@@ -17,17 +34,24 @@ export const runInvoicingInvoiceActionEpic = (actions$, _state$, zeniAPI) => act
17
34
  updateInvoices([response.data], 'merge'),
18
35
  updateAddresses(extractInvoicingInvoiceAddresses([response.data])),
19
36
  runInvoicingInvoiceActionSuccess({ invoiceId }),
37
+ ...snackbar('success'),
20
38
  ];
21
39
  }
22
- return of(runInvoicingInvoiceActionFailure({
23
- error: response.status,
40
+ return from([
41
+ runInvoicingInvoiceActionFailure({
42
+ error: response.status,
43
+ invoiceId,
44
+ }),
45
+ ...snackbar('failed'),
46
+ ]);
47
+ }), catchError((error) => from([
48
+ runInvoicingInvoiceActionFailure({
49
+ error: createZeniAPIStatus('Unexpected Error', 'Invoice action REST API call errored out ' +
50
+ JSON.stringify(error)),
24
51
  invoiceId,
25
- }));
26
- }), catchError((error) => of(runInvoicingInvoiceActionFailure({
27
- error: createZeniAPIStatus('Unexpected Error', 'Invoice action REST API call errored out ' +
28
- JSON.stringify(error)),
29
- invoiceId,
30
- }))));
52
+ }),
53
+ ...snackbar('failed'),
54
+ ])));
31
55
  }));
32
56
  export const updateInvoicingInvoiceEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(updateInvoicingInvoice.match), mergeMap((action) => {
33
57
  const { data, invoiceId } = action.payload;
@@ -40,15 +64,34 @@ export const updateInvoicingInvoiceEpic = (actions$, _state$, zeniAPI) => action
40
64
  updateInvoices([response.data], 'merge'),
41
65
  updateAddresses(extractInvoicingInvoiceAddresses([response.data])),
42
66
  runInvoicingInvoiceActionSuccess({ invoiceId }),
67
+ openSnackbar({
68
+ messageSection: 'invoicing_invoice_saved',
69
+ messageText: 'success',
70
+ type: 'success',
71
+ }),
43
72
  ];
44
73
  }
45
- return of(runInvoicingInvoiceActionFailure({
46
- error: response.status,
74
+ return from([
75
+ runInvoicingInvoiceActionFailure({
76
+ error: response.status,
77
+ invoiceId,
78
+ }),
79
+ openSnackbar({
80
+ messageSection: 'invoicing_invoice_saved',
81
+ messageText: 'failed',
82
+ type: 'error',
83
+ }),
84
+ ]);
85
+ }), catchError((error) => from([
86
+ runInvoicingInvoiceActionFailure({
87
+ error: createZeniAPIStatus('Unexpected Error', 'Invoice update REST API call errored out ' +
88
+ JSON.stringify(error)),
47
89
  invoiceId,
48
- }));
49
- }), catchError((error) => of(runInvoicingInvoiceActionFailure({
50
- error: createZeniAPIStatus('Unexpected Error', 'Invoice update REST API call errored out ' +
51
- JSON.stringify(error)),
52
- invoiceId,
53
- }))));
90
+ }),
91
+ openSnackbar({
92
+ messageSection: 'invoicing_invoice_saved',
93
+ messageText: 'failed',
94
+ type: 'error',
95
+ }),
96
+ ])));
54
97
  }));
@@ -8,7 +8,20 @@ export const initialState = {
8
8
  auditLogEntityRouteOptions: [],
9
9
  auditLogListSortFieldOptions: [],
10
10
  auditLogSourceLabels: [],
11
+ autoCollectionOptions: [],
12
+ billingPeriodUnitOptions: [],
13
+ catalogTrialEndActionOptions: [],
14
+ catalogTrialUnitOptions: [],
15
+ customerTypeOptions: [],
16
+ dateFormatOptions: [],
17
+ discountApplyOnOptions: [],
18
+ discountDurationTypeOptions: [],
19
+ discountTypeOptions: [],
11
20
  dunningScheduleActionOptions: [],
21
+ manualPaymentMethodOptions: [],
22
+ netTermDayOptions: [],
23
+ paymentGatewayOptions: [],
24
+ taxabilityOptions: [],
12
25
  enableFetchState: { fetchState: 'Not-Started', error: undefined },
13
26
  subscriptionLifecycleActionOptions: [],
14
27
  subscriptionCommercialEditAllowedFromStatuses: [],
@@ -29,6 +42,8 @@ export const initialState = {
29
42
  invoicingTosAcceptanceUserAgent: undefined,
30
43
  invoicingTosAcceptanceUserId: undefined,
31
44
  isInvoicingSettingsSeeded: undefined,
45
+ createdAt: undefined,
46
+ updatedAt: undefined,
32
47
  hasValidState() {
33
48
  return (this.fetchState === 'Completed' && this.isInvoicingTosAccepted != null);
34
49
  },
@@ -44,6 +59,21 @@ export function mapInvoicingConfigPayloadToState(payload) {
44
59
  code: option.code,
45
60
  name: option.name,
46
61
  })),
62
+ autoCollectionOptions: (payload.auto_collection_options ?? []).map(toInvoicingNamedOption),
63
+ billingPeriodUnitOptions: (payload.billing_period_unit_options ?? []).map(toInvoicingNamedOption),
64
+ catalogTrialEndActionOptions: (payload.catalog_trial_end_action_options ?? []).map(toInvoicingNamedOption),
65
+ catalogTrialUnitOptions: (payload.catalog_trial_unit_options ?? []).map(toInvoicingNamedOption),
66
+ customerTypeOptions: (payload.customer_type_options ?? []).map(toInvoicingNamedOption),
67
+ dateFormatOptions: (payload.date_format_options ?? []).map(toInvoicingNamedOption),
68
+ discountApplyOnOptions: (payload.discount_apply_on_options ?? []).map(toInvoicingNamedOption),
69
+ discountDurationTypeOptions: (payload.discount_duration_type_options ?? []).map(toInvoicingNamedOption),
70
+ discountTypeOptions: (payload.discount_type_options ?? []).map(toInvoicingNamedOption),
71
+ manualPaymentMethodOptions: (payload.manual_payment_method_options ?? []).map(toInvoicingNamedOption),
72
+ netTermDayOptions: (payload.net_term_day_options ?? []).map(toInvoicingNamedOption),
73
+ paymentGatewayOptions: (payload.payment_gateway_options ?? []).map(toInvoicingNamedOption),
74
+ taxabilityOptions: (payload.taxability_options ?? []).map(toInvoicingNamedOption),
75
+ createdAt: payload.created_at ?? undefined,
76
+ updatedAt: payload.updated_at ?? undefined,
47
77
  dunningScheduleActionOptions: payload.dunning_schedule_action_options.map((option) => ({
48
78
  code: toInvoicingDunningAction(option.code),
49
79
  name: option.name,
@@ -1,35 +1,10 @@
1
1
  import { deriveInvoicingOnboardingStatus, } from './invoicingConfigViewPayload';
2
- /**
3
- * Single bundled view for the invoicing config — consumers read only this.
4
- * Carries the config flags, the derived onboarding `status` used for route
5
- * gating, the config fetch (`fetchState`/`error`), and the accept-terms /
6
- * enable action fetch states.
7
- */
8
2
  export const getInvoicingConfigView = (state) => {
9
- const configState = state.invoicingConfigViewState;
3
+ const { acceptTermsFetchState, enableFetchState, ...configState } = state.invoicingConfigViewState;
10
4
  return {
11
- acceptTermsState: configState.acceptTermsFetchState,
12
- auditLogEntityRouteOptions: configState.auditLogEntityRouteOptions,
13
- auditLogListSortFieldOptions: configState.auditLogListSortFieldOptions,
14
- auditLogSourceLabels: configState.auditLogSourceLabels,
15
- dunningScheduleActionOptions: configState.dunningScheduleActionOptions,
16
- enableState: configState.enableFetchState,
17
- subscriptionLifecycleActionOptions: configState.subscriptionLifecycleActionOptions,
18
- subscriptionCommercialEditAllowedFromStatuses: configState.subscriptionCommercialEditAllowedFromStatuses,
19
- subscriptionMetadataEditAllowedFromStatuses: configState.subscriptionMetadataEditAllowedFromStatuses,
20
- subscriptionEditFieldOptions: configState.subscriptionEditFieldOptions,
21
- subscriptionCancelTimingOptions: configState.subscriptionCancelTimingOptions,
22
- subscriptionChangeOptionOptions: configState.subscriptionChangeOptionOptions,
23
- catalogItemLifecycleActionOptions: configState.catalogItemLifecycleActionOptions,
24
- catalogProductLifecycleActionOptions: configState.catalogProductLifecycleActionOptions,
25
- discountLifecycleActionOptions: configState.discountLifecycleActionOptions,
26
- qboAccountMappingKindOptions: configState.qboAccountMappingKindOptions,
27
- qboCustomerMatchingOptions: configState.qboCustomerMatchingOptions,
28
- qboSyncStatusOptions: configState.qboSyncStatusOptions,
29
- error: configState.error,
30
- fetchState: configState.fetchState,
31
- isInvoicingEnabled: configState.isInvoicingEnabled,
32
- isInvoicingTosAccepted: configState.isInvoicingTosAccepted,
5
+ ...configState,
6
+ acceptTermsState: acceptTermsFetchState,
7
+ enableState: enableFetchState,
33
8
  status: deriveInvoicingOnboardingStatus(configState.isInvoicingTosAccepted, configState.isInvoicingEnabled),
34
9
  };
35
10
  };
@@ -1,5 +1,6 @@
1
- import { of } from 'rxjs';
1
+ import { from, of } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
+ import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
3
4
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
4
5
  import { fetchInvoicingQboSyncHealth, retryInvoicingQboSyncTask, retryInvoicingQboSyncTaskFailure, retryInvoicingQboSyncTaskSuccess, } from '../invoicingQboViewReducer';
5
6
  export const retryInvoicingQboSyncTaskEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(retryInvoicingQboSyncTask.match), mergeMap((action) => {
@@ -12,15 +13,33 @@ export const retryInvoicingQboSyncTaskEpic = (actions$, _state$, zeniAPI) => act
12
13
  return of(retryInvoicingQboSyncTaskSuccess({
13
14
  status: response.data?.status ?? '',
14
15
  taskId: response.data?.task_id ?? taskId,
15
- }), fetchInvoicingQboSyncHealth());
16
+ }), fetchInvoicingQboSyncHealth(), openSnackbar({
17
+ messageSection: 'invoicing_qbo_sync_health_retry',
18
+ messageText: 'success',
19
+ type: 'success',
20
+ }));
16
21
  }
17
- return of(retryInvoicingQboSyncTaskFailure({
18
- status: response.status,
22
+ return from([
23
+ retryInvoicingQboSyncTaskFailure({
24
+ status: response.status,
25
+ taskId,
26
+ }),
27
+ openSnackbar({
28
+ messageSection: 'invoicing_qbo_sync_health_retry',
29
+ messageText: 'failed',
30
+ type: 'error',
31
+ }),
32
+ ]);
33
+ }), catchError((error) => from([
34
+ retryInvoicingQboSyncTaskFailure({
35
+ status: createZeniAPIStatus('Unexpected Error', 'Retry QBO sync task REST API call errored out ' +
36
+ JSON.stringify(error)),
19
37
  taskId,
20
- }));
21
- }), catchError((error) => of(retryInvoicingQboSyncTaskFailure({
22
- status: createZeniAPIStatus('Unexpected Error', 'Retry QBO sync task REST API call errored out ' +
23
- JSON.stringify(error)),
24
- taskId,
25
- }))));
38
+ }),
39
+ openSnackbar({
40
+ messageSection: 'invoicing_qbo_sync_health_retry',
41
+ messageText: 'failed',
42
+ type: 'error',
43
+ }),
44
+ ])));
26
45
  }));
@@ -1,5 +1,6 @@
1
- import { of } from 'rxjs';
1
+ import { from } from 'rxjs';
2
2
  import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
3
+ import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
3
4
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
4
5
  import { fetchInvoicingQboSyncHealth, startInvoicingQboBackfill, startInvoicingQboBackfillFailure, startInvoicingQboBackfillSuccess, } from '../invoicingQboViewReducer';
5
6
  export const startInvoicingQboBackfillEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(startInvoicingQboBackfill.match), switchMap((action) => {
@@ -10,9 +11,31 @@ export const startInvoicingQboBackfillEpic = (actions$, _state$, zeniAPI) => act
10
11
  })
11
12
  .pipe(mergeMap((response) => {
12
13
  if (isSuccessResponse(response)) {
13
- return of(startInvoicingQboBackfillSuccess(), fetchInvoicingQboSyncHealth());
14
+ return from([
15
+ startInvoicingQboBackfillSuccess(),
16
+ fetchInvoicingQboSyncHealth(),
17
+ openSnackbar({
18
+ messageSection: 'invoicing_qbo_backfill',
19
+ messageText: 'success',
20
+ type: 'success',
21
+ }),
22
+ ]);
14
23
  }
15
- return of(startInvoicingQboBackfillFailure(response.status));
16
- }), catchError((error) => of(startInvoicingQboBackfillFailure(createZeniAPIStatus('Unexpected Error', 'Start QBO backfill REST API call errored out ' +
17
- JSON.stringify(error))))));
24
+ return from([
25
+ startInvoicingQboBackfillFailure(response.status),
26
+ openSnackbar({
27
+ messageSection: 'invoicing_qbo_backfill',
28
+ messageText: 'failed',
29
+ type: 'error',
30
+ }),
31
+ ]);
32
+ }), catchError((error) => from([
33
+ startInvoicingQboBackfillFailure(createZeniAPIStatus('Unexpected Error', 'Start QBO backfill REST API call errored out ' +
34
+ JSON.stringify(error))),
35
+ openSnackbar({
36
+ messageSection: 'invoicing_qbo_backfill',
37
+ messageText: 'failed',
38
+ type: 'error',
39
+ }),
40
+ ])));
18
41
  }));