@zeniai/client-epic-state 5.1.91 → 5.1.92
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.
- package/lib/entity/snackbar/snackbarApiError.d.ts +8 -0
- package/lib/entity/snackbar/snackbarApiError.js +15 -0
- package/lib/esm/entity/snackbar/snackbarApiError.js +11 -0
- package/lib/esm/index.js +1 -1
- package/lib/esm/view/invoicing/createCreditNote/createCreditNoteEpic.js +2 -0
- package/lib/esm/view/invoicing/createInvoice/createInvoiceEpic.js +2 -0
- package/lib/esm/view/invoicing/discountAction/discountActionEpic.js +6 -3
- package/lib/esm/view/invoicing/dunningAction/dunningActionEpic.js +6 -3
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +5 -4
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +3 -0
- package/lib/esm/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +2 -0
- package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +2 -0
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +2 -0
- package/lib/esm/view/invoicing/invoiceAction/invoiceActionEpic.js +7 -3
- package/lib/esm/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +2 -0
- package/lib/esm/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +2 -0
- package/lib/esm/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +2 -0
- package/lib/esm/view/invoicing/recordPayment/recordPaymentEpic.js +3 -0
- package/lib/esm/view/invoicing/settingsView/settingsViewEpics.js +6 -3
- package/lib/esm/view/invoicing/settingsView/settingsViewSelector.js +52 -0
- package/lib/esm/view/invoicing/subscriptionAction/subscriptionActionEpic.js +6 -3
- package/lib/esm/view/vendorTabView/vendorTabViewReducer.js +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/index.js +2 -1
- package/lib/view/invoicing/createCreditNote/createCreditNoteEpic.js +2 -0
- package/lib/view/invoicing/createInvoice/createInvoiceEpic.js +2 -0
- package/lib/view/invoicing/discountAction/discountActionEpic.js +5 -2
- package/lib/view/invoicing/dunningAction/dunningActionEpic.js +5 -2
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +5 -4
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +3 -0
- package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +2 -0
- package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +2 -0
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +2 -0
- package/lib/view/invoicing/invoiceAction/invoiceActionEpic.js +6 -2
- package/lib/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +2 -0
- package/lib/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +2 -0
- package/lib/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +2 -0
- package/lib/view/invoicing/recordPayment/recordPaymentEpic.js +3 -0
- package/lib/view/invoicing/settingsView/settingsViewEpics.js +5 -2
- package/lib/view/invoicing/settingsView/settingsViewSelector.d.ts +41 -1
- package/lib/view/invoicing/settingsView/settingsViewSelector.js +55 -1
- package/lib/view/invoicing/subscriptionAction/subscriptionActionEpic.js +5 -2
- package/package.json +1 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ZeniAPIStatus } from '../../responsePayload';
|
|
2
|
+
interface SnackbarMessageVariable {
|
|
3
|
+
variableName: string;
|
|
4
|
+
variableValue: string;
|
|
5
|
+
}
|
|
6
|
+
/** Undefined when the status carries no message, so the snackbar falls back to its generic copy. */
|
|
7
|
+
export declare const apiErrorSnackbarVariables: (status: ZeniAPIStatus | undefined) => SnackbarMessageVariable[] | undefined;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.apiErrorSnackbarVariables = void 0;
|
|
4
|
+
/** Placeholder in every `failed` snackbar string, swapped for the API's message. */
|
|
5
|
+
const API_ERROR_TOKEN = '_api-error_';
|
|
6
|
+
/** Undefined when the status carries no message, so the snackbar falls back to its generic copy. */
|
|
7
|
+
// Pass only platform statuses: a local `createZeniAPIStatus` holds internal debug text.
|
|
8
|
+
const apiErrorSnackbarVariables = (status) => {
|
|
9
|
+
const message = status?.message?.trim() ?? '';
|
|
10
|
+
if (message === '') {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
return [{ variableName: API_ERROR_TOKEN, variableValue: message }];
|
|
14
|
+
};
|
|
15
|
+
exports.apiErrorSnackbarVariables = apiErrorSnackbarVariables;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Placeholder in every `failed` snackbar string, swapped for the API's message. */
|
|
2
|
+
const API_ERROR_TOKEN = '_api-error_';
|
|
3
|
+
/** Undefined when the status carries no message, so the snackbar falls back to its generic copy. */
|
|
4
|
+
// Pass only platform statuses: a local `createZeniAPIStatus` holds internal debug text.
|
|
5
|
+
export const apiErrorSnackbarVariables = (status) => {
|
|
6
|
+
const message = status?.message?.trim() ?? '';
|
|
7
|
+
if (message === '') {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
return [{ variableName: API_ERROR_TOKEN, variableValue: message }];
|
|
11
|
+
};
|
package/lib/esm/index.js
CHANGED
|
@@ -839,7 +839,7 @@ export { getInvoicingPlanById } from './entity/invoicing/plan/planSelector';
|
|
|
839
839
|
export { getInvoicingProductById } from './entity/invoicing/product/productSelector';
|
|
840
840
|
// ── Invoicing: settings ───────────────────────────────────────────────────────
|
|
841
841
|
export { clearInvoicingSettings, connectInvoicingStripe, disconnectInvoicingStripe, fetchInvoicingSettings, resetInvoicingBrandingFormDraft, resetSaveInvoicingSettings, saveInvoicingSettings, submitInvoicingBrandingForm, updateInvoicingBrandingFormDraft, updateInvoicingSettings, } from './view/invoicing/settingsView/settingsViewReducer';
|
|
842
|
-
export { getInvoicingBrandingFormView, getInvoicingSettings, getInvoicingSettingsFetchState, getInvoicingSettingsView, } from './view/invoicing/settingsView/settingsViewSelector';
|
|
842
|
+
export { getInvoicingBrandingFormView, getInvoicingSettings, getInvoicingSettingsFetchState, getInvoicingSettingsHubView, getInvoicingSettingsView, } from './view/invoicing/settingsView/settingsViewSelector';
|
|
843
843
|
export { INVOICING_BUSINESS_ADDRESS_TYPE, entityToInvoicingBrandingFormLocalData, initialInvoicingBrandingFormLocalData, } from './view/invoicing/settingsView/invoicingBrandingFormConfig';
|
|
844
844
|
export { isStripeConnectedFromSettings } from './view/invoicing/settingsView/invoicingSettingsHelpers';
|
|
845
845
|
// ── Invoicing: QBO integration ────────────────────────────────────────────────
|
|
@@ -1,6 +1,7 @@
|
|
|
1
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 { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
4
5
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
5
6
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
6
7
|
import { localDataToCreateCreditNotePayload, } from './createCreditNotePayload';
|
|
@@ -29,6 +30,7 @@ export const createCreditNoteEpic = (actions$, state$, zeniAPI) => actions$.pipe
|
|
|
29
30
|
messageSection: 'invoicing_credit_note_saved',
|
|
30
31
|
messageText: 'failed',
|
|
31
32
|
type: 'error',
|
|
33
|
+
variables: apiErrorSnackbarVariables(response.status),
|
|
32
34
|
}),
|
|
33
35
|
]);
|
|
34
36
|
}), catchError((error) => from([
|
|
@@ -3,6 +3,7 @@ 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 { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
6
7
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
7
8
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
8
9
|
import { addInvoiceToList } from '../invoiceList/invoiceListReducer';
|
|
@@ -36,6 +37,7 @@ export const createInvoiceEpic = (actions$, _state$, zeniAPI) => actions$.pipe(f
|
|
|
36
37
|
messageSection: 'invoicing_invoice_saved',
|
|
37
38
|
messageText: 'failed',
|
|
38
39
|
type: 'error',
|
|
40
|
+
variables: apiErrorSnackbarVariables(response.status),
|
|
39
41
|
}),
|
|
40
42
|
]);
|
|
41
43
|
}), catchError((error) => from([
|
|
@@ -1,8 +1,9 @@
|
|
|
1
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 { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
4
5
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
5
|
-
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
6
|
+
import { createZeniAPIStatus, isSuccessResponse, } from '../../../responsePayload';
|
|
6
7
|
import { runInvoicingDiscountAction, runInvoicingDiscountActionFailure, runInvoicingDiscountActionSuccess, } from './discountActionReducer';
|
|
7
8
|
/** Snackbar copy per action kind; unlisted kinds run without one. */
|
|
8
9
|
const SNACKBAR_SECTION_BY_KIND = {
|
|
@@ -14,13 +15,15 @@ export const runInvoicingDiscountActionEpic = (actions$, _state$, zeniAPI) => ac
|
|
|
14
15
|
const { action: kind, id } = action.payload;
|
|
15
16
|
const requestBody = { action: kind };
|
|
16
17
|
const snackbarSection = SNACKBAR_SECTION_BY_KIND[kind];
|
|
17
|
-
|
|
18
|
+
/** `status` surfaces the platform's error text; omit it to keep the generic copy. */
|
|
19
|
+
const snackbar = (messageText, status) => snackbarSection == null
|
|
18
20
|
? []
|
|
19
21
|
: [
|
|
20
22
|
openSnackbar({
|
|
21
23
|
messageSection: snackbarSection,
|
|
22
24
|
messageText,
|
|
23
25
|
type: messageText === 'success' ? 'success' : 'error',
|
|
26
|
+
variables: apiErrorSnackbarVariables(status),
|
|
24
27
|
}),
|
|
25
28
|
];
|
|
26
29
|
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/discounts/${encodeURIComponent(id)}/actions`;
|
|
@@ -39,7 +42,7 @@ export const runInvoicingDiscountActionEpic = (actions$, _state$, zeniAPI) => ac
|
|
|
39
42
|
error: response.status,
|
|
40
43
|
id,
|
|
41
44
|
}),
|
|
42
|
-
...snackbar('failed'),
|
|
45
|
+
...snackbar('failed', response.status),
|
|
43
46
|
]);
|
|
44
47
|
}), catchError((error) => from([
|
|
45
48
|
runInvoicingDiscountActionFailure({
|
|
@@ -1,8 +1,9 @@
|
|
|
1
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 { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
4
5
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
5
|
-
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
6
|
+
import { createZeniAPIStatus, isSuccessResponse, } from '../../../responsePayload';
|
|
6
7
|
import { runInvoicingDunningAction, runInvoicingDunningActionFailure, runInvoicingDunningActionSuccess, } from './dunningActionReducer';
|
|
7
8
|
/**
|
|
8
9
|
* Snackbar copy is per action kind; anything not listed here runs without one.
|
|
@@ -15,13 +16,15 @@ const SNACKBAR_SECTION_BY_KIND = {
|
|
|
15
16
|
export const runInvoicingDunningActionEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(runInvoicingDunningAction.match), mergeMap((action) => {
|
|
16
17
|
const { action: kind, body, id } = action.payload;
|
|
17
18
|
const snackbarSection = SNACKBAR_SECTION_BY_KIND[kind];
|
|
18
|
-
|
|
19
|
+
/** `status` surfaces the platform's error text; omit it to keep the generic copy. */
|
|
20
|
+
const snackbar = (messageText, status) => snackbarSection == null
|
|
19
21
|
? []
|
|
20
22
|
: [
|
|
21
23
|
openSnackbar({
|
|
22
24
|
messageSection: snackbarSection,
|
|
23
25
|
messageText,
|
|
24
26
|
type: messageText === 'success' ? 'success' : 'error',
|
|
27
|
+
variables: apiErrorSnackbarVariables(status),
|
|
25
28
|
}),
|
|
26
29
|
];
|
|
27
30
|
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/dunning/${encodeURIComponent(id)}/${kind}`;
|
|
@@ -40,7 +43,7 @@ export const runInvoicingDunningActionEpic = (actions$, _state$, zeniAPI) => act
|
|
|
40
43
|
error: response.status,
|
|
41
44
|
id,
|
|
42
45
|
}),
|
|
43
|
-
...snackbar('failed'),
|
|
46
|
+
...snackbar('failed', response.status),
|
|
44
47
|
]);
|
|
45
48
|
}), catchError((error) => from([
|
|
46
49
|
runInvoicingDunningActionFailure({
|
|
@@ -80,6 +80,8 @@ const buildSubFamilyPayload = (localData, subFamily, clearEmptyValues) => {
|
|
|
80
80
|
}
|
|
81
81
|
return payload;
|
|
82
82
|
};
|
|
83
|
+
/** `unit` is the item's unit of measure, not a currency; `CURRENCY_CODE` above prices sub-families. */
|
|
84
|
+
const DEFAULT_CATALOG_ITEM_UNIT = 'USD';
|
|
83
85
|
/**
|
|
84
86
|
* Build the parent catalog-item request body from the form draft. Creates omit
|
|
85
87
|
* both parent and sub-family IDs; edits retain returned sub-family IDs.
|
|
@@ -101,10 +103,9 @@ export const localDataToSaveInvoicingCatalogItemPayload = (localData, isCreate)
|
|
|
101
103
|
if (description != null) {
|
|
102
104
|
itemPayload.description = description;
|
|
103
105
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
106
|
+
// The form no longer collects a unit; an item that already has one keeps it.
|
|
107
|
+
itemPayload.unit =
|
|
108
|
+
trimOrUndefined(localData.unit) ?? DEFAULT_CATALOG_ITEM_UNIT;
|
|
108
109
|
if (localData.itemApplicability === 'restricted' &&
|
|
109
110
|
localData.applicableItems.length > 0) {
|
|
110
111
|
itemPayload.applicable_items = localData.applicableItems;
|
package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js
CHANGED
|
@@ -2,6 +2,7 @@ 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 { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
5
6
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
6
7
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
7
8
|
import { addInvoicingCatalogItem } from '../invoicingCatalogListView/invoicingCatalogListViewReducer';
|
|
@@ -45,6 +46,7 @@ export const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actio
|
|
|
45
46
|
messageSection: 'invoicing_catalog_item_saved',
|
|
46
47
|
messageText: 'failed',
|
|
47
48
|
type: 'error',
|
|
49
|
+
variables: apiErrorSnackbarVariables(failedProductResponse.status),
|
|
48
50
|
}),
|
|
49
51
|
]);
|
|
50
52
|
}
|
|
@@ -94,6 +96,7 @@ export const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actio
|
|
|
94
96
|
messageSection: 'invoicing_catalog_item_saved',
|
|
95
97
|
messageText: 'failed',
|
|
96
98
|
type: 'error',
|
|
99
|
+
variables: apiErrorSnackbarVariables(response.status),
|
|
97
100
|
}),
|
|
98
101
|
]);
|
|
99
102
|
}), catchError((error) => from([
|
|
@@ -1,6 +1,7 @@
|
|
|
1
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 { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
4
5
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
5
6
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
6
7
|
import { addInvoicingCouponToList } from '../couponView/couponViewReducer';
|
|
@@ -57,6 +58,7 @@ export const saveInvoicingCouponEpic = (actions$, state$, zeniAPI) => actions$.p
|
|
|
57
58
|
messageSection: 'invoicing_coupon_saved',
|
|
58
59
|
messageText: 'failed',
|
|
59
60
|
type: 'error',
|
|
61
|
+
variables: apiErrorSnackbarVariables(response.status),
|
|
60
62
|
}),
|
|
61
63
|
]);
|
|
62
64
|
}), catchError((error) => from([
|
|
@@ -3,6 +3,7 @@ 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 { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
6
7
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
7
8
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
8
9
|
import { resetNewAddressDataInLocalStore } from '../../addressView/addressViewReducer';
|
|
@@ -59,6 +60,7 @@ export const saveInvoicingCustomerEpic = (actions$, state$, zeniAPI) => actions$
|
|
|
59
60
|
messageSection: 'invoicing_customer_saved',
|
|
60
61
|
messageText: 'failed',
|
|
61
62
|
type: 'error',
|
|
63
|
+
variables: apiErrorSnackbarVariables(response.status),
|
|
62
64
|
}),
|
|
63
65
|
]);
|
|
64
66
|
}), catchError((error) => from([
|
package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js
CHANGED
|
@@ -3,6 +3,7 @@ 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 { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
6
7
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
7
8
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
8
9
|
import { resetNewAddressDataInLocalStore } from '../../addressView/addressViewReducer';
|
|
@@ -45,6 +46,7 @@ export const saveInvoicingSubscriptionEpic = (actions$, state$, zeniAPI) => acti
|
|
|
45
46
|
messageSection: 'invoicing_subscription_saved',
|
|
46
47
|
messageText: 'failed',
|
|
47
48
|
type: 'error',
|
|
49
|
+
variables: apiErrorSnackbarVariables(response.status),
|
|
48
50
|
}),
|
|
49
51
|
];
|
|
50
52
|
}
|
|
@@ -3,8 +3,9 @@ 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 { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
6
7
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
7
|
-
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
8
|
+
import { createZeniAPIStatus, isSuccessResponse, } from '../../../responsePayload';
|
|
8
9
|
import { runInvoicingInvoiceAction, runInvoicingInvoiceActionFailure, runInvoicingInvoiceActionSuccess, updateInvoicingInvoice, } from './invoiceActionReducer';
|
|
9
10
|
/** Snackbar copy per action kind; unlisted kinds run without one. */
|
|
10
11
|
const SNACKBAR_SECTION_BY_KIND = {
|
|
@@ -16,13 +17,15 @@ export const runInvoicingInvoiceActionEpic = (actions$, _state$, zeniAPI) => act
|
|
|
16
17
|
action.payload.action !== 'issue-credit-note'), mergeMap((action) => {
|
|
17
18
|
const { action: kind, body, invoiceId } = action.payload;
|
|
18
19
|
const snackbarSection = SNACKBAR_SECTION_BY_KIND[kind];
|
|
19
|
-
|
|
20
|
+
/** `status` surfaces the platform's error text; omit it to keep the generic copy. */
|
|
21
|
+
const snackbar = (messageText, status) => snackbarSection == null
|
|
20
22
|
? []
|
|
21
23
|
: [
|
|
22
24
|
openSnackbar({
|
|
23
25
|
messageSection: snackbarSection,
|
|
24
26
|
messageText,
|
|
25
27
|
type: messageText === 'success' ? 'success' : 'error',
|
|
28
|
+
variables: apiErrorSnackbarVariables(status),
|
|
26
29
|
}),
|
|
27
30
|
];
|
|
28
31
|
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/invoices/${encodeURIComponent(invoiceId)}/${kind}`;
|
|
@@ -42,7 +45,7 @@ export const runInvoicingInvoiceActionEpic = (actions$, _state$, zeniAPI) => act
|
|
|
42
45
|
error: response.status,
|
|
43
46
|
invoiceId,
|
|
44
47
|
}),
|
|
45
|
-
...snackbar('failed'),
|
|
48
|
+
...snackbar('failed', response.status),
|
|
46
49
|
]);
|
|
47
50
|
}), catchError((error) => from([
|
|
48
51
|
runInvoicingInvoiceActionFailure({
|
|
@@ -80,6 +83,7 @@ export const updateInvoicingInvoiceEpic = (actions$, _state$, zeniAPI) => action
|
|
|
80
83
|
messageSection: 'invoicing_invoice_saved',
|
|
81
84
|
messageText: 'failed',
|
|
82
85
|
type: 'error',
|
|
86
|
+
variables: apiErrorSnackbarVariables(response.status),
|
|
83
87
|
}),
|
|
84
88
|
]);
|
|
85
89
|
}), catchError((error) => from([
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { from, of } from 'rxjs';
|
|
2
2
|
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
|
+
import { apiErrorSnackbarVariables } from '../../../../entity/snackbar/snackbarApiError';
|
|
3
4
|
import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
|
|
4
5
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
5
6
|
import { fetchInvoicingQboSyncHealth, retryInvoicingQboSyncTask, retryInvoicingQboSyncTaskFailure, retryInvoicingQboSyncTaskSuccess, } from '../invoicingQboViewReducer';
|
|
@@ -28,6 +29,7 @@ export const retryInvoicingQboSyncTaskEpic = (actions$, _state$, zeniAPI) => act
|
|
|
28
29
|
messageSection: 'invoicing_qbo_sync_health_retry',
|
|
29
30
|
messageText: 'failed',
|
|
30
31
|
type: 'error',
|
|
32
|
+
variables: apiErrorSnackbarVariables(response.status),
|
|
31
33
|
}),
|
|
32
34
|
]);
|
|
33
35
|
}), catchError((error) => from([
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { from } from 'rxjs';
|
|
2
2
|
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
|
+
import { apiErrorSnackbarVariables } from '../../../../entity/snackbar/snackbarApiError';
|
|
3
4
|
import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
|
|
4
5
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
5
6
|
import { fetchInvoicingQboSyncHealth, startInvoicingQboBackfill, startInvoicingQboBackfillFailure, startInvoicingQboBackfillSuccess, } from '../invoicingQboViewReducer';
|
|
@@ -27,6 +28,7 @@ export const startInvoicingQboBackfillEpic = (actions$, _state$, zeniAPI) => act
|
|
|
27
28
|
messageSection: 'invoicing_qbo_backfill',
|
|
28
29
|
messageText: 'failed',
|
|
29
30
|
type: 'error',
|
|
31
|
+
variables: apiErrorSnackbarVariables(response.status),
|
|
30
32
|
}),
|
|
31
33
|
]);
|
|
32
34
|
}), catchError((error) => from([
|
|
@@ -1,6 +1,7 @@
|
|
|
1
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 { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
4
5
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
5
6
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
6
7
|
import { fetchInvoiceDetail } from '../invoiceDetail/invoiceDetailReducer';
|
|
@@ -32,6 +33,7 @@ export const issueCreditNoteEpic = (actions$, state$, zeniAPI) => actions$.pipe(
|
|
|
32
33
|
messageSection: 'invoicing_credit_note_saved',
|
|
33
34
|
messageText: 'failed',
|
|
34
35
|
type: 'error',
|
|
36
|
+
variables: apiErrorSnackbarVariables(response.status),
|
|
35
37
|
}),
|
|
36
38
|
]);
|
|
37
39
|
}), catchError((error) => from([
|
|
@@ -2,6 +2,7 @@ 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 { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
5
6
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
6
7
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
7
8
|
import { fetchInvoiceDetail } from '../invoiceDetail/invoiceDetailReducer';
|
|
@@ -40,6 +41,7 @@ export const recordPaymentEpic = (actions$, state$, zeniAPI) => actions$.pipe(fi
|
|
|
40
41
|
messageSection: 'invoicing_payment_recorded',
|
|
41
42
|
messageText: 'failed',
|
|
42
43
|
type: 'error',
|
|
44
|
+
variables: apiErrorSnackbarVariables(response.status),
|
|
43
45
|
}),
|
|
44
46
|
]);
|
|
45
47
|
}), catchError((error) => from([
|
|
@@ -82,6 +84,7 @@ export const recordPaymentEpic = (actions$, state$, zeniAPI) => actions$.pipe(fi
|
|
|
82
84
|
messageSection: 'invoicing_payment_recorded',
|
|
83
85
|
messageText: 'failed',
|
|
84
86
|
type: 'error',
|
|
87
|
+
variables: apiErrorSnackbarVariables(response.status),
|
|
85
88
|
}),
|
|
86
89
|
]);
|
|
87
90
|
}), catchError((error) => from([
|
|
@@ -1,8 +1,9 @@
|
|
|
1
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 { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
4
5
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
5
|
-
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
6
|
+
import { createZeniAPIStatus, isSuccessResponse, } from '../../../responsePayload';
|
|
6
7
|
import { connectInvoicingStripe, disconnectInvoicingStripe, fetchInvoicingSettings, invoicingStripeConnectionFailure, saveInvoicingSettings, saveInvoicingSettingsFailure, saveInvoicingSettingsSuccess, updateInvoicingSettings, updateInvoicingSettingsFailure, updateInvoicingStripeConnection, } from './settingsViewReducer';
|
|
7
8
|
export const fetchInvoicingSettingsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(fetchInvoicingSettings.match), switchMap(() => {
|
|
8
9
|
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/settings`;
|
|
@@ -59,13 +60,15 @@ export const disconnectInvoicingStripeEpic = (actions$, _state$, zeniAPI) => act
|
|
|
59
60
|
export const saveInvoicingSettingsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(saveInvoicingSettings.match), mergeMap((action) => {
|
|
60
61
|
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/settings`;
|
|
61
62
|
const { settings, snackbarSection } = action.payload;
|
|
62
|
-
|
|
63
|
+
/** `status` surfaces the platform's error text; omit it to keep the generic copy. */
|
|
64
|
+
const snackbar = (messageText, status) => snackbarSection == null
|
|
63
65
|
? []
|
|
64
66
|
: [
|
|
65
67
|
openSnackbar({
|
|
66
68
|
messageSection: snackbarSection,
|
|
67
69
|
messageText,
|
|
68
70
|
type: messageText === 'success' ? 'success' : 'error',
|
|
71
|
+
variables: apiErrorSnackbarVariables(status),
|
|
69
72
|
}),
|
|
70
73
|
];
|
|
71
74
|
return zeniAPI
|
|
@@ -79,7 +82,7 @@ export const saveInvoicingSettingsEpic = (actions$, _state$, zeniAPI) => actions
|
|
|
79
82
|
}
|
|
80
83
|
return from([
|
|
81
84
|
saveInvoicingSettingsFailure(response.status),
|
|
82
|
-
...snackbar('failed'),
|
|
85
|
+
...snackbar('failed', response.status),
|
|
83
86
|
]);
|
|
84
87
|
}), catchError((error) => from([
|
|
85
88
|
saveInvoicingSettingsFailure(createZeniAPIStatus('Unexpected Error', 'Save settings REST API call errored out ' +
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getInvoicingQboAccountMappingId, } from '../../../entity/invoicing/invoicingCommonPayload';
|
|
1
2
|
import { getFormattedAddress } from '../../addressView/addressViewSelector';
|
|
2
3
|
import { getInvoicingConfigView } from '../invoicingConfigView/invoicingConfigViewSelector';
|
|
3
4
|
import { INVOICING_BUSINESS_ADDRESS_TYPE, entityToInvoicingBrandingFormLocalData, } from './invoicingBrandingFormConfig';
|
|
@@ -30,6 +31,57 @@ export const getInvoicingSettingsView = (state) => {
|
|
|
30
31
|
stripeConnectState: stripeFetchState,
|
|
31
32
|
};
|
|
32
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* Gates the Enable Invoicing action: payments must be able to land (Stripe
|
|
36
|
+
* connected *and* accepting charges) and the QBO accounting step must be
|
|
37
|
+
* finished, so an enabled tenant can always book what it invoices.
|
|
38
|
+
*
|
|
39
|
+
* Deliberately not part of `deriveInvoicingOnboardingStatus`, which routes the
|
|
40
|
+
* module off the config flags alone. Folding these in there would (a) demote a
|
|
41
|
+
* live tenant to the settings tree the moment an integration broke, stranding
|
|
42
|
+
* its existing invoices, and (b) deadlock the route gate, which fetches only the
|
|
43
|
+
* config — never the settings or QBO connection these read.
|
|
44
|
+
*/
|
|
45
|
+
export function deriveInvoicingEnablePrerequisites(settings, isQboConnected, qboAccountMappingKindOptions) {
|
|
46
|
+
const isStripeConnected = settings?.stripe_connected === true &&
|
|
47
|
+
settings?.stripe_account?.charges_enabled === true;
|
|
48
|
+
const accountMappings = settings?.qbo?.account_mappings ?? undefined;
|
|
49
|
+
// An empty option list means the config has not landed yet — treating that as
|
|
50
|
+
// configured would let `every` pass vacuously and unlock the button early.
|
|
51
|
+
const isQboConfigured = isQboConnected &&
|
|
52
|
+
qboAccountMappingKindOptions.length > 0 &&
|
|
53
|
+
qboAccountMappingKindOptions.every((option) => getInvoicingQboAccountMappingId(accountMappings, option.code) != null);
|
|
54
|
+
return {
|
|
55
|
+
canEnable: isStripeConnected && isQboConfigured,
|
|
56
|
+
isQboConfigured,
|
|
57
|
+
isStripeConnected,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The settings hub's composite of everything it derives from the store: whether
|
|
62
|
+
* to offer Enable Invoicing at all, the in-flight flag for that action, and the
|
|
63
|
+
* two integration prerequisites kept separate so the hub can name the step still
|
|
64
|
+
* outstanding instead of showing a dead button.
|
|
65
|
+
*
|
|
66
|
+
* `canEnableInvoicing` folds in the onboarding step, so the screen does not need
|
|
67
|
+
* to re-check it: the footer is only offered mid-onboarding and only once both
|
|
68
|
+
* integrations are ready.
|
|
69
|
+
*
|
|
70
|
+
* Deliberately not folded into `getInvoicingConfigView`: that selector gates
|
|
71
|
+
* every invoicing route and stays a pure read of the config slice. The settings
|
|
72
|
+
* and QBO slices read here are only fetched once a settings screen is mounted.
|
|
73
|
+
*/
|
|
74
|
+
export const getInvoicingSettingsHubView = (state) => {
|
|
75
|
+
const { enableState, qboAccountMappingKindOptions, status } = getInvoicingConfigView(state);
|
|
76
|
+
const { canEnable, isQboConfigured, isStripeConnected } = deriveInvoicingEnablePrerequisites(state.invoicingSettingsViewState.settings, state.invoicingQboViewState.connection?.connected === true, qboAccountMappingKindOptions);
|
|
77
|
+
return {
|
|
78
|
+
canEnableInvoicing: status === 'settings' && canEnable,
|
|
79
|
+
isEnablingInvoicing: enableState.fetchState === 'In-Progress',
|
|
80
|
+
isQboConfigured,
|
|
81
|
+
isStripeConnected,
|
|
82
|
+
status,
|
|
83
|
+
};
|
|
84
|
+
};
|
|
33
85
|
/**
|
|
34
86
|
* Bundled view for the branding settings form: the draft `localData` (seeded
|
|
35
87
|
* from the existing settings until the user edits), the business-address label
|
|
@@ -3,8 +3,9 @@ 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 { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
6
7
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
7
|
-
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
8
|
+
import { createZeniAPIStatus, isSuccessResponse, } from '../../../responsePayload';
|
|
8
9
|
import { runInvoicingSubscriptionAction, runInvoicingSubscriptionActionFailure, runInvoicingSubscriptionActionSuccess, } from './subscriptionActionReducer';
|
|
9
10
|
/**
|
|
10
11
|
* Each lifecycle action reports with its own copy. Keyed loosely because the
|
|
@@ -24,13 +25,15 @@ export const runInvoicingSubscriptionActionEpic = (actions$, _state$, zeniAPI) =
|
|
|
24
25
|
const { action: kind, body, id } = action.payload;
|
|
25
26
|
const requestBody = { action: kind, ...(body ?? {}) };
|
|
26
27
|
const snackbarSection = SNACKBAR_SECTION_BY_ACTION[kind];
|
|
27
|
-
|
|
28
|
+
/** `status` surfaces the platform's error text; omit it to keep the generic copy. */
|
|
29
|
+
const snackbar = (messageText, status) => snackbarSection == null
|
|
28
30
|
? []
|
|
29
31
|
: [
|
|
30
32
|
openSnackbar({
|
|
31
33
|
messageSection: snackbarSection,
|
|
32
34
|
messageText,
|
|
33
35
|
type: messageText === 'success' ? 'success' : 'error',
|
|
36
|
+
variables: apiErrorSnackbarVariables(status),
|
|
34
37
|
}),
|
|
35
38
|
];
|
|
36
39
|
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/subscriptions/${encodeURIComponent(id)}/actions`;
|
|
@@ -50,7 +53,7 @@ export const runInvoicingSubscriptionActionEpic = (actions$, _state$, zeniAPI) =
|
|
|
50
53
|
error: response.status,
|
|
51
54
|
id,
|
|
52
55
|
}),
|
|
53
|
-
...snackbar('failed'),
|
|
56
|
+
...snackbar('failed', response.status),
|
|
54
57
|
]);
|
|
55
58
|
}), catchError((error) => from([
|
|
56
59
|
runInvoicingSubscriptionActionFailure({
|
|
@@ -53,5 +53,5 @@ const vendorTabView = createSlice({
|
|
|
53
53
|
});
|
|
54
54
|
},
|
|
55
55
|
});
|
|
56
|
-
export const { clearVendorTabView, fetchVendorTabView, updateVendorTabViewTab
|
|
56
|
+
export const { clearVendorTabView, fetchVendorTabView, updateVendorTabViewTab } = vendorTabView.actions;
|
|
57
57
|
export default vendorTabView.reducer;
|
package/lib/index.d.ts
CHANGED
|
@@ -137,7 +137,7 @@ import { getTaskGroupById } from './entity/taskGroup/taskGroupSelector';
|
|
|
137
137
|
import { TaskGroupState } from './entity/taskGroup/taskGroupState';
|
|
138
138
|
import { TaskGroupTemplate } from './entity/taskGroupTemplate/taskGroupTemplateState';
|
|
139
139
|
import { DoSignInPayload, deleteConnection, doMagicLinkSignIn, doSignIn, doSignOut, fetchActiveTenant, fetchAllTenants, fetchExcludedResources as fetchExcludedResourcesForTenant, fetchExternalConnections as fetchExternalConnectionsForTenant, fetchSubscriptionSummaryForTenant, initEmailConnectOAuth, resendVerifyDeviceOTP, resetSignInState, saveAPIKeyConnection, saveConnectorCredentials, saveExternalConnection as saveExternalConnectionForTenant, saveOAuthConnection, sendEmailMagicLinkToUser, sendSessionHeartbeat, toExternalIntegrationType, toExternalSupportedTool, updateCurrentTenant, updateSignInState, verifyDeviceWithTwoFA } from './entity/tenant/tenantReducer';
|
|
140
|
-
import { CurrentTenant, TenantBaseView, TenantCoreDetailsView, TenantView, TenantsBaseOrdered, TenantsOrdered,
|
|
140
|
+
import { CurrentTenant, DEFAULT_RECEIPTS_EMAIL, TenantBaseView, TenantCoreDetailsView, TenantView, TenantsBaseOrdered, TenantsOrdered, getCurrentTenant, getIsAccountingClassesEnabled, getIsAccountingProjectsEnabled, getReceiptsEmail, getTenantBaseById, getTenantBaseViewForTenantId, getTenantBaseViewForTenantView, getTenantsBaseByCheckInDateSelector, getTenantsByCheckInDateSelector, getTenantsCoreDetailsByCheckInDateSelector, isOtherProductsEnabledForTenant, isTenantBankingOnly, isTenantBookkeepingEnabled, isTenantCardsOnly, isTenantUsingZeniCOA, isZeniDomainTenant, toTenantCoreDetailsView } from './entity/tenant/tenantSelector';
|
|
141
141
|
import { CapitalizableAccount, CapitalizableAccounts, CapitalizableClassificationType, CapitalizableMatchPattern, Connection, LoggedInUser, RoleResource, Tenant, TenantProductSettings } from './entity/tenant/tenantState';
|
|
142
142
|
import { ToastNotificationPayload } from './entity/toastNotification/toastNotificationPayload';
|
|
143
143
|
import { pushToastNotification } from './entity/toastNotification/toastNotificationReducer';
|
|
@@ -1211,8 +1211,8 @@ export { getInvoicingPlanById } from './entity/invoicing/plan/planSelector';
|
|
|
1211
1211
|
export { getInvoicingProductById } from './entity/invoicing/product/productSelector';
|
|
1212
1212
|
export type { InvoicingCatalogItemDetailView } from './view/invoicing/invoicingCatalogItemDetailView/invoicingCatalogItemDetailViewSelector';
|
|
1213
1213
|
export { clearInvoicingSettings, connectInvoicingStripe, disconnectInvoicingStripe, fetchInvoicingSettings, resetInvoicingBrandingFormDraft, resetSaveInvoicingSettings, saveInvoicingSettings, submitInvoicingBrandingForm, updateInvoicingBrandingFormDraft, updateInvoicingSettings, } from './view/invoicing/settingsView/settingsViewReducer';
|
|
1214
|
-
export { getInvoicingBrandingFormView, getInvoicingSettings, getInvoicingSettingsFetchState, getInvoicingSettingsView, } from './view/invoicing/settingsView/settingsViewSelector';
|
|
1215
|
-
export type { InvoicingBrandingFormView, InvoicingSettingsView, } from './view/invoicing/settingsView/settingsViewSelector';
|
|
1214
|
+
export { getInvoicingBrandingFormView, getInvoicingSettings, getInvoicingSettingsFetchState, getInvoicingSettingsHubView, getInvoicingSettingsView, } from './view/invoicing/settingsView/settingsViewSelector';
|
|
1215
|
+
export type { InvoicingBrandingFormView, InvoicingSettingsHubView, InvoicingSettingsView, } from './view/invoicing/settingsView/settingsViewSelector';
|
|
1216
1216
|
export type { InvoicingBrandingFormLocalData } from './view/invoicing/settingsView/invoicingBrandingFormConfig';
|
|
1217
1217
|
export { INVOICING_BUSINESS_ADDRESS_TYPE, entityToInvoicingBrandingFormLocalData, initialInvoicingBrandingFormLocalData, } from './view/invoicing/settingsView/invoicingBrandingFormConfig';
|
|
1218
1218
|
export { isStripeConnectedFromSettings } from './view/invoicing/settingsView/invoicingSettingsHelpers';
|
package/lib/index.js
CHANGED
|
@@ -84,7 +84,7 @@ exports.updateInvoicingCustomerFilters = exports.setInvoicingCustomerActiveTab =
|
|
|
84
84
|
exports.updateInvoicingTransactionFilters = exports.setInvoicingTransactionActiveTab = exports.fetchInvoicingTransactionListPage = exports.fetchInvoicingTransactionList = exports.clearInvoicingTransactionListView = exports.updateInvoicingTransactions = exports.removeInvoicingTransaction = exports.clearAllInvoicingTransactions = exports.getInvoicingSubscriptionDetail = exports.getInvoicingSubscriptionById = exports.fetchInvoicingSubscriptionDetail = exports.clearInvoicingSubscriptionDetailView = exports.getInvoicingSubscriptionListView = exports.INVOICING_SUBSCRIPTION_TABS = exports.INVOICING_SUBSCRIPTION_COLUMNS = exports.ALL_INVOICING_SUBSCRIPTION_TAB_IDS = exports.ALL_INVOICING_SUBSCRIPTION_SORT_KEYS = exports.updateInvoicingSubscriptionFilters = exports.setInvoicingSubscriptionActiveTab = exports.fetchInvoicingSubscriptionListPage = exports.fetchInvoicingSubscriptionList = exports.fetchInvoicingSubscriptionCounts = exports.clearInvoicingSubscriptionListView = exports.updateInvoicingSubscriptions = exports.removeInvoicingSubscription = exports.clearAllInvoicingSubscriptions = exports.resetPromotionalCreditAction = exports.submitAddPromotionalCredits = exports.getInvoicingSetupIntentFetchState = exports.getInvoicingSetupIntent = exports.getInvoicingSentPaymentLinkMagicUrl = exports.getInvoicingSentPaymentLinkEmail = exports.getInvoicingPlaidLinkTokenFetchState = exports.getInvoicingPlaidLinkToken = exports.getInvoicingPaymentMethodSaveState = exports.getInvoicingPaymentLinkSendState = exports.sendInvoicingPaymentLink = exports.saveInvoicingPaymentMethod = exports.resetInvoicingCustomerPaymentMethod = exports.fetchInvoicingPlaidLinkToken = exports.createInvoicingSetupIntent = exports.getInvoicingCustomerDetail = exports.fetchInvoicingCustomerDetailPage = exports.fetchInvoicingCustomerDetail = exports.clearInvoicingCustomerDetailView = exports.getInvoicingCustomerListView = exports.INVOICING_CUSTOMER_TABS = exports.INVOICING_CUSTOMER_COLUMNS = exports.ALL_INVOICING_CUSTOMER_TAB_IDS = exports.ALL_INVOICING_CUSTOMER_SORT_KEYS = void 0;
|
|
85
85
|
exports.fetchInvoicingCouponDetail = exports.clearInvoicingCouponDetailView = exports.getInvoicingCouponById = exports.getInvoicingCouponListView = exports.getInvoicingCouponListNextCursor = exports.getInvoicingCouponListItems = exports.getInvoicingCouponListHasMore = exports.getInvoicingCouponListFilters = exports.getInvoicingCouponListFetchState = exports.getInvoicingCouponCounts = exports.INVOICING_COUPON_TABS = exports.INVOICING_COUPON_COLUMNS = exports.ALL_INVOICING_COUPON_TAB_IDS = exports.ALL_INVOICING_COUPON_SORT_KEYS = exports.updateInvoicingCouponFilters = exports.setInvoicingCouponActiveTab = exports.fetchInvoicingCouponListPage = exports.fetchInvoicingCouponList = exports.fetchInvoicingCouponCounts = exports.clearInvoicingCouponView = exports.updateInvoicingCoupons = exports.removeInvoicingCoupon = exports.clearAllInvoicingCoupons = exports.getInvoicingCreditNoteDetail = exports.getInvoicingCreditNoteById = exports.fetchInvoicingCreditNoteDetail = exports.clearInvoicingCreditNoteDetailView = exports.getInvoicingCreditNoteListView = exports.INVOICING_CREDIT_NOTE_TABS = exports.INVOICING_CREDIT_NOTE_COLUMNS = exports.ALL_INVOICING_CREDIT_NOTE_TAB_IDS = exports.ALL_INVOICING_CREDIT_NOTE_SORT_KEYS = exports.updateInvoicingCreditNoteFilters = exports.setInvoicingCreditNoteActiveTab = exports.fetchInvoicingCreditNoteListPage = exports.fetchInvoicingCreditNoteList = exports.fetchInvoicingCreditNoteCounts = exports.clearInvoicingCreditNoteListView = exports.updateInvoicingCreditNotes = exports.removeInvoicingCreditNote = exports.clearAllInvoicingCreditNotes = exports.getInvoicingTransactionDetail = exports.getInvoicingTransactionById = exports.fetchInvoicingTransactionDetail = exports.clearInvoicingTransactionDetailView = exports.getInvoicingTransactionListView = exports.INVOICING_TRANSACTION_TABS = exports.INVOICING_TRANSACTION_COLUMNS = exports.ALL_INVOICING_TRANSACTION_TAB_IDS = exports.ALL_INVOICING_TRANSACTION_SORT_KEYS = void 0;
|
|
86
86
|
exports.resetSaveInvoicingSettings = exports.resetInvoicingBrandingFormDraft = exports.fetchInvoicingSettings = exports.disconnectInvoicingStripe = exports.connectInvoicingStripe = exports.clearInvoicingSettings = exports.getInvoicingProductById = exports.getInvoicingPlanById = exports.getInvoicingCatalogItemDetail = exports.fetchInvoicingCatalogItemDetail = exports.clearInvoicingCatalogItemDetailView = exports.getInvoicingCatalogListView = exports.INVOICING_PRODUCT_COLUMNS = exports.ALL_INVOICING_PRODUCT_SORT_KEYS = exports.updateInvoicingCatalogProductFilters = exports.updateInvoicingCatalogPlanFilters = exports.fetchInvoicingCatalogProductList = exports.fetchInvoicingCatalogPlanList = exports.fetchInvoicingCatalogListPage = exports.fetchInvoicingCatalogCounts = exports.clearInvoicingCatalogListView = exports.updateInvoicingProducts = exports.removeInvoicingProduct = exports.clearAllInvoicingProducts = exports.updateInvoicingPlans = exports.removeInvoicingPlan = exports.mergeInvoicingPlanSubFamily = exports.clearAllInvoicingPlans = exports.getInvoicingDunningEmailPreview = exports.getInvoicingDunningCaseDetail = exports.getInvoicingDunningCaseById = exports.invalidateInvoicingDunningEmailPreview = exports.fetchInvoicingDunningEmailPreviewPage = exports.fetchInvoicingDunningCaseDetail = exports.clearInvoicingDunningCaseDetailView = exports.getInvoicingDunningCaseListView = exports.INVOICING_DUNNING_CASE_TABS = exports.INVOICING_DUNNING_CASE_COLUMNS = exports.ALL_INVOICING_DUNNING_CASE_TAB_IDS = exports.ALL_INVOICING_DUNNING_CASE_SORT_KEYS = exports.updateInvoicingDunningCaseFilters = exports.setInvoicingDunningCaseActiveTab = exports.fetchInvoicingDunningCaseListPage = exports.fetchInvoicingDunningCaseList = exports.fetchInvoicingDunningCaseCounts = exports.clearInvoicingDunningCaseListView = exports.updateInvoicingDunningCases = exports.removeInvoicingDunningCase = exports.clearAllInvoicingDunningCases = exports.getInvoicingCouponDetail = void 0;
|
|
87
|
-
exports.getInvoicingConfigView = exports.updateInvoicingConfig = exports.resetInvoicingConfigActionStates = exports.fetchInvoicingConfig = exports.enableInvoicing = exports.clearInvoicingConfig = exports.acceptInvoicingTerms = exports.withInvoicingQboAccountMappingId = exports.toInvoicingQboCustomerMatchingMode = exports.getInvoicingQboAccountMappingId = exports.INVOICING_QBO_CUSTOMER_MATCHING_MODES = exports.getInvoicingQboView = exports.startInvoicingQboBackfill = exports.retryInvoicingQboSyncTask = exports.fetchInvoicingQboSyncHealth = exports.fetchInvoicingQboConnection = exports.fetchInvoicingQboClasses = exports.fetchInvoicingQboAccounts = exports.clearInvoicingQboView = exports.isStripeConnectedFromSettings = exports.initialInvoicingBrandingFormLocalData = exports.entityToInvoicingBrandingFormLocalData = exports.INVOICING_BUSINESS_ADDRESS_TYPE = exports.getInvoicingSettingsView = exports.getInvoicingSettingsFetchState = exports.getInvoicingSettings = exports.getInvoicingBrandingFormView = exports.updateInvoicingSettings = exports.updateInvoicingBrandingFormDraft = exports.submitInvoicingBrandingForm = exports.saveInvoicingSettings = void 0;
|
|
87
|
+
exports.getInvoicingConfigView = exports.updateInvoicingConfig = exports.resetInvoicingConfigActionStates = exports.fetchInvoicingConfig = exports.enableInvoicing = exports.clearInvoicingConfig = exports.acceptInvoicingTerms = exports.withInvoicingQboAccountMappingId = exports.toInvoicingQboCustomerMatchingMode = exports.getInvoicingQboAccountMappingId = exports.INVOICING_QBO_CUSTOMER_MATCHING_MODES = exports.getInvoicingQboView = exports.startInvoicingQboBackfill = exports.retryInvoicingQboSyncTask = exports.fetchInvoicingQboSyncHealth = exports.fetchInvoicingQboConnection = exports.fetchInvoicingQboClasses = exports.fetchInvoicingQboAccounts = exports.clearInvoicingQboView = exports.isStripeConnectedFromSettings = exports.initialInvoicingBrandingFormLocalData = exports.entityToInvoicingBrandingFormLocalData = exports.INVOICING_BUSINESS_ADDRESS_TYPE = exports.getInvoicingSettingsView = exports.getInvoicingSettingsHubView = exports.getInvoicingSettingsFetchState = exports.getInvoicingSettings = exports.getInvoicingBrandingFormView = exports.updateInvoicingSettings = exports.updateInvoicingBrandingFormDraft = exports.submitInvoicingBrandingForm = exports.saveInvoicingSettings = void 0;
|
|
88
88
|
const allowedValue_1 = require("./commonStateTypes/allowedValue");
|
|
89
89
|
Object.defineProperty(exports, "isAllowedValueWithCode", { enumerable: true, get: function () { return allowedValue_1.isAllowedValueWithCode; } });
|
|
90
90
|
Object.defineProperty(exports, "isAllowedValueWithID", { enumerable: true, get: function () { return allowedValue_1.isAllowedValueWithID; } });
|
|
@@ -3137,6 +3137,7 @@ var settingsViewSelector_2 = require("./view/invoicing/settingsView/settingsView
|
|
|
3137
3137
|
Object.defineProperty(exports, "getInvoicingBrandingFormView", { enumerable: true, get: function () { return settingsViewSelector_2.getInvoicingBrandingFormView; } });
|
|
3138
3138
|
Object.defineProperty(exports, "getInvoicingSettings", { enumerable: true, get: function () { return settingsViewSelector_2.getInvoicingSettings; } });
|
|
3139
3139
|
Object.defineProperty(exports, "getInvoicingSettingsFetchState", { enumerable: true, get: function () { return settingsViewSelector_2.getInvoicingSettingsFetchState; } });
|
|
3140
|
+
Object.defineProperty(exports, "getInvoicingSettingsHubView", { enumerable: true, get: function () { return settingsViewSelector_2.getInvoicingSettingsHubView; } });
|
|
3140
3141
|
Object.defineProperty(exports, "getInvoicingSettingsView", { enumerable: true, get: function () { return settingsViewSelector_2.getInvoicingSettingsView; } });
|
|
3141
3142
|
var invoicingBrandingFormConfig_1 = require("./view/invoicing/settingsView/invoicingBrandingFormConfig");
|
|
3142
3143
|
Object.defineProperty(exports, "INVOICING_BUSINESS_ADDRESS_TYPE", { enumerable: true, get: function () { return invoicingBrandingFormConfig_1.INVOICING_BUSINESS_ADDRESS_TYPE; } });
|
|
@@ -4,6 +4,7 @@ exports.createCreditNoteEpic = void 0;
|
|
|
4
4
|
const rxjs_1 = require("rxjs");
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
6
|
const creditNoteReducer_1 = require("../../../entity/invoicing/creditNote/creditNoteReducer");
|
|
7
|
+
const snackbarApiError_1 = require("../../../entity/snackbar/snackbarApiError");
|
|
7
8
|
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
8
9
|
const responsePayload_1 = require("../../../responsePayload");
|
|
9
10
|
const createCreditNotePayload_1 = require("./createCreditNotePayload");
|
|
@@ -32,6 +33,7 @@ const createCreditNoteEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, op
|
|
|
32
33
|
messageSection: 'invoicing_credit_note_saved',
|
|
33
34
|
messageText: 'failed',
|
|
34
35
|
type: 'error',
|
|
36
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(response.status),
|
|
35
37
|
}),
|
|
36
38
|
]);
|
|
37
39
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
@@ -6,6 +6,7 @@ const operators_1 = require("rxjs/operators");
|
|
|
6
6
|
const addressReducer_1 = require("../../../entity/address/addressReducer");
|
|
7
7
|
const invoicePayload_1 = require("../../../entity/invoicing/invoice/invoicePayload");
|
|
8
8
|
const invoiceReducer_1 = require("../../../entity/invoicing/invoice/invoiceReducer");
|
|
9
|
+
const snackbarApiError_1 = require("../../../entity/snackbar/snackbarApiError");
|
|
9
10
|
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
10
11
|
const responsePayload_1 = require("../../../responsePayload");
|
|
11
12
|
const invoiceListReducer_1 = require("../invoiceList/invoiceListReducer");
|
|
@@ -39,6 +40,7 @@ const createInvoiceEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, oper
|
|
|
39
40
|
messageSection: 'invoicing_invoice_saved',
|
|
40
41
|
messageText: 'failed',
|
|
41
42
|
type: 'error',
|
|
43
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(response.status),
|
|
42
44
|
}),
|
|
43
45
|
]);
|
|
44
46
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
@@ -4,6 +4,7 @@ exports.runInvoicingDiscountActionEpic = void 0;
|
|
|
4
4
|
const rxjs_1 = require("rxjs");
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
6
|
const couponReducer_1 = require("../../../entity/invoicing/coupon/couponReducer");
|
|
7
|
+
const snackbarApiError_1 = require("../../../entity/snackbar/snackbarApiError");
|
|
7
8
|
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
8
9
|
const responsePayload_1 = require("../../../responsePayload");
|
|
9
10
|
const discountActionReducer_1 = require("./discountActionReducer");
|
|
@@ -17,13 +18,15 @@ const runInvoicingDiscountActionEpic = (actions$, _state$, zeniAPI) => actions$.
|
|
|
17
18
|
const { action: kind, id } = action.payload;
|
|
18
19
|
const requestBody = { action: kind };
|
|
19
20
|
const snackbarSection = SNACKBAR_SECTION_BY_KIND[kind];
|
|
20
|
-
|
|
21
|
+
/** `status` surfaces the platform's error text; omit it to keep the generic copy. */
|
|
22
|
+
const snackbar = (messageText, status) => snackbarSection == null
|
|
21
23
|
? []
|
|
22
24
|
: [
|
|
23
25
|
(0, snackbarReducer_1.openSnackbar)({
|
|
24
26
|
messageSection: snackbarSection,
|
|
25
27
|
messageText,
|
|
26
28
|
type: messageText === 'success' ? 'success' : 'error',
|
|
29
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(status),
|
|
27
30
|
}),
|
|
28
31
|
];
|
|
29
32
|
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/discounts/${encodeURIComponent(id)}/actions`;
|
|
@@ -42,7 +45,7 @@ const runInvoicingDiscountActionEpic = (actions$, _state$, zeniAPI) => actions$.
|
|
|
42
45
|
error: response.status,
|
|
43
46
|
id,
|
|
44
47
|
}),
|
|
45
|
-
...snackbar('failed'),
|
|
48
|
+
...snackbar('failed', response.status),
|
|
46
49
|
]);
|
|
47
50
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
48
51
|
(0, discountActionReducer_1.runInvoicingDiscountActionFailure)({
|
|
@@ -4,6 +4,7 @@ exports.runInvoicingDunningActionEpic = void 0;
|
|
|
4
4
|
const rxjs_1 = require("rxjs");
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
6
|
const dunningCaseReducer_1 = require("../../../entity/invoicing/dunningCase/dunningCaseReducer");
|
|
7
|
+
const snackbarApiError_1 = require("../../../entity/snackbar/snackbarApiError");
|
|
7
8
|
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
8
9
|
const responsePayload_1 = require("../../../responsePayload");
|
|
9
10
|
const dunningActionReducer_1 = require("./dunningActionReducer");
|
|
@@ -18,13 +19,15 @@ const SNACKBAR_SECTION_BY_KIND = {
|
|
|
18
19
|
const runInvoicingDunningActionEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(dunningActionReducer_1.runInvoicingDunningAction.match), (0, operators_1.mergeMap)((action) => {
|
|
19
20
|
const { action: kind, body, id } = action.payload;
|
|
20
21
|
const snackbarSection = SNACKBAR_SECTION_BY_KIND[kind];
|
|
21
|
-
|
|
22
|
+
/** `status` surfaces the platform's error text; omit it to keep the generic copy. */
|
|
23
|
+
const snackbar = (messageText, status) => snackbarSection == null
|
|
22
24
|
? []
|
|
23
25
|
: [
|
|
24
26
|
(0, snackbarReducer_1.openSnackbar)({
|
|
25
27
|
messageSection: snackbarSection,
|
|
26
28
|
messageText,
|
|
27
29
|
type: messageText === 'success' ? 'success' : 'error',
|
|
30
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(status),
|
|
28
31
|
}),
|
|
29
32
|
];
|
|
30
33
|
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/dunning/${encodeURIComponent(id)}/${kind}`;
|
|
@@ -43,7 +46,7 @@ const runInvoicingDunningActionEpic = (actions$, _state$, zeniAPI) => actions$.p
|
|
|
43
46
|
error: response.status,
|
|
44
47
|
id,
|
|
45
48
|
}),
|
|
46
|
-
...snackbar('failed'),
|
|
49
|
+
...snackbar('failed', response.status),
|
|
47
50
|
]);
|
|
48
51
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
49
52
|
(0, dunningActionReducer_1.runInvoicingDunningActionFailure)({
|
|
@@ -83,6 +83,8 @@ const buildSubFamilyPayload = (localData, subFamily, clearEmptyValues) => {
|
|
|
83
83
|
}
|
|
84
84
|
return payload;
|
|
85
85
|
};
|
|
86
|
+
/** `unit` is the item's unit of measure, not a currency; `CURRENCY_CODE` above prices sub-families. */
|
|
87
|
+
const DEFAULT_CATALOG_ITEM_UNIT = 'USD';
|
|
86
88
|
/**
|
|
87
89
|
* Build the parent catalog-item request body from the form draft. Creates omit
|
|
88
90
|
* both parent and sub-family IDs; edits retain returned sub-family IDs.
|
|
@@ -104,10 +106,9 @@ const localDataToSaveInvoicingCatalogItemPayload = (localData, isCreate) => {
|
|
|
104
106
|
if (description != null) {
|
|
105
107
|
itemPayload.description = description;
|
|
106
108
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
109
|
+
// The form no longer collects a unit; an item that already has one keeps it.
|
|
110
|
+
itemPayload.unit =
|
|
111
|
+
trimOrUndefined(localData.unit) ?? DEFAULT_CATALOG_ITEM_UNIT;
|
|
111
112
|
if (localData.itemApplicability === 'restricted' &&
|
|
112
113
|
localData.applicableItems.length > 0) {
|
|
113
114
|
itemPayload.applicable_items = localData.applicableItems;
|
package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js
CHANGED
|
@@ -5,6 +5,7 @@ const rxjs_1 = require("rxjs");
|
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
6
|
const planReducer_1 = require("../../../entity/invoicing/plan/planReducer");
|
|
7
7
|
const productReducer_1 = require("../../../entity/invoicing/product/productReducer");
|
|
8
|
+
const snackbarApiError_1 = require("../../../entity/snackbar/snackbarApiError");
|
|
8
9
|
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
9
10
|
const responsePayload_1 = require("../../../responsePayload");
|
|
10
11
|
const invoicingCatalogListViewReducer_1 = require("../invoicingCatalogListView/invoicingCatalogListViewReducer");
|
|
@@ -48,6 +49,7 @@ const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actions$.pip
|
|
|
48
49
|
messageSection: 'invoicing_catalog_item_saved',
|
|
49
50
|
messageText: 'failed',
|
|
50
51
|
type: 'error',
|
|
52
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(failedProductResponse.status),
|
|
51
53
|
}),
|
|
52
54
|
]);
|
|
53
55
|
}
|
|
@@ -97,6 +99,7 @@ const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actions$.pip
|
|
|
97
99
|
messageSection: 'invoicing_catalog_item_saved',
|
|
98
100
|
messageText: 'failed',
|
|
99
101
|
type: 'error',
|
|
102
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(response.status),
|
|
100
103
|
}),
|
|
101
104
|
]);
|
|
102
105
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
@@ -4,6 +4,7 @@ exports.saveInvoicingCouponEpic = void 0;
|
|
|
4
4
|
const rxjs_1 = require("rxjs");
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
6
|
const couponReducer_1 = require("../../../entity/invoicing/coupon/couponReducer");
|
|
7
|
+
const snackbarApiError_1 = require("../../../entity/snackbar/snackbarApiError");
|
|
7
8
|
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
8
9
|
const responsePayload_1 = require("../../../responsePayload");
|
|
9
10
|
const couponViewReducer_1 = require("../couponView/couponViewReducer");
|
|
@@ -60,6 +61,7 @@ const saveInvoicingCouponEpic = (actions$, state$, zeniAPI) => actions$.pipe((0,
|
|
|
60
61
|
messageSection: 'invoicing_coupon_saved',
|
|
61
62
|
messageText: 'failed',
|
|
62
63
|
type: 'error',
|
|
64
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(response.status),
|
|
63
65
|
}),
|
|
64
66
|
]);
|
|
65
67
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
@@ -6,6 +6,7 @@ const operators_1 = require("rxjs/operators");
|
|
|
6
6
|
const addressReducer_1 = require("../../../entity/address/addressReducer");
|
|
7
7
|
const invoicingCustomerPayload_1 = require("../../../entity/invoicing/invoicingCustomer/invoicingCustomerPayload");
|
|
8
8
|
const invoicingCustomerReducer_1 = require("../../../entity/invoicing/invoicingCustomer/invoicingCustomerReducer");
|
|
9
|
+
const snackbarApiError_1 = require("../../../entity/snackbar/snackbarApiError");
|
|
9
10
|
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
10
11
|
const responsePayload_1 = require("../../../responsePayload");
|
|
11
12
|
const addressViewReducer_1 = require("../../addressView/addressViewReducer");
|
|
@@ -62,6 +63,7 @@ const saveInvoicingCustomerEpic = (actions$, state$, zeniAPI) => actions$.pipe((
|
|
|
62
63
|
messageSection: 'invoicing_customer_saved',
|
|
63
64
|
messageText: 'failed',
|
|
64
65
|
type: 'error',
|
|
66
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(response.status),
|
|
65
67
|
}),
|
|
66
68
|
]);
|
|
67
69
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js
CHANGED
|
@@ -6,6 +6,7 @@ const operators_1 = require("rxjs/operators");
|
|
|
6
6
|
const addressReducer_1 = require("../../../entity/address/addressReducer");
|
|
7
7
|
const invoicingSubscriptionPayload_1 = require("../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload");
|
|
8
8
|
const invoicingSubscriptionReducer_1 = require("../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionReducer");
|
|
9
|
+
const snackbarApiError_1 = require("../../../entity/snackbar/snackbarApiError");
|
|
9
10
|
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
10
11
|
const responsePayload_1 = require("../../../responsePayload");
|
|
11
12
|
const addressViewReducer_1 = require("../../addressView/addressViewReducer");
|
|
@@ -48,6 +49,7 @@ const saveInvoicingSubscriptionEpic = (actions$, state$, zeniAPI) => actions$.pi
|
|
|
48
49
|
messageSection: 'invoicing_subscription_saved',
|
|
49
50
|
messageText: 'failed',
|
|
50
51
|
type: 'error',
|
|
52
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(response.status),
|
|
51
53
|
}),
|
|
52
54
|
];
|
|
53
55
|
}
|
|
@@ -6,6 +6,7 @@ const operators_1 = require("rxjs/operators");
|
|
|
6
6
|
const addressReducer_1 = require("../../../entity/address/addressReducer");
|
|
7
7
|
const invoicePayload_1 = require("../../../entity/invoicing/invoice/invoicePayload");
|
|
8
8
|
const invoiceReducer_1 = require("../../../entity/invoicing/invoice/invoiceReducer");
|
|
9
|
+
const snackbarApiError_1 = require("../../../entity/snackbar/snackbarApiError");
|
|
9
10
|
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
10
11
|
const responsePayload_1 = require("../../../responsePayload");
|
|
11
12
|
const invoiceActionReducer_1 = require("./invoiceActionReducer");
|
|
@@ -19,13 +20,15 @@ const runInvoicingInvoiceActionEpic = (actions$, _state$, zeniAPI) => actions$.p
|
|
|
19
20
|
action.payload.action !== 'issue-credit-note'), (0, operators_1.mergeMap)((action) => {
|
|
20
21
|
const { action: kind, body, invoiceId } = action.payload;
|
|
21
22
|
const snackbarSection = SNACKBAR_SECTION_BY_KIND[kind];
|
|
22
|
-
|
|
23
|
+
/** `status` surfaces the platform's error text; omit it to keep the generic copy. */
|
|
24
|
+
const snackbar = (messageText, status) => snackbarSection == null
|
|
23
25
|
? []
|
|
24
26
|
: [
|
|
25
27
|
(0, snackbarReducer_1.openSnackbar)({
|
|
26
28
|
messageSection: snackbarSection,
|
|
27
29
|
messageText,
|
|
28
30
|
type: messageText === 'success' ? 'success' : 'error',
|
|
31
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(status),
|
|
29
32
|
}),
|
|
30
33
|
];
|
|
31
34
|
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/invoices/${encodeURIComponent(invoiceId)}/${kind}`;
|
|
@@ -45,7 +48,7 @@ const runInvoicingInvoiceActionEpic = (actions$, _state$, zeniAPI) => actions$.p
|
|
|
45
48
|
error: response.status,
|
|
46
49
|
invoiceId,
|
|
47
50
|
}),
|
|
48
|
-
...snackbar('failed'),
|
|
51
|
+
...snackbar('failed', response.status),
|
|
49
52
|
]);
|
|
50
53
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
51
54
|
(0, invoiceActionReducer_1.runInvoicingInvoiceActionFailure)({
|
|
@@ -84,6 +87,7 @@ const updateInvoicingInvoiceEpic = (actions$, _state$, zeniAPI) => actions$.pipe
|
|
|
84
87
|
messageSection: 'invoicing_invoice_saved',
|
|
85
88
|
messageText: 'failed',
|
|
86
89
|
type: 'error',
|
|
90
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(response.status),
|
|
87
91
|
}),
|
|
88
92
|
]);
|
|
89
93
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.retryInvoicingQboSyncTaskEpic = void 0;
|
|
4
4
|
const rxjs_1 = require("rxjs");
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const snackbarApiError_1 = require("../../../../entity/snackbar/snackbarApiError");
|
|
6
7
|
const snackbarReducer_1 = require("../../../../entity/snackbar/snackbarReducer");
|
|
7
8
|
const responsePayload_1 = require("../../../../responsePayload");
|
|
8
9
|
const invoicingQboViewReducer_1 = require("../invoicingQboViewReducer");
|
|
@@ -31,6 +32,7 @@ const retryInvoicingQboSyncTaskEpic = (actions$, _state$, zeniAPI) => actions$.p
|
|
|
31
32
|
messageSection: 'invoicing_qbo_sync_health_retry',
|
|
32
33
|
messageText: 'failed',
|
|
33
34
|
type: 'error',
|
|
35
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(response.status),
|
|
34
36
|
}),
|
|
35
37
|
]);
|
|
36
38
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.startInvoicingQboBackfillEpic = void 0;
|
|
4
4
|
const rxjs_1 = require("rxjs");
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const snackbarApiError_1 = require("../../../../entity/snackbar/snackbarApiError");
|
|
6
7
|
const snackbarReducer_1 = require("../../../../entity/snackbar/snackbarReducer");
|
|
7
8
|
const responsePayload_1 = require("../../../../responsePayload");
|
|
8
9
|
const invoicingQboViewReducer_1 = require("../invoicingQboViewReducer");
|
|
@@ -30,6 +31,7 @@ const startInvoicingQboBackfillEpic = (actions$, _state$, zeniAPI) => actions$.p
|
|
|
30
31
|
messageSection: 'invoicing_qbo_backfill',
|
|
31
32
|
messageText: 'failed',
|
|
32
33
|
type: 'error',
|
|
34
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(response.status),
|
|
33
35
|
}),
|
|
34
36
|
]);
|
|
35
37
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
@@ -4,6 +4,7 @@ exports.issueCreditNoteEpic = void 0;
|
|
|
4
4
|
const rxjs_1 = require("rxjs");
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
6
|
const creditNoteReducer_1 = require("../../../entity/invoicing/creditNote/creditNoteReducer");
|
|
7
|
+
const snackbarApiError_1 = require("../../../entity/snackbar/snackbarApiError");
|
|
7
8
|
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
8
9
|
const responsePayload_1 = require("../../../responsePayload");
|
|
9
10
|
const invoiceDetailReducer_1 = require("../invoiceDetail/invoiceDetailReducer");
|
|
@@ -35,6 +36,7 @@ const issueCreditNoteEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, ope
|
|
|
35
36
|
messageSection: 'invoicing_credit_note_saved',
|
|
36
37
|
messageText: 'failed',
|
|
37
38
|
type: 'error',
|
|
39
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(response.status),
|
|
38
40
|
}),
|
|
39
41
|
]);
|
|
40
42
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
@@ -5,6 +5,7 @@ const rxjs_1 = require("rxjs");
|
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
6
|
const invoiceReducer_1 = require("../../../entity/invoicing/invoice/invoiceReducer");
|
|
7
7
|
const invoicingTransactionReducer_1 = require("../../../entity/invoicing/invoicingTransaction/invoicingTransactionReducer");
|
|
8
|
+
const snackbarApiError_1 = require("../../../entity/snackbar/snackbarApiError");
|
|
8
9
|
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
9
10
|
const responsePayload_1 = require("../../../responsePayload");
|
|
10
11
|
const invoiceDetailReducer_1 = require("../invoiceDetail/invoiceDetailReducer");
|
|
@@ -43,6 +44,7 @@ const recordPaymentEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, opera
|
|
|
43
44
|
messageSection: 'invoicing_payment_recorded',
|
|
44
45
|
messageText: 'failed',
|
|
45
46
|
type: 'error',
|
|
47
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(response.status),
|
|
46
48
|
}),
|
|
47
49
|
]);
|
|
48
50
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
@@ -85,6 +87,7 @@ const recordPaymentEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, opera
|
|
|
85
87
|
messageSection: 'invoicing_payment_recorded',
|
|
86
88
|
messageText: 'failed',
|
|
87
89
|
type: 'error',
|
|
90
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(response.status),
|
|
88
91
|
}),
|
|
89
92
|
]);
|
|
90
93
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
@@ -4,6 +4,7 @@ exports.saveInvoicingSettingsEpic = exports.disconnectInvoicingStripeEpic = expo
|
|
|
4
4
|
const rxjs_1 = require("rxjs");
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
6
|
const addressReducer_1 = require("../../../entity/address/addressReducer");
|
|
7
|
+
const snackbarApiError_1 = require("../../../entity/snackbar/snackbarApiError");
|
|
7
8
|
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
8
9
|
const responsePayload_1 = require("../../../responsePayload");
|
|
9
10
|
const settingsViewReducer_1 = require("./settingsViewReducer");
|
|
@@ -65,13 +66,15 @@ exports.disconnectInvoicingStripeEpic = disconnectInvoicingStripeEpic;
|
|
|
65
66
|
const saveInvoicingSettingsEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(settingsViewReducer_1.saveInvoicingSettings.match), (0, operators_1.mergeMap)((action) => {
|
|
66
67
|
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/settings`;
|
|
67
68
|
const { settings, snackbarSection } = action.payload;
|
|
68
|
-
|
|
69
|
+
/** `status` surfaces the platform's error text; omit it to keep the generic copy. */
|
|
70
|
+
const snackbar = (messageText, status) => snackbarSection == null
|
|
69
71
|
? []
|
|
70
72
|
: [
|
|
71
73
|
(0, snackbarReducer_1.openSnackbar)({
|
|
72
74
|
messageSection: snackbarSection,
|
|
73
75
|
messageText,
|
|
74
76
|
type: messageText === 'success' ? 'success' : 'error',
|
|
77
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(status),
|
|
75
78
|
}),
|
|
76
79
|
];
|
|
77
80
|
return zeniAPI
|
|
@@ -85,7 +88,7 @@ const saveInvoicingSettingsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(
|
|
|
85
88
|
}
|
|
86
89
|
return (0, rxjs_1.from)([
|
|
87
90
|
(0, settingsViewReducer_1.saveInvoicingSettingsFailure)(response.status),
|
|
88
|
-
...snackbar('failed'),
|
|
91
|
+
...snackbar('failed', response.status),
|
|
89
92
|
]);
|
|
90
93
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
91
94
|
(0, settingsViewReducer_1.saveInvoicingSettingsFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Save settings REST API call errored out ' +
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { FetchState, FetchStateAndError } from '../../../commonStateTypes/common';
|
|
2
|
-
import { InvoicingNamedOption, InvoicingSettingsPayload } from '../../../entity/invoicing/invoicingCommonPayload';
|
|
2
|
+
import { InvoicingNamedOption, InvoicingQboAccountMappingKindOption, InvoicingSettingsPayload } from '../../../entity/invoicing/invoicingCommonPayload';
|
|
3
3
|
import { RootState } from '../../../reducer';
|
|
4
4
|
import { ZeniAPIStatus } from '../../../responsePayload';
|
|
5
|
+
import { InvoicingOnboardingStatus } from '../invoicingConfigView/invoicingConfigViewPayload';
|
|
5
6
|
import { InvoicingBrandingFormLocalData } from './invoicingBrandingFormConfig';
|
|
6
7
|
/**
|
|
7
8
|
* Shared primitive: the raw invoicing settings. Consumed internally by other
|
|
@@ -27,6 +28,45 @@ export interface InvoicingSettingsView {
|
|
|
27
28
|
* Stripe-connect fetch state.
|
|
28
29
|
*/
|
|
29
30
|
export declare const getInvoicingSettingsView: (state: RootState) => InvoicingSettingsView;
|
|
31
|
+
export interface InvoicingEnablePrerequisites {
|
|
32
|
+
canEnable: boolean;
|
|
33
|
+
isQboConfigured: boolean;
|
|
34
|
+
isStripeConnected: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Gates the Enable Invoicing action: payments must be able to land (Stripe
|
|
38
|
+
* connected *and* accepting charges) and the QBO accounting step must be
|
|
39
|
+
* finished, so an enabled tenant can always book what it invoices.
|
|
40
|
+
*
|
|
41
|
+
* Deliberately not part of `deriveInvoicingOnboardingStatus`, which routes the
|
|
42
|
+
* module off the config flags alone. Folding these in there would (a) demote a
|
|
43
|
+
* live tenant to the settings tree the moment an integration broke, stranding
|
|
44
|
+
* its existing invoices, and (b) deadlock the route gate, which fetches only the
|
|
45
|
+
* config — never the settings or QBO connection these read.
|
|
46
|
+
*/
|
|
47
|
+
export declare function deriveInvoicingEnablePrerequisites(settings: InvoicingSettingsPayload | undefined, isQboConnected: boolean, qboAccountMappingKindOptions: InvoicingQboAccountMappingKindOption[]): InvoicingEnablePrerequisites;
|
|
48
|
+
export interface InvoicingSettingsHubView {
|
|
49
|
+
canEnableInvoicing: boolean;
|
|
50
|
+
isEnablingInvoicing: boolean;
|
|
51
|
+
isQboConfigured: boolean;
|
|
52
|
+
isStripeConnected: boolean;
|
|
53
|
+
status?: InvoicingOnboardingStatus;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The settings hub's composite of everything it derives from the store: whether
|
|
57
|
+
* to offer Enable Invoicing at all, the in-flight flag for that action, and the
|
|
58
|
+
* two integration prerequisites kept separate so the hub can name the step still
|
|
59
|
+
* outstanding instead of showing a dead button.
|
|
60
|
+
*
|
|
61
|
+
* `canEnableInvoicing` folds in the onboarding step, so the screen does not need
|
|
62
|
+
* to re-check it: the footer is only offered mid-onboarding and only once both
|
|
63
|
+
* integrations are ready.
|
|
64
|
+
*
|
|
65
|
+
* Deliberately not folded into `getInvoicingConfigView`: that selector gates
|
|
66
|
+
* every invoicing route and stays a pure read of the config slice. The settings
|
|
67
|
+
* and QBO slices read here are only fetched once a settings screen is mounted.
|
|
68
|
+
*/
|
|
69
|
+
export declare const getInvoicingSettingsHubView: (state: RootState) => InvoicingSettingsHubView;
|
|
30
70
|
export interface InvoicingBrandingFormView {
|
|
31
71
|
dateFormatOptions: InvoicingNamedOption[];
|
|
32
72
|
localData: InvoicingBrandingFormLocalData;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getInvoicingBrandingFormView = exports.getInvoicingSettingsView = exports.getInvoicingSettingsFetchState = exports.getInvoicingSettings = void 0;
|
|
3
|
+
exports.getInvoicingBrandingFormView = exports.getInvoicingSettingsHubView = exports.getInvoicingSettingsView = exports.getInvoicingSettingsFetchState = exports.getInvoicingSettings = void 0;
|
|
4
|
+
exports.deriveInvoicingEnablePrerequisites = deriveInvoicingEnablePrerequisites;
|
|
5
|
+
const invoicingCommonPayload_1 = require("../../../entity/invoicing/invoicingCommonPayload");
|
|
4
6
|
const addressViewSelector_1 = require("../../addressView/addressViewSelector");
|
|
5
7
|
const invoicingConfigViewSelector_1 = require("../invoicingConfigView/invoicingConfigViewSelector");
|
|
6
8
|
const invoicingBrandingFormConfig_1 = require("./invoicingBrandingFormConfig");
|
|
@@ -36,6 +38,58 @@ const getInvoicingSettingsView = (state) => {
|
|
|
36
38
|
};
|
|
37
39
|
};
|
|
38
40
|
exports.getInvoicingSettingsView = getInvoicingSettingsView;
|
|
41
|
+
/**
|
|
42
|
+
* Gates the Enable Invoicing action: payments must be able to land (Stripe
|
|
43
|
+
* connected *and* accepting charges) and the QBO accounting step must be
|
|
44
|
+
* finished, so an enabled tenant can always book what it invoices.
|
|
45
|
+
*
|
|
46
|
+
* Deliberately not part of `deriveInvoicingOnboardingStatus`, which routes the
|
|
47
|
+
* module off the config flags alone. Folding these in there would (a) demote a
|
|
48
|
+
* live tenant to the settings tree the moment an integration broke, stranding
|
|
49
|
+
* its existing invoices, and (b) deadlock the route gate, which fetches only the
|
|
50
|
+
* config — never the settings or QBO connection these read.
|
|
51
|
+
*/
|
|
52
|
+
function deriveInvoicingEnablePrerequisites(settings, isQboConnected, qboAccountMappingKindOptions) {
|
|
53
|
+
const isStripeConnected = settings?.stripe_connected === true &&
|
|
54
|
+
settings?.stripe_account?.charges_enabled === true;
|
|
55
|
+
const accountMappings = settings?.qbo?.account_mappings ?? undefined;
|
|
56
|
+
// An empty option list means the config has not landed yet — treating that as
|
|
57
|
+
// configured would let `every` pass vacuously and unlock the button early.
|
|
58
|
+
const isQboConfigured = isQboConnected &&
|
|
59
|
+
qboAccountMappingKindOptions.length > 0 &&
|
|
60
|
+
qboAccountMappingKindOptions.every((option) => (0, invoicingCommonPayload_1.getInvoicingQboAccountMappingId)(accountMappings, option.code) != null);
|
|
61
|
+
return {
|
|
62
|
+
canEnable: isStripeConnected && isQboConfigured,
|
|
63
|
+
isQboConfigured,
|
|
64
|
+
isStripeConnected,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The settings hub's composite of everything it derives from the store: whether
|
|
69
|
+
* to offer Enable Invoicing at all, the in-flight flag for that action, and the
|
|
70
|
+
* two integration prerequisites kept separate so the hub can name the step still
|
|
71
|
+
* outstanding instead of showing a dead button.
|
|
72
|
+
*
|
|
73
|
+
* `canEnableInvoicing` folds in the onboarding step, so the screen does not need
|
|
74
|
+
* to re-check it: the footer is only offered mid-onboarding and only once both
|
|
75
|
+
* integrations are ready.
|
|
76
|
+
*
|
|
77
|
+
* Deliberately not folded into `getInvoicingConfigView`: that selector gates
|
|
78
|
+
* every invoicing route and stays a pure read of the config slice. The settings
|
|
79
|
+
* and QBO slices read here are only fetched once a settings screen is mounted.
|
|
80
|
+
*/
|
|
81
|
+
const getInvoicingSettingsHubView = (state) => {
|
|
82
|
+
const { enableState, qboAccountMappingKindOptions, status } = (0, invoicingConfigViewSelector_1.getInvoicingConfigView)(state);
|
|
83
|
+
const { canEnable, isQboConfigured, isStripeConnected } = deriveInvoicingEnablePrerequisites(state.invoicingSettingsViewState.settings, state.invoicingQboViewState.connection?.connected === true, qboAccountMappingKindOptions);
|
|
84
|
+
return {
|
|
85
|
+
canEnableInvoicing: status === 'settings' && canEnable,
|
|
86
|
+
isEnablingInvoicing: enableState.fetchState === 'In-Progress',
|
|
87
|
+
isQboConfigured,
|
|
88
|
+
isStripeConnected,
|
|
89
|
+
status,
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
exports.getInvoicingSettingsHubView = getInvoicingSettingsHubView;
|
|
39
93
|
/**
|
|
40
94
|
* Bundled view for the branding settings form: the draft `localData` (seeded
|
|
41
95
|
* from the existing settings until the user edits), the business-address label
|
|
@@ -6,6 +6,7 @@ const operators_1 = require("rxjs/operators");
|
|
|
6
6
|
const addressReducer_1 = require("../../../entity/address/addressReducer");
|
|
7
7
|
const invoicingSubscriptionPayload_1 = require("../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload");
|
|
8
8
|
const invoicingSubscriptionReducer_1 = require("../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionReducer");
|
|
9
|
+
const snackbarApiError_1 = require("../../../entity/snackbar/snackbarApiError");
|
|
9
10
|
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
10
11
|
const responsePayload_1 = require("../../../responsePayload");
|
|
11
12
|
const subscriptionActionReducer_1 = require("./subscriptionActionReducer");
|
|
@@ -27,13 +28,15 @@ const runInvoicingSubscriptionActionEpic = (actions$, _state$, zeniAPI) => actio
|
|
|
27
28
|
const { action: kind, body, id } = action.payload;
|
|
28
29
|
const requestBody = { action: kind, ...(body ?? {}) };
|
|
29
30
|
const snackbarSection = SNACKBAR_SECTION_BY_ACTION[kind];
|
|
30
|
-
|
|
31
|
+
/** `status` surfaces the platform's error text; omit it to keep the generic copy. */
|
|
32
|
+
const snackbar = (messageText, status) => snackbarSection == null
|
|
31
33
|
? []
|
|
32
34
|
: [
|
|
33
35
|
(0, snackbarReducer_1.openSnackbar)({
|
|
34
36
|
messageSection: snackbarSection,
|
|
35
37
|
messageText,
|
|
36
38
|
type: messageText === 'success' ? 'success' : 'error',
|
|
39
|
+
variables: (0, snackbarApiError_1.apiErrorSnackbarVariables)(status),
|
|
37
40
|
}),
|
|
38
41
|
];
|
|
39
42
|
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/subscriptions/${encodeURIComponent(id)}/actions`;
|
|
@@ -53,7 +56,7 @@ const runInvoicingSubscriptionActionEpic = (actions$, _state$, zeniAPI) => actio
|
|
|
53
56
|
error: response.status,
|
|
54
57
|
id,
|
|
55
58
|
}),
|
|
56
|
-
...snackbar('failed'),
|
|
59
|
+
...snackbar('failed', response.status),
|
|
57
60
|
]);
|
|
58
61
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
59
62
|
(0, subscriptionActionReducer_1.runInvoicingSubscriptionActionFailure)({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeniai/client-epic-state",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.92",
|
|
4
4
|
"description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/esm/index.js",
|