@zeniai/client-epic-state 5.1.90 → 5.1.91

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 (145) 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/company/companyPayload.d.ts +4 -0
  6. package/lib/entity/company/companyPayload.js +18 -8
  7. package/lib/entity/company/companyStateTypes.d.ts +4 -0
  8. package/lib/entity/customerSatisfaction/customerSatisfactionReducer.d.ts +1 -1
  9. package/lib/entity/customerSatisfaction/customerSatisfactionReducer.js +6 -2
  10. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  11. package/lib/entity/snackbar/snackbarTypes.js +31 -0
  12. package/lib/entity/tenant/tenantPayload.d.ts +1 -0
  13. package/lib/entity/tenant/tenantReducer.d.ts +5 -1
  14. package/lib/entity/tenant/tenantReducer.js +22 -2
  15. package/lib/entity/tenant/tenantSelector.d.ts +2 -0
  16. package/lib/entity/tenant/tenantSelector.js +11 -1
  17. package/lib/entity/tenant/tenantState.d.ts +1 -0
  18. package/lib/epic.d.ts +3 -1
  19. package/lib/epic.js +5 -1
  20. package/lib/esm/entity/aiCfo/aiCfoReducer.js +23 -1
  21. package/lib/esm/entity/company/companyPayload.js +18 -8
  22. package/lib/esm/entity/customerSatisfaction/customerSatisfactionReducer.js +4 -1
  23. package/lib/esm/entity/snackbar/snackbarTypes.js +31 -0
  24. package/lib/esm/entity/tenant/tenantReducer.js +21 -1
  25. package/lib/esm/entity/tenant/tenantSelector.js +9 -0
  26. package/lib/esm/epic.js +5 -1
  27. package/lib/esm/index.js +10 -9
  28. package/lib/esm/view/companyHealthMetricView/companyHealthMetricConfigReducer.js +4 -1
  29. package/lib/esm/view/companyView/companyViewReducer.js +58 -1
  30. package/lib/esm/view/companyView/epic/updateCompanyProductServicesEpic.js +91 -0
  31. package/lib/esm/view/companyView/epic/updateCompanyQboRealmIdEpic.js +58 -0
  32. package/lib/esm/view/companyView/selector/companyManagementViewSelector.js +52 -0
  33. package/lib/esm/view/companyView/types/cockpitTypes.js +13 -1
  34. package/lib/esm/view/companyView/types/companyManagementViewState.js +2 -0
  35. package/lib/esm/view/invoicing/createCreditNote/createCreditNoteEpic.js +24 -4
  36. package/lib/esm/view/invoicing/createInvoice/createInvoiceEpic.js +24 -4
  37. package/lib/esm/view/invoicing/createInvoice/createInvoiceSelector.js +37 -10
  38. package/lib/esm/view/invoicing/discountAction/discountActionEpic.js +33 -9
  39. package/lib/esm/view/invoicing/dunningAction/dunningActionEpic.js +35 -9
  40. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js +5 -1
  41. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +32 -5
  42. package/lib/esm/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +23 -3
  43. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +24 -4
  44. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +24 -4
  45. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/syncInvoicingSubscriptionCouponsEpic.js +20 -3
  46. package/lib/esm/view/invoicing/invoiceAction/invoiceActionEpic.js +60 -17
  47. package/lib/esm/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.js +30 -0
  48. package/lib/esm/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.js +4 -29
  49. package/lib/esm/view/invoicing/invoicingDunningCaseDetailView/fetchInvoicingDunningEmailPreviewEpic.js +26 -0
  50. package/lib/esm/view/invoicing/invoicingDunningCaseDetailView/fetchInvoicingDunningEmailPreviewPageEpic.js +16 -0
  51. package/lib/esm/view/invoicing/invoicingDunningCaseDetailView/invoicingDunningCaseDetailViewPayload.js +9 -1
  52. package/lib/esm/view/invoicing/invoicingDunningCaseDetailView/invoicingDunningCaseDetailViewReducer.js +50 -1
  53. package/lib/esm/view/invoicing/invoicingDunningCaseDetailView/invoicingDunningCaseDetailViewSelector.js +14 -1
  54. package/lib/esm/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +29 -10
  55. package/lib/esm/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +28 -5
  56. package/lib/esm/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +24 -4
  57. package/lib/esm/view/invoicing/issueCreditNote/issueCreditNoteSelector.js +22 -14
  58. package/lib/esm/view/invoicing/recordPayment/recordPaymentEpic.js +46 -7
  59. package/lib/esm/view/invoicing/settingsView/settingsViewEpics.js +26 -8
  60. package/lib/esm/view/invoicing/settingsView/settingsViewReducer.js +1 -1
  61. package/lib/esm/view/invoicing/settingsView/settingsViewSelector.js +4 -1
  62. package/lib/esm/view/invoicing/subscriptionAction/subscriptionActionEpic.js +41 -9
  63. package/lib/esm/view/vendorFiling1099/vendorFiling1099UploadDetails/vendorFiling1099UploadDetailsReducer.js +4 -1
  64. package/lib/esm/view/vendorTabView/vendorTabViewReducer.js +4 -1
  65. package/lib/index.d.ts +16 -12
  66. package/lib/index.js +63 -50
  67. package/lib/view/companyHealthMetricView/companyHealthMetricConfigReducer.d.ts +1 -1
  68. package/lib/view/companyHealthMetricView/companyHealthMetricConfigReducer.js +5 -2
  69. package/lib/view/companyView/companyViewReducer.d.ts +22 -1
  70. package/lib/view/companyView/companyViewReducer.js +60 -3
  71. package/lib/view/companyView/epic/updateCompanyProductServicesEpic.d.ts +10 -0
  72. package/lib/view/companyView/epic/updateCompanyProductServicesEpic.js +95 -0
  73. package/lib/view/companyView/epic/updateCompanyQboRealmIdEpic.d.ts +8 -0
  74. package/lib/view/companyView/epic/updateCompanyQboRealmIdEpic.js +62 -0
  75. package/lib/view/companyView/selector/companyManagementViewSelector.d.ts +3 -0
  76. package/lib/view/companyView/selector/companyManagementViewSelector.js +55 -0
  77. package/lib/view/companyView/types/cockpitTypes.d.ts +7 -3
  78. package/lib/view/companyView/types/cockpitTypes.js +15 -1
  79. package/lib/view/companyView/types/companyManagementViewState.d.ts +2 -0
  80. package/lib/view/companyView/types/companyManagementViewState.js +2 -0
  81. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  82. package/lib/view/invoicing/createCreditNote/createCreditNoteEpic.d.ts +2 -1
  83. package/lib/view/invoicing/createCreditNote/createCreditNoteEpic.js +23 -3
  84. package/lib/view/invoicing/createInvoice/createInvoiceEpic.d.ts +2 -1
  85. package/lib/view/invoicing/createInvoice/createInvoiceEpic.js +23 -3
  86. package/lib/view/invoicing/createInvoice/createInvoiceSelector.d.ts +22 -8
  87. package/lib/view/invoicing/createInvoice/createInvoiceSelector.js +37 -10
  88. package/lib/view/invoicing/discountAction/discountActionEpic.d.ts +2 -1
  89. package/lib/view/invoicing/discountAction/discountActionEpic.js +32 -8
  90. package/lib/view/invoicing/dunningAction/dunningActionEpic.d.ts +2 -1
  91. package/lib/view/invoicing/dunningAction/dunningActionEpic.js +34 -8
  92. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.d.ts +3 -1
  93. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js +5 -1
  94. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.d.ts +2 -1
  95. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +31 -4
  96. package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.d.ts +2 -1
  97. package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +22 -2
  98. package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.d.ts +2 -1
  99. package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +23 -3
  100. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.d.ts +2 -1
  101. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +23 -3
  102. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/syncInvoicingSubscriptionCouponsEpic.d.ts +2 -1
  103. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/syncInvoicingSubscriptionCouponsEpic.js +19 -2
  104. package/lib/view/invoicing/invoiceAction/invoiceActionEpic.d.ts +2 -1
  105. package/lib/view/invoicing/invoiceAction/invoiceActionEpic.js +59 -16
  106. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewPayload.d.ts +13 -0
  107. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.d.ts +1 -1
  108. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.js +30 -0
  109. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.d.ts +11 -31
  110. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.js +4 -29
  111. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewState.d.ts +15 -0
  112. package/lib/view/invoicing/invoicingDunningCaseDetailView/fetchInvoicingDunningEmailPreviewEpic.d.ts +7 -0
  113. package/lib/view/invoicing/invoicingDunningCaseDetailView/fetchInvoicingDunningEmailPreviewEpic.js +30 -0
  114. package/lib/view/invoicing/invoicingDunningCaseDetailView/fetchInvoicingDunningEmailPreviewPageEpic.d.ts +6 -0
  115. package/lib/view/invoicing/invoicingDunningCaseDetailView/fetchInvoicingDunningEmailPreviewPageEpic.js +20 -0
  116. package/lib/view/invoicing/invoicingDunningCaseDetailView/invoicingDunningCaseDetailViewEpics.d.ts +2 -2
  117. package/lib/view/invoicing/invoicingDunningCaseDetailView/invoicingDunningCaseDetailViewPayload.d.ts +12 -0
  118. package/lib/view/invoicing/invoicingDunningCaseDetailView/invoicingDunningCaseDetailViewPayload.js +11 -0
  119. package/lib/view/invoicing/invoicingDunningCaseDetailView/invoicingDunningCaseDetailViewReducer.d.ts +21 -4
  120. package/lib/view/invoicing/invoicingDunningCaseDetailView/invoicingDunningCaseDetailViewReducer.js +51 -2
  121. package/lib/view/invoicing/invoicingDunningCaseDetailView/invoicingDunningCaseDetailViewSelector.d.ts +3 -0
  122. package/lib/view/invoicing/invoicingDunningCaseDetailView/invoicingDunningCaseDetailViewSelector.js +16 -2
  123. package/lib/view/invoicing/invoicingDunningCaseDetailView/invoicingDunningCaseDetailViewState.d.ts +13 -0
  124. package/lib/view/invoicing/invoicingQboView/epics/invoicingQboViewActionType.d.ts +2 -1
  125. package/lib/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +28 -9
  126. package/lib/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +27 -4
  127. package/lib/view/invoicing/issueCreditNote/issueCreditNoteEpic.d.ts +2 -1
  128. package/lib/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +23 -3
  129. package/lib/view/invoicing/issueCreditNote/issueCreditNoteSelector.d.ts +24 -7
  130. package/lib/view/invoicing/issueCreditNote/issueCreditNoteSelector.js +23 -16
  131. package/lib/view/invoicing/recordPayment/recordPaymentEpic.d.ts +2 -1
  132. package/lib/view/invoicing/recordPayment/recordPaymentEpic.js +45 -6
  133. package/lib/view/invoicing/settingsView/settingsViewEpics.d.ts +2 -1
  134. package/lib/view/invoicing/settingsView/settingsViewEpics.js +25 -7
  135. package/lib/view/invoicing/settingsView/settingsViewReducer.d.ts +10 -1
  136. package/lib/view/invoicing/settingsView/settingsViewReducer.js +1 -1
  137. package/lib/view/invoicing/settingsView/settingsViewSelector.d.ts +4 -2
  138. package/lib/view/invoicing/settingsView/settingsViewSelector.js +4 -1
  139. package/lib/view/invoicing/subscriptionAction/subscriptionActionEpic.d.ts +2 -1
  140. package/lib/view/invoicing/subscriptionAction/subscriptionActionEpic.js +40 -8
  141. package/lib/view/vendorFiling1099/vendorFiling1099UploadDetails/vendorFiling1099UploadDetailsReducer.d.ts +1 -1
  142. package/lib/view/vendorFiling1099/vendorFiling1099UploadDetails/vendorFiling1099UploadDetailsReducer.js +5 -2
  143. package/lib/view/vendorTabView/vendorTabViewReducer.d.ts +1 -1
  144. package/lib/view/vendorTabView/vendorTabViewReducer.js +5 -2
  145. package/package.json +2 -2
@@ -1,8 +1,14 @@
1
1
  import { createSlice } from '@reduxjs/toolkit';
2
2
  import { clearAll } from '../../../rootActions';
3
+ export const initialEmailPreviewState = {
4
+ fetchState: 'Not-Started',
5
+ error: undefined,
6
+ preview: undefined,
7
+ };
3
8
  export const initialState = {
4
9
  fetchState: 'Not-Started',
5
10
  error: undefined,
11
+ emailPreview: initialEmailPreviewState,
6
12
  id: undefined,
7
13
  };
8
14
  const invoicingDunningCaseDetailView = createSlice({
@@ -10,10 +16,38 @@ const invoicingDunningCaseDetailView = createSlice({
10
16
  initialState,
11
17
  reducers: {
12
18
  fetchInvoicingDunningCaseDetail(draft, action) {
19
+ if (draft.id !== action.payload.id) {
20
+ draft.emailPreview = { ...initialEmailPreviewState };
21
+ }
13
22
  draft.id = action.payload.id;
14
23
  draft.fetchState = 'In-Progress';
15
24
  draft.error = undefined;
16
25
  },
26
+ fetchInvoicingDunningEmailPreview(draft, action) {
27
+ if (draft.id !== action.payload.id) {
28
+ return;
29
+ }
30
+ draft.emailPreview.fetchState = 'In-Progress';
31
+ draft.emailPreview.error = undefined;
32
+ },
33
+ fetchInvoicingDunningEmailPreviewPage: {
34
+ reducer() {
35
+ // Cache-aware orchestrator trigger only.
36
+ },
37
+ prepare(payload) {
38
+ return {
39
+ payload: {
40
+ cacheOverride: payload.cacheOverride ?? false,
41
+ id: payload.id,
42
+ },
43
+ };
44
+ },
45
+ },
46
+ invalidateInvoicingDunningEmailPreview(draft, action) {
47
+ if (draft.id === action.payload.id) {
48
+ draft.emailPreview = { ...initialEmailPreviewState };
49
+ }
50
+ },
17
51
  updateInvoicingDunningCaseDetail(draft, action) {
18
52
  draft.id = action.payload.id;
19
53
  draft.fetchState = 'Completed';
@@ -23,6 +57,21 @@ const invoicingDunningCaseDetailView = createSlice({
23
57
  draft.fetchState = 'Error';
24
58
  draft.error = action.payload;
25
59
  },
60
+ updateInvoicingDunningEmailPreview(draft, action) {
61
+ if (draft.id === action.payload.id) {
62
+ draft.emailPreview = {
63
+ error: undefined,
64
+ fetchState: 'Completed',
65
+ preview: action.payload.preview,
66
+ };
67
+ }
68
+ },
69
+ updateInvoicingDunningEmailPreviewFailure(draft, action) {
70
+ if (draft.id === action.payload.id) {
71
+ draft.emailPreview.fetchState = 'Error';
72
+ draft.emailPreview.error = action.payload.status;
73
+ }
74
+ },
26
75
  clearInvoicingDunningCaseDetailView(draft) {
27
76
  Object.assign(draft, initialState);
28
77
  },
@@ -33,5 +82,5 @@ const invoicingDunningCaseDetailView = createSlice({
33
82
  });
34
83
  },
35
84
  });
36
- export const { fetchInvoicingDunningCaseDetail, updateInvoicingDunningCaseDetail, updateInvoicingDunningCaseDetailFailure, clearInvoicingDunningCaseDetailView, } = invoicingDunningCaseDetailView.actions;
85
+ export const { clearInvoicingDunningCaseDetailView, fetchInvoicingDunningCaseDetail, fetchInvoicingDunningEmailPreview, fetchInvoicingDunningEmailPreviewPage, invalidateInvoicingDunningEmailPreview, updateInvoicingDunningCaseDetail, updateInvoicingDunningCaseDetailFailure, updateInvoicingDunningEmailPreview, updateInvoicingDunningEmailPreviewFailure, } = invoicingDunningCaseDetailView.actions;
37
86
  export default invoicingDunningCaseDetailView.reducer;
@@ -1,13 +1,26 @@
1
1
  import { getInvoicingDunningCaseById as getInvoicingDunningCaseByIdFromState } from '../../../entity/invoicing/dunningCase/dunningCaseSelector';
2
2
  import { getInvoicingDunningActionState } from '../dunningAction/dunningActionSelector';
3
+ const EMAIL_PREVIEW_NOT_STARTED = {
4
+ error: undefined,
5
+ fetchState: 'Not-Started',
6
+ preview: undefined,
7
+ };
3
8
  export const getInvoicingDunningCaseById = (state, id) => getInvoicingDunningCaseByIdFromState(state.invoicingDunningCaseState, id);
4
9
  export const getInvoicingDunningCaseDetail = (state, invoicingDunningCaseID) => {
5
- const { error, fetchState } = state.invoicingDunningCaseDetailViewState;
10
+ const { emailPreview, error, fetchState, id } = state.invoicingDunningCaseDetailViewState;
6
11
  return {
7
12
  actionState: getInvoicingDunningActionState(invoicingDunningCaseID)(state),
8
13
  dunningCase: getInvoicingDunningCaseById(state, invoicingDunningCaseID),
14
+ emailPreview: id === invoicingDunningCaseID ? emailPreview : EMAIL_PREVIEW_NOT_STARTED,
9
15
  fetchState,
10
16
  error,
11
17
  version: 1.0,
12
18
  };
13
19
  };
20
+ export const getInvoicingDunningEmailPreview = (state, invoicingDunningCaseID) => {
21
+ const detailState = state.invoicingDunningCaseDetailViewState;
22
+ if (detailState.id !== invoicingDunningCaseID) {
23
+ return EMAIL_PREVIEW_NOT_STARTED;
24
+ }
25
+ return detailState.emailPreview;
26
+ };
@@ -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
  }));
@@ -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 { updateInvoicingCreditNotes } from '../../../entity/invoicing/creditNote/creditNoteReducer';
4
+ import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
4
5
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
5
6
  import { fetchInvoiceDetail } from '../invoiceDetail/invoiceDetailReducer';
6
7
  import { localDataToIssueCreditNotePayload, } from './issueCreditNotePayload';
@@ -18,9 +19,28 @@ export const issueCreditNoteEpic = (actions$, state$, zeniAPI) => actions$.pipe(
18
19
  updateInvoicingCreditNotes([response.data], 'merge'),
19
20
  fetchInvoiceDetail({ invoiceId }),
20
21
  issueCreditNoteSuccess({ creditNoteId: response.data.id }),
22
+ openSnackbar({
23
+ messageSection: 'invoicing_credit_note_saved',
24
+ messageText: 'success',
25
+ type: 'success',
26
+ }),
21
27
  ];
22
28
  }
23
- return of(issueCreditNoteFailure(response.status));
24
- }), catchError((error) => of(issueCreditNoteFailure(createZeniAPIStatus('Unexpected Error', 'Issue credit note REST API call errored out ' +
25
- JSON.stringify(error))))));
29
+ return from([
30
+ issueCreditNoteFailure(response.status),
31
+ openSnackbar({
32
+ messageSection: 'invoicing_credit_note_saved',
33
+ messageText: 'failed',
34
+ type: 'error',
35
+ }),
36
+ ]);
37
+ }), catchError((error) => from([
38
+ issueCreditNoteFailure(createZeniAPIStatus('Unexpected Error', 'Issue credit note REST API call errored out ' +
39
+ JSON.stringify(error))),
40
+ openSnackbar({
41
+ messageSection: 'invoicing_credit_note_saved',
42
+ messageText: 'failed',
43
+ type: 'error',
44
+ }),
45
+ ])));
26
46
  }));
@@ -1,20 +1,28 @@
1
- import { INVOICING_CREDIT_NOTE_REASON_CODES } from './issueCreditNoteFormConfig';
2
- export const getIssueCreditNoteView = (state) => {
3
- const { error, fetchState, issuedCreditNoteId } = state.invoicingIssueCreditNoteState;
1
+ import { getInvoiceDetail } from '../invoiceDetail/invoiceDetailSelector';
2
+ import { INVOICING_CREDIT_NOTE_REASON_CODES, initialIssueCreditNoteFormLocalData, } from './issueCreditNoteFormConfig';
3
+ /**
4
+ * The draft is a single global slice, so a draft seeded for a previously opened
5
+ * invoice can still be in state when another invoice's screen mounts. Anything
6
+ * that would render that stale draft next to this invoice is dropped until the
7
+ * screen re-seeds it for `invoiceId`.
8
+ */
9
+ export const getIssueCreditNoteView = (state, invoiceId) => {
10
+ const invoiceView = getInvoiceDetail(state, invoiceId);
11
+ const { draft, error, fetchState, issuedCreditNoteId } = state.invoicingIssueCreditNoteState;
12
+ const isDraftForInvoice = draft.invoiceId === invoiceId;
4
13
  return {
5
- error,
6
- fetchState,
14
+ invoice: invoiceView.invoice,
15
+ isPageReady: invoiceView.fetchState === 'Completed' &&
16
+ isDraftForInvoice &&
17
+ draft.lineItems.length > 0,
7
18
  issuedCreditNoteId,
8
- version: 1.0,
9
- };
10
- };
11
- export const getIssueCreditNoteFormView = (state) => {
12
- const { draft, error, fetchState } = state.invoicingIssueCreditNoteState;
13
- return {
14
- localData: draft,
19
+ localData: isDraftForInvoice
20
+ ? draft
21
+ : initialIssueCreditNoteFormLocalData(invoiceId),
15
22
  reasonCodeValues: [...INVOICING_CREDIT_NOTE_REASON_CODES],
16
- error,
17
- fetchState,
23
+ submitState: { error, fetchState },
24
+ error: invoiceView.error,
25
+ fetchState: invoiceView.fetchState,
18
26
  version: 1.0,
19
27
  };
20
28
  };
@@ -1,7 +1,8 @@
1
- import { of } from 'rxjs';
1
+ import { from } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { updateInvoices } from '../../../entity/invoicing/invoice/invoiceReducer';
4
4
  import { updateInvoicingTransactions } from '../../../entity/invoicing/invoicingTransaction/invoicingTransactionReducer';
5
+ import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
5
6
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
6
7
  import { fetchInvoiceDetail } from '../invoiceDetail/invoiceDetailReducer';
7
8
  import { addInvoicingTransactionToList } from '../invoicingTransactionListView/invoicingTransactionListViewReducer';
@@ -26,11 +27,30 @@ export const recordPaymentEpic = (actions$, state$, zeniAPI) => actions$.pipe(fi
26
27
  updateInvoices([response.data], 'merge'),
27
28
  fetchInvoiceDetail({ invoiceId }),
28
29
  recordPaymentSuccess({ invoiceId }),
30
+ openSnackbar({
31
+ messageSection: 'invoicing_payment_recorded',
32
+ messageText: 'success',
33
+ type: 'success',
34
+ }),
29
35
  ];
30
36
  }
31
- return of(recordPaymentFailure(response.status));
32
- }), catchError((error) => of(recordPaymentFailure(createZeniAPIStatus('Unexpected Error', 'Record payment REST API call errored out ' +
33
- JSON.stringify(error))))));
37
+ return from([
38
+ recordPaymentFailure(response.status),
39
+ openSnackbar({
40
+ messageSection: 'invoicing_payment_recorded',
41
+ messageText: 'failed',
42
+ type: 'error',
43
+ }),
44
+ ]);
45
+ }), catchError((error) => from([
46
+ recordPaymentFailure(createZeniAPIStatus('Unexpected Error', 'Record payment REST API call errored out ' +
47
+ JSON.stringify(error))),
48
+ openSnackbar({
49
+ messageSection: 'invoicing_payment_recorded',
50
+ messageText: 'failed',
51
+ type: 'error',
52
+ }),
53
+ ])));
34
54
  }
35
55
  const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/payments`;
36
56
  const data = localDataToRecordPaymentPayload(draft);
@@ -49,9 +69,28 @@ export const recordPaymentEpic = (actions$, state$, zeniAPI) => actions$.pipe(fi
49
69
  if (linkedInvoiceId != null) {
50
70
  successActions.push(fetchInvoiceDetail({ invoiceId: linkedInvoiceId }));
51
71
  }
72
+ successActions.push(openSnackbar({
73
+ messageSection: 'invoicing_payment_recorded',
74
+ messageText: 'success',
75
+ type: 'success',
76
+ }));
52
77
  return successActions;
53
78
  }
54
- return of(recordPaymentFailure(response.status));
55
- }), catchError((error) => of(recordPaymentFailure(createZeniAPIStatus('Unexpected Error', 'Record payment REST API call errored out ' +
56
- JSON.stringify(error))))));
79
+ return from([
80
+ recordPaymentFailure(response.status),
81
+ openSnackbar({
82
+ messageSection: 'invoicing_payment_recorded',
83
+ messageText: 'failed',
84
+ type: 'error',
85
+ }),
86
+ ]);
87
+ }), catchError((error) => from([
88
+ recordPaymentFailure(createZeniAPIStatus('Unexpected Error', 'Record payment REST API call errored out ' +
89
+ JSON.stringify(error))),
90
+ openSnackbar({
91
+ messageSection: 'invoicing_payment_recorded',
92
+ messageText: 'failed',
93
+ type: 'error',
94
+ }),
95
+ ])));
57
96
  }));
@@ -1,6 +1,7 @@
1
- import { of } from 'rxjs';
1
+ import { from, of } from 'rxjs';
2
2
  import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
3
3
  import { updateAddresses } from '../../../entity/address/addressReducer';
4
+ import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
4
5
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
5
6
  import { connectInvoicingStripe, disconnectInvoicingStripe, fetchInvoicingSettings, invoicingStripeConnectionFailure, saveInvoicingSettings, saveInvoicingSettingsFailure, saveInvoicingSettingsSuccess, updateInvoicingSettings, updateInvoicingSettingsFailure, updateInvoicingStripeConnection, } from './settingsViewReducer';
6
7
  export const fetchInvoicingSettingsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(fetchInvoicingSettings.match), switchMap(() => {
@@ -57,15 +58,32 @@ export const disconnectInvoicingStripeEpic = (actions$, _state$, zeniAPI) => act
57
58
  }));
58
59
  export const saveInvoicingSettingsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(saveInvoicingSettings.match), mergeMap((action) => {
59
60
  const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/settings`;
61
+ const { settings, snackbarSection } = action.payload;
62
+ const snackbar = (messageText) => snackbarSection == null
63
+ ? []
64
+ : [
65
+ openSnackbar({
66
+ messageSection: snackbarSection,
67
+ messageText,
68
+ type: messageText === 'success' ? 'success' : 'error',
69
+ }),
70
+ ];
60
71
  return zeniAPI
61
- .putAndGetJSON(apiUrl, {
62
- ...action.payload,
63
- })
72
+ .putAndGetJSON(apiUrl, { ...settings })
64
73
  .pipe(switchMap((response) => {
65
74
  if (isSuccessResponse(response) && response.data != null) {
66
- return of(saveInvoicingSettingsSuccess(response.data));
75
+ return from([
76
+ saveInvoicingSettingsSuccess(response.data),
77
+ ...snackbar('success'),
78
+ ]);
67
79
  }
68
- return of(saveInvoicingSettingsFailure(response.status));
69
- }), catchError((error) => of(saveInvoicingSettingsFailure(createZeniAPIStatus('Unexpected Error', 'Save settings REST API call errored out ' +
70
- JSON.stringify(error))))));
80
+ return from([
81
+ saveInvoicingSettingsFailure(response.status),
82
+ ...snackbar('failed'),
83
+ ]);
84
+ }), catchError((error) => from([
85
+ saveInvoicingSettingsFailure(createZeniAPIStatus('Unexpected Error', 'Save settings REST API call errored out ' +
86
+ JSON.stringify(error))),
87
+ ...snackbar('failed'),
88
+ ])));
71
89
  }));
@@ -30,7 +30,7 @@ const settingsView = createSlice({
30
30
  saveInvoicingSettings(draft, action) {
31
31
  draft.saveFetchState = { fetchState: 'In-Progress', error: undefined };
32
32
  if (draft.settings != null) {
33
- draft.settings = { ...draft.settings, ...action.payload };
33
+ draft.settings = { ...draft.settings, ...action.payload.settings };
34
34
  }
35
35
  },
36
36
  saveInvoicingSettingsSuccess(draft, action) {
@@ -1,4 +1,5 @@
1
1
  import { getFormattedAddress } from '../../addressView/addressViewSelector';
2
+ import { getInvoicingConfigView } from '../invoicingConfigView/invoicingConfigViewSelector';
2
3
  import { INVOICING_BUSINESS_ADDRESS_TYPE, entityToInvoicingBrandingFormLocalData, } from './invoicingBrandingFormConfig';
3
4
  /**
4
5
  * Shared primitive: the raw invoicing settings. Consumed internally by other
@@ -33,7 +34,8 @@ export const getInvoicingSettingsView = (state) => {
33
34
  * Bundled view for the branding settings form: the draft `localData` (seeded
34
35
  * from the existing settings until the user edits), the business-address label
35
36
  * (from the shared Address screen, seeded on load from `address_id`), the raw
36
- * settings (for the logo/preview) and the save fetch state.
37
+ * settings (for the logo/preview), the backend date-format choices and the
38
+ * save fetch state.
37
39
  */
38
40
  export const getInvoicingBrandingFormView = (state) => {
39
41
  const { brandingDraft, saveFetchState, settings } = state.invoicingSettingsViewState;
@@ -43,6 +45,7 @@ export const getInvoicingBrandingFormView = (state) => {
43
45
  : undefined;
44
46
  return {
45
47
  addressLabel,
48
+ dateFormatOptions: getInvoicingConfigView(state).dateFormatOptions,
46
49
  localData: brandingDraft ?? entityToInvoicingBrandingFormLocalData(settings),
47
50
  saveState: saveFetchState,
48
51
  settings,
@@ -1,13 +1,38 @@
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 { runInvoicingSubscriptionAction, runInvoicingSubscriptionActionFailure, runInvoicingSubscriptionActionSuccess, } from './subscriptionActionReducer';
9
+ /**
10
+ * Each lifecycle action reports with its own copy. Keyed loosely because the
11
+ * action payload carries a plain `string`; an unmapped kind stays silent.
12
+ */
13
+ const SNACKBAR_SECTION_BY_ACTION = {
14
+ activate: 'invoicing_subscription_activated',
15
+ cancel: 'invoicing_subscription_cancelled',
16
+ change_term_end: 'invoicing_subscription_term_end_changed',
17
+ pause: 'invoicing_subscription_paused',
18
+ reactivate: 'invoicing_subscription_reactivated',
19
+ remove_scheduled_cancellation: 'invoicing_subscription_cancellation_removed',
20
+ resume: 'invoicing_subscription_resumed',
21
+ set_non_renewing: 'invoicing_subscription_non_renewing',
22
+ };
8
23
  export const runInvoicingSubscriptionActionEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(runInvoicingSubscriptionAction.match), mergeMap((action) => {
9
24
  const { action: kind, body, id } = action.payload;
10
25
  const requestBody = { action: kind, ...(body ?? {}) };
26
+ const snackbarSection = SNACKBAR_SECTION_BY_ACTION[kind];
27
+ const snackbar = (messageText) => snackbarSection == null
28
+ ? []
29
+ : [
30
+ openSnackbar({
31
+ messageSection: snackbarSection,
32
+ messageText,
33
+ type: messageText === 'success' ? 'success' : 'error',
34
+ }),
35
+ ];
11
36
  const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/subscriptions/${encodeURIComponent(id)}/actions`;
12
37
  return zeniAPI
13
38
  .postAndGetJSON(apiUrl, requestBody)
@@ -17,15 +42,22 @@ export const runInvoicingSubscriptionActionEpic = (actions$, _state$, zeniAPI) =
17
42
  updateInvoicingSubscriptions([response.data], 'merge'),
18
43
  updateAddresses(extractInvoicingSubscriptionAddresses([response.data])),
19
44
  runInvoicingSubscriptionActionSuccess({ id }),
45
+ ...snackbar('success'),
20
46
  ];
21
47
  }
22
- return of(runInvoicingSubscriptionActionFailure({
23
- error: response.status,
48
+ return from([
49
+ runInvoicingSubscriptionActionFailure({
50
+ error: response.status,
51
+ id,
52
+ }),
53
+ ...snackbar('failed'),
54
+ ]);
55
+ }), catchError((error) => from([
56
+ runInvoicingSubscriptionActionFailure({
57
+ error: createZeniAPIStatus('Unexpected Error', 'Subscription action REST API call errored out ' +
58
+ JSON.stringify(error)),
24
59
  id,
25
- }));
26
- }), catchError((error) => of(runInvoicingSubscriptionActionFailure({
27
- error: createZeniAPIStatus('Unexpected Error', 'Subscription action REST API call errored out ' +
28
- JSON.stringify(error)),
29
- id,
30
- }))));
60
+ }),
61
+ ...snackbar('failed'),
62
+ ])));
31
63
  }));
@@ -206,10 +206,13 @@ const vendorFiling1099UploadDetails = createSlice({
206
206
  address: action.payload.ocrData.address != null,
207
207
  };
208
208
  },
209
+ clearVendorFiling1099UploadDetails() {
210
+ return initialState;
211
+ },
209
212
  },
210
213
  extraReducers: (builder) => {
211
214
  builder.addCase(clearAll, () => initialState);
212
215
  },
213
216
  });
214
- export const { updateW9FormUploadFile, updateW9FormUploadFetchState, vendorFiling1099UploadDetailsSave, vendorFiling1099UploadDetailsResetLocalData, vendorFiling1099UploadDetailsSuccessOrFailure, initializeVendorFiling1099UploadDetailsLocalState, updateVendor1099DetailsLocalData, updateW9FormOCRDataToLocalData, vendorFiling1099UploadDetailsResetFormStatus, } = vendorFiling1099UploadDetails.actions;
217
+ export const { clearVendorFiling1099UploadDetails, updateW9FormUploadFile, updateW9FormUploadFetchState, vendorFiling1099UploadDetailsSave, vendorFiling1099UploadDetailsResetLocalData, vendorFiling1099UploadDetailsSuccessOrFailure, initializeVendorFiling1099UploadDetailsLocalState, updateVendor1099DetailsLocalData, updateW9FormOCRDataToLocalData, vendorFiling1099UploadDetailsResetFormStatus, } = vendorFiling1099UploadDetails.actions;
215
218
  export default vendorFiling1099UploadDetails.reducer;
@@ -43,6 +43,9 @@ const vendorTabView = createSlice({
43
43
  draft.currentTab = action.payload.tab;
44
44
  },
45
45
  },
46
+ clearVendorTabView(draft) {
47
+ Object.assign(draft, initialState);
48
+ },
46
49
  },
47
50
  extraReducers: (builder) => {
48
51
  builder.addCase(clearAll, (draft) => {
@@ -50,5 +53,5 @@ const vendorTabView = createSlice({
50
53
  });
51
54
  },
52
55
  });
53
- export const { fetchVendorTabView, updateVendorTabViewTab } = vendorTabView.actions;
56
+ export const { clearVendorTabView, fetchVendorTabView, updateVendorTabViewTab, } = vendorTabView.actions;
54
57
  export default vendorTabView.reducer;