@zeniai/client-epic-state 5.2.11 → 5.2.12
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/invoicing/invoicingCommonPayload.d.ts +27 -29
- package/lib/entity/invoicing/invoicingCommonPayload.js +37 -75
- package/lib/entity/invoicing/product/productPayload.d.ts +10 -0
- package/lib/entity/invoicing/product/productPayload.js +14 -2
- package/lib/epic.d.ts +1 -1
- package/lib/epic.js +10 -5
- package/lib/esm/entity/invoicing/invoicingCommonPayload.js +33 -73
- package/lib/esm/entity/invoicing/product/productPayload.js +14 -2
- package/lib/esm/epic.js +6 -1
- package/lib/esm/index.js +5 -4
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +25 -9
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +6 -1
- package/lib/esm/view/invoicing/invoicingQboView/invoicingQboViewSelector.js +40 -0
- package/lib/esm/view/invoicing/settingsView/epics/connectInvoicingStripeEpic.js +27 -0
- package/lib/esm/view/invoicing/settingsView/epics/disconnectInvoicingStripeEpic.js +19 -0
- package/lib/esm/view/invoicing/settingsView/epics/fetchInvoicingSettingsEpic.js +19 -0
- package/lib/esm/view/invoicing/settingsView/epics/saveInvoicingSettingsEpic.js +39 -0
- package/lib/esm/view/invoicing/settingsView/epics/settingsViewActionType.js +1 -0
- package/lib/esm/view/invoicing/settingsView/epics/submitInvoicingQboSettingsEpic.js +25 -0
- package/lib/esm/view/invoicing/settingsView/invoicingQboSettingsFormConfig.js +48 -0
- package/lib/esm/view/invoicing/settingsView/settingsViewReducer.js +25 -1
- package/lib/esm/view/invoicing/settingsView/settingsViewSelector.js +41 -0
- package/lib/index.d.ts +7 -5
- package/lib/index.js +13 -6
- package/lib/view/expenseAutomationView/types/reconciliationViewState.d.ts +1 -1
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.d.ts +12 -1
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +25 -9
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +6 -1
- package/lib/view/invoicing/invoicingQboView/invoicingQboViewSelector.d.ts +10 -1
- package/lib/view/invoicing/invoicingQboView/invoicingQboViewSelector.js +43 -1
- package/lib/view/invoicing/settingsView/epics/connectInvoicingStripeEpic.d.ts +6 -0
- package/lib/view/invoicing/settingsView/epics/connectInvoicingStripeEpic.js +31 -0
- package/lib/view/invoicing/settingsView/epics/disconnectInvoicingStripeEpic.d.ts +6 -0
- package/lib/view/invoicing/settingsView/epics/disconnectInvoicingStripeEpic.js +23 -0
- package/lib/view/invoicing/settingsView/epics/fetchInvoicingSettingsEpic.d.ts +6 -0
- package/lib/view/invoicing/settingsView/epics/fetchInvoicingSettingsEpic.js +23 -0
- package/lib/view/invoicing/settingsView/epics/saveInvoicingSettingsEpic.d.ts +6 -0
- package/lib/view/invoicing/settingsView/epics/saveInvoicingSettingsEpic.js +43 -0
- package/lib/view/invoicing/settingsView/epics/settingsViewActionType.d.ts +5 -0
- package/lib/view/invoicing/settingsView/epics/settingsViewActionType.js +2 -0
- package/lib/view/invoicing/settingsView/epics/submitInvoicingQboSettingsEpic.d.ts +11 -0
- package/lib/view/invoicing/settingsView/epics/submitInvoicingQboSettingsEpic.js +29 -0
- package/lib/view/invoicing/settingsView/invoicingQboSettingsFormConfig.d.ts +34 -0
- package/lib/view/invoicing/settingsView/invoicingQboSettingsFormConfig.js +53 -0
- package/lib/view/invoicing/settingsView/settingsViewReducer.d.ts +4 -1
- package/lib/view/invoicing/settingsView/settingsViewReducer.js +26 -2
- package/lib/view/invoicing/settingsView/settingsViewSelector.d.ts +35 -0
- package/lib/view/invoicing/settingsView/settingsViewSelector.js +43 -1
- package/lib/view/invoicing/settingsView/settingsViewState.d.ts +8 -0
- package/package.json +1 -1
- package/lib/esm/view/invoicing/settingsView/settingsViewEpics.js +0 -92
- package/lib/view/invoicing/settingsView/settingsViewEpics.d.ts +0 -12
- package/lib/view/invoicing/settingsView/settingsViewEpics.js +0 -99
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { toAccountPayload } from '../../../entity/account/accountPayload';
|
|
2
|
+
import { toClassBasePayload } from '../../../entity/class/classPayload';
|
|
1
3
|
import { blankInvoicingCatalogSubFamily, isTieredCatalogPricingModel, } from './invoicingCatalogItemFormConfig';
|
|
2
4
|
const CURRENCY_CODE = 'USD';
|
|
3
5
|
const trimOrUndefined = (value) => value.trim() !== '' ? value.trim() : undefined;
|
|
@@ -7,20 +9,26 @@ const toProductCode = (value) => value
|
|
|
7
9
|
.toLowerCase()
|
|
8
10
|
.replace(/[^a-z0-9]+/g, '-')
|
|
9
11
|
.replace(/^-|-$/g, '');
|
|
10
|
-
const buildAccountingDetail = (subFamily) => {
|
|
12
|
+
const buildAccountingDetail = (subFamily, lookup) => {
|
|
11
13
|
const detail = {};
|
|
12
14
|
if (subFamily.sku.trim() !== '') {
|
|
13
15
|
detail.sku = subFamily.sku.trim();
|
|
14
16
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
// The account and class travel as whole objects rather than bare codes, built
|
|
18
|
+
// by the same helpers the transaction and vendor payloads use. An id that no
|
|
19
|
+
// longer resolves is dropped: sending a code the service cannot expand is how
|
|
20
|
+
// a mapping silently lands on the wrong account.
|
|
21
|
+
const account = lookup.accountByQboId(subFamily.accountingCode.trim());
|
|
22
|
+
if (account != null) {
|
|
23
|
+
detail.account = toAccountPayload(account);
|
|
17
24
|
}
|
|
18
|
-
|
|
19
|
-
|
|
25
|
+
const accountingClass = lookup.classByQboId(subFamily.accountingCategory.trim());
|
|
26
|
+
if (accountingClass != null) {
|
|
27
|
+
detail.accounting_class = toClassBasePayload(accountingClass);
|
|
20
28
|
}
|
|
21
29
|
return Object.keys(detail).length > 0 ? detail : undefined;
|
|
22
30
|
};
|
|
23
|
-
const buildSubFamilyPayload = (localData, subFamily, clearEmptyValues) => {
|
|
31
|
+
const buildSubFamilyPayload = (localData, subFamily, clearEmptyValues, lookup) => {
|
|
24
32
|
const isAddon = localData.catalogType === 'addon';
|
|
25
33
|
const tiered = isTieredCatalogPricingModel(subFamily.pricingModel);
|
|
26
34
|
const name = subFamily.name.trim();
|
|
@@ -74,7 +82,7 @@ const buildSubFamilyPayload = (localData, subFamily, clearEmptyValues) => {
|
|
|
74
82
|
starting_unit: Number(tier.startingUnit) || 1,
|
|
75
83
|
}));
|
|
76
84
|
}
|
|
77
|
-
const accountingDetail = buildAccountingDetail(subFamily);
|
|
85
|
+
const accountingDetail = buildAccountingDetail(subFamily, lookup);
|
|
78
86
|
if (accountingDetail != null) {
|
|
79
87
|
payload.accounting_detail = accountingDetail;
|
|
80
88
|
}
|
|
@@ -86,7 +94,7 @@ const DEFAULT_CATALOG_ITEM_UNIT = 'USD';
|
|
|
86
94
|
* Build the parent catalog-item request body from the form draft. Creates omit
|
|
87
95
|
* both parent and sub-family IDs; edits retain returned sub-family IDs.
|
|
88
96
|
*/
|
|
89
|
-
export const localDataToSaveInvoicingCatalogItemPayload = (localData, isCreate) => {
|
|
97
|
+
export const localDataToSaveInvoicingCatalogItemPayload = (localData, isCreate, lookup) => {
|
|
90
98
|
const description = trimOrUndefined(localData.description);
|
|
91
99
|
const productCode = trimOrUndefined(localData.productCode) ?? toProductCode(localData.name);
|
|
92
100
|
const itemPayload = {
|
|
@@ -114,7 +122,7 @@ export const localDataToSaveInvoicingCatalogItemPayload = (localData, isCreate)
|
|
|
114
122
|
? localData.subFamilies
|
|
115
123
|
: [blankInvoicingCatalogSubFamily()];
|
|
116
124
|
itemPayload.sub_family_details = isCreate
|
|
117
|
-
? subFamilies.map((subFamily) => buildSubFamilyPayload(localData, subFamily, false))
|
|
125
|
+
? subFamilies.map((subFamily) => buildSubFamilyPayload(localData, subFamily, false, lookup))
|
|
118
126
|
: subFamilies.map((subFamily) => {
|
|
119
127
|
const priceCode = trimOrUndefined(subFamily.priceCode) ?? toProductCode(subFamily.name);
|
|
120
128
|
const detail = {
|
|
@@ -124,6 +132,14 @@ export const localDataToSaveInvoicingCatalogItemPayload = (localData, isCreate)
|
|
|
124
132
|
price_code: priceCode,
|
|
125
133
|
show_description_in_invoices: subFamily.showDescriptionInInvoices,
|
|
126
134
|
};
|
|
135
|
+
// Edits send a narrower body than creates, but the accounting mapping
|
|
136
|
+
// is editable on this form, so leaving it out dropped the account and
|
|
137
|
+
// class the user had just picked. `null` rather than omitted when it is
|
|
138
|
+
// empty: an absent key on an update reads as "leave it alone", which
|
|
139
|
+
// would make a cleared mapping impossible to save — the same reason
|
|
140
|
+
// `description` and `invoice_notes` go through `trimOrNull`.
|
|
141
|
+
detail.accounting_detail =
|
|
142
|
+
buildAccountingDetail(subFamily, lookup) ?? null;
|
|
127
143
|
const id = trimOrUndefined(subFamily.id);
|
|
128
144
|
return id != null ? { ...detail, id } : detail;
|
|
129
145
|
});
|
package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js
CHANGED
|
@@ -6,6 +6,7 @@ import { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiE
|
|
|
6
6
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
7
7
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
8
8
|
import { addInvoicingCatalogItem } from '../invoicingCatalogListView/invoicingCatalogListViewReducer';
|
|
9
|
+
import { invoicingQboAccountByQboId, invoicingQboClassByQboId, } from '../invoicingQboView/invoicingQboViewSelector';
|
|
9
10
|
import { localDataToSaveInvoicingCatalogItemPayload, } from './editInvoicingCatalogItemDetailViewPayload';
|
|
10
11
|
import { saveInvoicingCatalogItem, submitInvoicingCatalogItemForm, submitInvoicingCatalogItemFormFailure, submitInvoicingCatalogItemFormSuccess, } from './editInvoicingCatalogItemDetailViewReducer';
|
|
11
12
|
export const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter((action) => submitInvoicingCatalogItemForm.match(action) ||
|
|
@@ -20,7 +21,11 @@ export const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actio
|
|
|
20
21
|
const viewState = state$.value.editInvoicingCatalogItemDetailViewState;
|
|
21
22
|
const localData = (id != null ? viewState.editDraftById[id] : viewState.newItemDraft) ??
|
|
22
23
|
viewState.newItemDraft;
|
|
23
|
-
|
|
24
|
+
const state = state$.value;
|
|
25
|
+
data = localDataToSaveInvoicingCatalogItemPayload(localData, id == null, {
|
|
26
|
+
accountByQboId: (qboId) => invoicingQboAccountByQboId(state, qboId),
|
|
27
|
+
classByQboId: (qboId) => invoicingQboClassByQboId(state, qboId),
|
|
28
|
+
});
|
|
24
29
|
}
|
|
25
30
|
const baseUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0`;
|
|
26
31
|
const path = id != null
|
|
@@ -37,6 +37,46 @@ export const INVOICING_INCOME_ACCOUNT_TYPES = [
|
|
|
37
37
|
'income',
|
|
38
38
|
'other_income',
|
|
39
39
|
];
|
|
40
|
+
/**
|
|
41
|
+
* The account behind a picker value. The pickers submit the QuickBooks id, so
|
|
42
|
+
* that is what callers hold; the payload builders need the whole entity to send
|
|
43
|
+
* `toAccountPayload`, which is why the lookup lives here next to the options.
|
|
44
|
+
*/
|
|
45
|
+
export const invoicingQboAccountByQboId = (state, qboId) => {
|
|
46
|
+
if (qboId == null || qboId === '') {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
// `getAccountList` throws when a listed id is missing from the entity slice.
|
|
50
|
+
// That is survivable when looking one account up — the caller falls back to
|
|
51
|
+
// the id it already had — but not when it happens inside an epic, where the
|
|
52
|
+
// throw would take the whole request with it.
|
|
53
|
+
try {
|
|
54
|
+
const { accounts } = getAccountList(state.accountState, state.accountListState, INVOICING_ACCOUNT_LIST_KEY);
|
|
55
|
+
// Matched on any id the account is known by. The pickers submit `qboId`,
|
|
56
|
+
// but a mapping that arrived from the service can name the account by its
|
|
57
|
+
// platform id instead, and an account we cannot resolve is a mapping that
|
|
58
|
+
// cannot be sent as a record.
|
|
59
|
+
return accounts.find((account) => account.qboId === qboId ||
|
|
60
|
+
account.accountId === qboId ||
|
|
61
|
+
account.coaId === qboId);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
/** The class behind a picker value, for the same reason as the account above. */
|
|
68
|
+
export const invoicingQboClassByQboId = (state, qboId) => {
|
|
69
|
+
if (qboId == null || qboId === '') {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
const { classes } = getClassList(state.classState, state.classListState);
|
|
74
|
+
return classes.find((accountingClass) => accountingClass.qboId === qboId);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
40
80
|
/**
|
|
41
81
|
* Accounts and classes as the invoicing pickers need them. Both come from the
|
|
42
82
|
* shared accounting-service lists, so whatever another screen already loaded
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { of } from 'rxjs';
|
|
2
|
+
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
|
+
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
4
|
+
import { connectInvoicingStripe, fetchInvoicingSettings, invoicingStripeConnectionFailure, updateInvoicingStripeConnection, } from '../settingsViewReducer';
|
|
5
|
+
export const connectInvoicingStripeEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(connectInvoicingStripe.match), mergeMap((action) => {
|
|
6
|
+
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/settings/stripe-connect/setup`;
|
|
7
|
+
const { api_key, publishable_key, webhook_secret } = action.payload;
|
|
8
|
+
const body = {
|
|
9
|
+
api_key,
|
|
10
|
+
publishable_key,
|
|
11
|
+
...(webhook_secret != null && webhook_secret !== ''
|
|
12
|
+
? { webhook_secret }
|
|
13
|
+
: {}),
|
|
14
|
+
};
|
|
15
|
+
return zeniAPI
|
|
16
|
+
.postAndGetJSON(apiUrl, body)
|
|
17
|
+
.pipe(switchMap((response) => {
|
|
18
|
+
if (isSuccessResponse(response) && response.data != null) {
|
|
19
|
+
return of(updateInvoicingStripeConnection({
|
|
20
|
+
stripe_connected: response.data.stripe_connected,
|
|
21
|
+
publishable_key: response.data.publishable_key,
|
|
22
|
+
}), fetchInvoicingSettings());
|
|
23
|
+
}
|
|
24
|
+
return of(invoicingStripeConnectionFailure(response.status));
|
|
25
|
+
}), catchError((error) => of(invoicingStripeConnectionFailure(createZeniAPIStatus('Unexpected Error', 'Stripe connect setup REST API call errored out ' +
|
|
26
|
+
JSON.stringify(error))))));
|
|
27
|
+
}));
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { of } from 'rxjs';
|
|
2
|
+
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
|
+
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
4
|
+
import { disconnectInvoicingStripe, fetchInvoicingSettings, invoicingStripeConnectionFailure, updateInvoicingStripeConnection, } from '../settingsViewReducer';
|
|
5
|
+
export const disconnectInvoicingStripeEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(disconnectInvoicingStripe.match), mergeMap(() => {
|
|
6
|
+
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/settings/stripe-connect/callback`;
|
|
7
|
+
return zeniAPI
|
|
8
|
+
.deleteAndGetJSON(apiUrl)
|
|
9
|
+
.pipe(switchMap((response) => {
|
|
10
|
+
if (isSuccessResponse(response)) {
|
|
11
|
+
return of(updateInvoicingStripeConnection({
|
|
12
|
+
stripe_connected: false,
|
|
13
|
+
publishable_key: '',
|
|
14
|
+
}), fetchInvoicingSettings());
|
|
15
|
+
}
|
|
16
|
+
return of(invoicingStripeConnectionFailure(response.status));
|
|
17
|
+
}), catchError((error) => of(invoicingStripeConnectionFailure(createZeniAPIStatus('Unexpected Error', 'Stripe disconnect REST API call errored out ' +
|
|
18
|
+
JSON.stringify(error))))));
|
|
19
|
+
}));
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { of } from 'rxjs';
|
|
2
|
+
import { catchError, filter, switchMap } from 'rxjs/operators';
|
|
3
|
+
import { updateAddresses } from '../../../../entity/address/addressReducer';
|
|
4
|
+
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
5
|
+
import { fetchInvoicingSettings, updateInvoicingSettings, updateInvoicingSettingsFailure, } from '../settingsViewReducer';
|
|
6
|
+
export const fetchInvoicingSettingsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(fetchInvoicingSettings.match), switchMap(() => {
|
|
7
|
+
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/settings`;
|
|
8
|
+
return zeniAPI.getJSON(apiUrl).pipe(switchMap((response) => {
|
|
9
|
+
if (isSuccessResponse(response) && response.data != null) {
|
|
10
|
+
const address = response.data.address;
|
|
11
|
+
return [
|
|
12
|
+
...(address != null ? [updateAddresses([address])] : []),
|
|
13
|
+
updateInvoicingSettings(response.data),
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
return of(updateInvoicingSettingsFailure(response.status));
|
|
17
|
+
}), catchError((error) => of(updateInvoicingSettingsFailure(createZeniAPIStatus('Unexpected Error', 'Fetch settings REST API call errored out ' +
|
|
18
|
+
JSON.stringify(error))))));
|
|
19
|
+
}));
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { from } from 'rxjs';
|
|
2
|
+
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
|
+
import { apiErrorSnackbarVariables } from '../../../../entity/snackbar/snackbarApiError';
|
|
4
|
+
import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
|
|
5
|
+
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
6
|
+
import { saveInvoicingSettings, saveInvoicingSettingsFailure, saveInvoicingSettingsSuccess, } from '../settingsViewReducer';
|
|
7
|
+
export const saveInvoicingSettingsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(saveInvoicingSettings.match), mergeMap((action) => {
|
|
8
|
+
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/settings`;
|
|
9
|
+
const { settings, snackbarSection } = action.payload;
|
|
10
|
+
/** `status` surfaces the platform's error text; omit it to keep the generic copy. */
|
|
11
|
+
const snackbar = (messageText, status) => snackbarSection == null
|
|
12
|
+
? []
|
|
13
|
+
: [
|
|
14
|
+
openSnackbar({
|
|
15
|
+
messageSection: snackbarSection,
|
|
16
|
+
messageText,
|
|
17
|
+
type: messageText === 'success' ? 'success' : 'error',
|
|
18
|
+
variables: apiErrorSnackbarVariables(status),
|
|
19
|
+
}),
|
|
20
|
+
];
|
|
21
|
+
return zeniAPI
|
|
22
|
+
.putAndGetJSON(apiUrl, { ...settings })
|
|
23
|
+
.pipe(switchMap((response) => {
|
|
24
|
+
if (isSuccessResponse(response) && response.data != null) {
|
|
25
|
+
return from([
|
|
26
|
+
saveInvoicingSettingsSuccess(response.data),
|
|
27
|
+
...snackbar('success'),
|
|
28
|
+
]);
|
|
29
|
+
}
|
|
30
|
+
return from([
|
|
31
|
+
saveInvoicingSettingsFailure(response.status),
|
|
32
|
+
...snackbar('failed', response.status),
|
|
33
|
+
]);
|
|
34
|
+
}), catchError((error) => from([
|
|
35
|
+
saveInvoicingSettingsFailure(createZeniAPIStatus('Unexpected Error', 'Save settings REST API call errored out ' +
|
|
36
|
+
JSON.stringify(error))),
|
|
37
|
+
...snackbar('failed'),
|
|
38
|
+
])));
|
|
39
|
+
}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { EMPTY, of } from 'rxjs';
|
|
2
|
+
import { filter, mergeMap, withLatestFrom } from 'rxjs/operators';
|
|
3
|
+
import { invoicingQboAccountByQboId } from '../../invoicingQboView/invoicingQboViewSelector';
|
|
4
|
+
import { invoicingQboSettingsLocalDataToPayload } from '../invoicingQboSettingsFormConfig';
|
|
5
|
+
import { saveInvoicingSettings, submitInvoicingQboSettings, } from '../settingsViewReducer';
|
|
6
|
+
/**
|
|
7
|
+
* Saves the QBO local data. The screen fires this without a payload — the local
|
|
8
|
+
* data is already in the store, so sending it back through the action would make
|
|
9
|
+
* the page the carrier for state it does not own. Converting to the request body
|
|
10
|
+
* happens here too, keeping the wire shape out of the screen.
|
|
11
|
+
*/
|
|
12
|
+
export const submitInvoicingQboSettingsEpic = (actions$, state$) => actions$.pipe(filter(submitInvoicingQboSettings.match), withLatestFrom(state$), mergeMap(([, state]) => {
|
|
13
|
+
const { qboDraft } = state.invoicingSettingsViewState;
|
|
14
|
+
// No local data means the settings response has not landed, so there is
|
|
15
|
+
// nothing the user could have edited yet.
|
|
16
|
+
if (qboDraft == null) {
|
|
17
|
+
return EMPTY;
|
|
18
|
+
}
|
|
19
|
+
return of(saveInvoicingSettings({
|
|
20
|
+
settings: {
|
|
21
|
+
qbo: invoicingQboSettingsLocalDataToPayload(qboDraft, (accountId) => invoicingQboAccountByQboId(state, accountId)),
|
|
22
|
+
},
|
|
23
|
+
snackbarSection: 'invoicing_qbo_settings_save',
|
|
24
|
+
}));
|
|
25
|
+
}));
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { getInvoicingQboAccountMappingId, toInvoicingQboAccountMappingSlot, toInvoicingQboAccountMappingsPayload, } from '../../../entity/invoicing/invoicingCommonPayload';
|
|
2
|
+
export const initialInvoicingQboSettingsLocalData = {
|
|
3
|
+
accountIdByMappingCode: {},
|
|
4
|
+
autoCreateItems: false,
|
|
5
|
+
closedPeriodVoidAsCreditMemo: false,
|
|
6
|
+
customerMatching: '',
|
|
7
|
+
isSyncEnabled: false,
|
|
8
|
+
syncStartDate: '',
|
|
9
|
+
trackingCategoriesEnabled: false,
|
|
10
|
+
};
|
|
11
|
+
/** The settings response as the page edits it. */
|
|
12
|
+
export const entityToInvoicingQboSettingsLocalData = (qbo) => {
|
|
13
|
+
const accountMappings = qbo?.account_mappings ?? {};
|
|
14
|
+
const accountIdByMappingCode = {};
|
|
15
|
+
// Keyed by the slot the payload used, which is the config code the page will
|
|
16
|
+
// ask for — the reader tolerates the older `_id` form on the way in.
|
|
17
|
+
Object.keys(accountMappings).forEach((key) => {
|
|
18
|
+
const accountId = getInvoicingQboAccountMappingId(accountMappings, key);
|
|
19
|
+
if (accountId != null) {
|
|
20
|
+
accountIdByMappingCode[toInvoicingQboAccountMappingSlot(key)] = accountId;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
return {
|
|
24
|
+
accountIdByMappingCode,
|
|
25
|
+
autoCreateItems: qbo?.auto_create_items === true,
|
|
26
|
+
closedPeriodVoidAsCreditMemo: qbo?.closed_period_void_as_credit_memo === true,
|
|
27
|
+
customerMatching: qbo?.customer_matching ?? '',
|
|
28
|
+
isSyncEnabled: qbo?.enabled === true,
|
|
29
|
+
syncStartDate: qbo?.sync_start_date ?? '',
|
|
30
|
+
trackingCategoriesEnabled: qbo?.tracking_categories_enabled === true,
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The local data as the request body. `accountForId` turns each picked id into
|
|
35
|
+
* the whole account the service stores; it comes from the epic, which is where
|
|
36
|
+
* the account list is in reach.
|
|
37
|
+
*/
|
|
38
|
+
export const invoicingQboSettingsLocalDataToPayload = (localData, accountForId) => {
|
|
39
|
+
return {
|
|
40
|
+
account_mappings: toInvoicingQboAccountMappingsPayload(localData.accountIdByMappingCode, accountForId),
|
|
41
|
+
auto_create_items: localData.autoCreateItems,
|
|
42
|
+
closed_period_void_as_credit_memo: localData.closedPeriodVoidAsCreditMemo,
|
|
43
|
+
customer_matching: localData.customerMatching,
|
|
44
|
+
enabled: localData.isSyncEnabled,
|
|
45
|
+
sync_start_date: localData.syncStartDate !== '' ? localData.syncStartDate : null,
|
|
46
|
+
tracking_categories_enabled: localData.trackingCategoriesEnabled,
|
|
47
|
+
};
|
|
48
|
+
};
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
2
|
import { clearAll } from '../../../rootActions';
|
|
3
|
+
import { entityToInvoicingQboSettingsLocalData, } from './invoicingQboSettingsFormConfig';
|
|
3
4
|
export const initialState = {
|
|
4
5
|
fetchState: 'Not-Started',
|
|
5
6
|
error: undefined,
|
|
6
7
|
saveFetchState: { fetchState: 'Not-Started', error: undefined },
|
|
7
8
|
stripeFetchState: { fetchState: 'Not-Started', error: undefined },
|
|
8
9
|
settings: undefined,
|
|
10
|
+
// Listed so `clearAll` resets them: an in-progress draft left behind by a
|
|
11
|
+
// tenant switch would be shown and saved against the tenant switched to.
|
|
12
|
+
brandingDraft: undefined,
|
|
13
|
+
qboDraft: undefined,
|
|
9
14
|
hasValidState() {
|
|
10
15
|
return this.fetchState === 'Completed' && this.settings != null;
|
|
11
16
|
},
|
|
@@ -22,6 +27,11 @@ const settingsView = createSlice({
|
|
|
22
27
|
draft.settings = action.payload;
|
|
23
28
|
draft.fetchState = 'Completed';
|
|
24
29
|
draft.error = undefined;
|
|
30
|
+
// Seed the QBO page's local data from the response. An edit already in
|
|
31
|
+
// progress wins: a refetch behind the user must not discard it.
|
|
32
|
+
if (draft.qboDraft == null) {
|
|
33
|
+
draft.qboDraft = entityToInvoicingQboSettingsLocalData(action.payload.qbo);
|
|
34
|
+
}
|
|
25
35
|
},
|
|
26
36
|
updateInvoicingSettingsFailure(draft, action) {
|
|
27
37
|
draft.fetchState = 'Error';
|
|
@@ -36,6 +46,9 @@ const settingsView = createSlice({
|
|
|
36
46
|
saveInvoicingSettingsSuccess(draft, action) {
|
|
37
47
|
draft.settings = action.payload;
|
|
38
48
|
draft.saveFetchState = { fetchState: 'Completed', error: undefined };
|
|
49
|
+
// Re-seeded from what was just persisted, so the page keeps working off
|
|
50
|
+
// local data while showing the server's version of it.
|
|
51
|
+
draft.qboDraft = entityToInvoicingQboSettingsLocalData(action.payload.qbo);
|
|
39
52
|
},
|
|
40
53
|
saveInvoicingSettingsFailure(draft, action) {
|
|
41
54
|
draft.saveFetchState = { fetchState: 'Error', error: action.payload };
|
|
@@ -54,6 +67,17 @@ const settingsView = createSlice({
|
|
|
54
67
|
resetInvoicingBrandingFormDraft(draft) {
|
|
55
68
|
draft.brandingDraft = undefined;
|
|
56
69
|
},
|
|
70
|
+
updateInvoicingQboSettingsDraft(draft, action) {
|
|
71
|
+
draft.qboDraft = action.payload.localData;
|
|
72
|
+
},
|
|
73
|
+
// Trigger only — handled by submitInvoicingQboSettingsEpic, which reads the
|
|
74
|
+
// local data and converts it to the request body.
|
|
75
|
+
submitInvoicingQboSettings(draft) {
|
|
76
|
+
draft.saveFetchState = { fetchState: 'In-Progress', error: undefined };
|
|
77
|
+
},
|
|
78
|
+
resetInvoicingQboSettingsDraft(draft) {
|
|
79
|
+
draft.qboDraft = undefined;
|
|
80
|
+
},
|
|
57
81
|
connectInvoicingStripe: {
|
|
58
82
|
reducer(draft) {
|
|
59
83
|
draft.stripeFetchState = { fetchState: 'In-Progress', error: undefined };
|
|
@@ -85,5 +109,5 @@ const settingsView = createSlice({
|
|
|
85
109
|
});
|
|
86
110
|
},
|
|
87
111
|
});
|
|
88
|
-
export const { fetchInvoicingSettings, updateInvoicingSettings, updateInvoicingSettingsFailure, saveInvoicingSettings, saveInvoicingSettingsSuccess, saveInvoicingSettingsFailure, resetSaveInvoicingSettings, updateInvoicingBrandingFormDraft, submitInvoicingBrandingForm, resetInvoicingBrandingFormDraft, connectInvoicingStripe, disconnectInvoicingStripe, updateInvoicingStripeConnection, invoicingStripeConnectionFailure, } = settingsView.actions;
|
|
112
|
+
export const { fetchInvoicingSettings, updateInvoicingSettings, updateInvoicingSettingsFailure, saveInvoicingSettings, saveInvoicingSettingsSuccess, saveInvoicingSettingsFailure, resetSaveInvoicingSettings, updateInvoicingBrandingFormDraft, submitInvoicingBrandingForm, resetInvoicingBrandingFormDraft, updateInvoicingQboSettingsDraft, submitInvoicingQboSettings, resetInvoicingQboSettingsDraft, connectInvoicingStripe, disconnectInvoicingStripe, updateInvoicingStripeConnection, invoicingStripeConnectionFailure, } = settingsView.actions;
|
|
89
113
|
export default settingsView.reducer;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { getInvoicingQboAccountMappingId, } from '../../../entity/invoicing/invoicingCommonPayload';
|
|
2
2
|
import { getFormattedAddress } from '../../addressView/addressViewSelector';
|
|
3
3
|
import { getInvoicingConfigView } from '../invoicingConfigView/invoicingConfigViewSelector';
|
|
4
|
+
import { getInvoicingQboView, isInvoicingAccountingPickerDataLoading, } from '../invoicingQboView/invoicingQboViewSelector';
|
|
4
5
|
import { INVOICING_BUSINESS_ADDRESS_TYPE, entityToInvoicingBrandingFormLocalData, } from './invoicingBrandingFormConfig';
|
|
6
|
+
import { initialInvoicingQboSettingsLocalData, } from './invoicingQboSettingsFormConfig';
|
|
5
7
|
/**
|
|
6
8
|
* Shared primitive: the raw invoicing settings. Consumed internally by other
|
|
7
9
|
* CES selectors (create-invoice, customer-detail, overview) and by non-settings
|
|
@@ -92,6 +94,45 @@ export const getInvoicingSettingsHubView = (state) => {
|
|
|
92
94
|
status,
|
|
93
95
|
};
|
|
94
96
|
};
|
|
97
|
+
/**
|
|
98
|
+
* Bundled view for the QBO configuration page: the draft it edits, the accounts
|
|
99
|
+
* and option lists its dropdowns render, the connection and sync health it
|
|
100
|
+
* reports, and the fetch states that decide between skeleton, form and error.
|
|
101
|
+
*
|
|
102
|
+
* `localData` is the draft once the user has edited, and the settings response
|
|
103
|
+
* before that — so the page has one field to read and CES owns when it becomes
|
|
104
|
+
* available, rather than the page copying settings into local state.
|
|
105
|
+
*/
|
|
106
|
+
export const getInvoicingQboSettingsFormView = (state) => {
|
|
107
|
+
const { error, fetchState, qboDraft, saveFetchState, settings } = state.invoicingSettingsViewState;
|
|
108
|
+
const { fetchState: configFetchState, qboAccountMappingKindOptions, qboCustomerMatchingOptions, qboSyncStatusOptions, } = getInvoicingConfigView(state);
|
|
109
|
+
const qboView = getInvoicingQboView(state);
|
|
110
|
+
return {
|
|
111
|
+
accountMappingKindOptions: qboAccountMappingKindOptions,
|
|
112
|
+
accounts: qboView.accounts,
|
|
113
|
+
backfillState: qboView.backfillState,
|
|
114
|
+
connection: qboView.connection,
|
|
115
|
+
configFetchState,
|
|
116
|
+
customerMatchingOptions: qboCustomerMatchingOptions,
|
|
117
|
+
// The dropdowns cannot be built before both the settings and the accounts
|
|
118
|
+
// land, so the page waits on either rather than rendering empty pickers.
|
|
119
|
+
isLoading: fetchState === 'Not-Started' ||
|
|
120
|
+
fetchState === 'In-Progress' ||
|
|
121
|
+
isInvoicingAccountingPickerDataLoading(state),
|
|
122
|
+
isSyncEnabledSaved: settings?.qbo?.enabled === true,
|
|
123
|
+
// Seeded in the reducer when the settings response lands, so this is a plain
|
|
124
|
+
// read rather than a second place that decides what the page starts from.
|
|
125
|
+
localData: qboDraft ?? initialInvoicingQboSettingsLocalData,
|
|
126
|
+
nestedAccountHierarchy: qboView.nestedAccountHierarchy,
|
|
127
|
+
retryFetchStateByTaskId: qboView.retryFetchStateByTaskId,
|
|
128
|
+
saveState: saveFetchState.fetchState === 'Not-Started' && error != null
|
|
129
|
+
? { fetchState, error }
|
|
130
|
+
: saveFetchState,
|
|
131
|
+
settingsFetchState: fetchState,
|
|
132
|
+
syncHealth: qboView.syncHealth,
|
|
133
|
+
syncStatusOptions: qboSyncStatusOptions,
|
|
134
|
+
};
|
|
135
|
+
};
|
|
95
136
|
/**
|
|
96
137
|
* Bundled view for the branding settings form: the draft `localData` (seeded
|
|
97
138
|
* from the existing settings until the user edits), the business-address label
|
package/lib/index.d.ts
CHANGED
|
@@ -321,12 +321,12 @@ import { getExpenseAutomationTransactionView, getLastTransferEntryReplacement }
|
|
|
321
321
|
import { applyTransactionFilters } from './view/expenseAutomationView/transactionFilterHelpers';
|
|
322
322
|
import { TRANSACTION_FILTER_CATEGORIES, TransactionFilterAmountMatchingOperator, TransactionFilterCategory, TransactionFilterCategoryDropdownOption, TransactionFilterCategoryField, TransactionFilterEntityType, TransactionFilters } from './view/expenseAutomationView/transactionFilterTypes';
|
|
323
323
|
import { CompletedSubTab, DEFAULT_COMPLETED_SUB_TAB, toCompletedSubTab } from './view/expenseAutomationView/types/completedSubTab';
|
|
324
|
-
import { DEFAULT_TRANSACTION_GROUP, TRANSACTION_GROUPS, TransactionGroup, toTransactionGroup } from './view/expenseAutomationView/types/transactionGroup';
|
|
325
324
|
import { FluxAnalysisActionType, FluxAnalysisReviewStatus, FluxAnalysisSectionType, FluxAnalysisSortKey, FluxAnalysisViewUIState, FluxBalancesByMonth } from './view/expenseAutomationView/types/fluxAnalysisViewState';
|
|
326
325
|
import { AccountSettingsLocalData, JEScheduleMainTab as ExpenseAutomationJEScheduleMainTab, JEScheduleSortKey as ExpenseAutomationJEScheduleSortKey, JESchedulesViewUIState as ExpenseAutomationJESchedulesViewUIState, JEScheduleLocalData, toJEScheduleMainTab as toExpenseAutomationJEScheduleMainTab, toJEScheduleSortKey as toExpenseAutomationJEScheduleSortKey } from './view/expenseAutomationView/types/jeSchedulesViewState';
|
|
327
326
|
import { BATCH_FILE_STATUSES, BatchDetails, BatchFile, BatchFileStatus, BatchListItem, BatchStatus, BatchStatusValue, BatchSummary, BulkUploadPhase, BulkUploadResultsTab, BulkUploadSortKey, BulkUploadState, CandidateRef, MatchCandidate, MatchSource, MissingReceiptsTab, isUnmatchedTabFileStatus, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toMatchSource, toMissingReceiptsTab } from './view/expenseAutomationView/types/missingReceiptsViewState';
|
|
328
327
|
import { MissingReceiptsSortKey as ExpenseAutomationMissingReceiptsSortKey, MissingReceiptsViewState as ExpenseAutomationMissingReceiptsViewState, MissingReceiptsViewUIState as ExpenseAutomationMissingReceiptsViewUIState, toMissingReceiptsSortKey as toExpenseAutomationMissingReceiptsSortKey } from './view/expenseAutomationView/types/missingReceiptsViewState';
|
|
329
328
|
import { AccountReconciliationLocalData, CombinedStatementAccount, ExcludeAccountFromReconciliationPayload, ReconciliationViewTabType as ExpenseAutomationReconciliationViewTab, ParsedStatementData, ReconReconcileSortKey, ReconReviewSortKey, ReconciliationReconcileTabLocalData, ReconciliationReviewTabLocalData, SaveReconcileDetailActionPayload as SaveExpenseAutomationReconciliationActionType, StatementAccountScope, StatementDateConflict, StatementMeta, StatementTransaction, StatementTransactionForUpdate, StatementTransactionsUpdate, StatementUpdateLocalData, toReconciliationTabsType } from './view/expenseAutomationView/types/reconciliationViewState';
|
|
329
|
+
import { DEFAULT_TRANSACTION_GROUP, TRANSACTION_GROUPS, TransactionGroup, toTransactionGroup } from './view/expenseAutomationView/types/transactionGroup';
|
|
330
330
|
import { TransactionsTab as ExpenseAutomationTransactionsTab, TransactionsViewState as ExpenseAutomationTransactionsViewState, TransactionsViewUIState as ExpenseAutomationTransactionsViewUIState, SupportedTransactionCategorization, TransactionCategorizationLineItemData, TransactionReviewLocalData, TransactionsSortKey, TransactionsTab, toTransactionsTabKey as toExpenseAutomationTransactionsTabKey, toTransactionsSortKey } from './view/expenseAutomationView/types/transactionsViewState';
|
|
331
331
|
import { fetchRegisteredInterests, notifyMeForFeature } from './view/featureNotificationView/featureNotificationViewReducer';
|
|
332
332
|
import { getFeatureNotificationView, getRegisteredInterests, getRegisteredInterestsByFeature, isFeatureInterestRegistered } from './view/featureNotificationView/featureNotificationViewSelector';
|
|
@@ -1236,10 +1236,12 @@ export { getInvoicingCatalogItemDetail } from './view/invoicing/invoicingCatalog
|
|
|
1236
1236
|
export { getInvoicingPlanById } from './entity/invoicing/plan/planSelector';
|
|
1237
1237
|
export { getInvoicingProductById } from './entity/invoicing/product/productSelector';
|
|
1238
1238
|
export type { InvoicingCatalogItemDetailView } from './view/invoicing/invoicingCatalogItemDetailView/invoicingCatalogItemDetailViewSelector';
|
|
1239
|
-
export { connectInvoicingStripe, disconnectInvoicingStripe, fetchInvoicingSettings, resetInvoicingBrandingFormDraft, resetSaveInvoicingSettings, saveInvoicingSettings, submitInvoicingBrandingForm, updateInvoicingBrandingFormDraft, updateInvoicingSettings, } from './view/invoicing/settingsView/settingsViewReducer';
|
|
1240
|
-
export { getInvoicingBrandingFormView, getInvoicingSettings, getInvoicingSettingsFetchState, getInvoicingSettingsHubView, getInvoicingSettingsView, } from './view/invoicing/settingsView/settingsViewSelector';
|
|
1241
|
-
export type { InvoicingBrandingFormView, InvoicingSettingsHubView, InvoicingSettingsView, } from './view/invoicing/settingsView/settingsViewSelector';
|
|
1239
|
+
export { connectInvoicingStripe, disconnectInvoicingStripe, fetchInvoicingSettings, resetInvoicingBrandingFormDraft, resetInvoicingQboSettingsDraft, resetSaveInvoicingSettings, saveInvoicingSettings, submitInvoicingBrandingForm, submitInvoicingQboSettings, updateInvoicingBrandingFormDraft, updateInvoicingQboSettingsDraft, updateInvoicingSettings, } from './view/invoicing/settingsView/settingsViewReducer';
|
|
1240
|
+
export { getInvoicingBrandingFormView, getInvoicingQboSettingsFormView, getInvoicingSettings, getInvoicingSettingsFetchState, getInvoicingSettingsHubView, getInvoicingSettingsView, } from './view/invoicing/settingsView/settingsViewSelector';
|
|
1241
|
+
export type { InvoicingBrandingFormView, InvoicingQboSettingsFormView, InvoicingSettingsHubView, InvoicingSettingsView, } from './view/invoicing/settingsView/settingsViewSelector';
|
|
1242
1242
|
export type { InvoicingBrandingFormLocalData } from './view/invoicing/settingsView/invoicingBrandingFormConfig';
|
|
1243
|
+
export type { InvoicingQboSettingsLocalData } from './view/invoicing/settingsView/invoicingQboSettingsFormConfig';
|
|
1244
|
+
export { entityToInvoicingQboSettingsLocalData, initialInvoicingQboSettingsLocalData, invoicingQboSettingsLocalDataToPayload, } from './view/invoicing/settingsView/invoicingQboSettingsFormConfig';
|
|
1243
1245
|
export { INVOICING_BUSINESS_ADDRESS_TYPE, entityToInvoicingBrandingFormLocalData, initialInvoicingBrandingFormLocalData, } from './view/invoicing/settingsView/invoicingBrandingFormConfig';
|
|
1244
1246
|
export { isStripeConnectedFromSettings } from './view/invoicing/settingsView/invoicingSettingsHelpers';
|
|
1245
1247
|
export { fetchInvoicingAccountingPickers, fetchInvoicingQboConnection, fetchInvoicingQboSyncHealth, retryInvoicingQboSyncTask, startInvoicingQboBackfill, } from './view/invoicing/invoicingQboView/invoicingQboViewReducer';
|
|
@@ -1248,7 +1250,7 @@ export type { InvoicingAccountingOption } from './view/invoicing/invoicingQboVie
|
|
|
1248
1250
|
export { getInvoicingQboView } from './view/invoicing/invoicingQboView/invoicingQboViewSelector';
|
|
1249
1251
|
export type { InvoicingQboView } from './view/invoicing/invoicingQboView/invoicingQboViewSelector';
|
|
1250
1252
|
export type { InvoicingQboConnection, InvoicingQboFailedTask, InvoicingQboSyncHealth, } from './view/invoicing/invoicingQboView/invoicingQboViewPayload';
|
|
1251
|
-
export { INVOICING_QBO_CUSTOMER_MATCHING_MODES, getInvoicingQboAccountMappingId, toInvoicingNamedOptionsByKey, toInvoicingQboCustomerMatchingMode,
|
|
1253
|
+
export { INVOICING_QBO_CUSTOMER_MATCHING_MODES, getInvoicingQboAccountMappingId, toInvoicingNamedOptionsByKey, toInvoicingQboCustomerMatchingMode, } from './entity/invoicing/invoicingCommonPayload';
|
|
1252
1254
|
export type { InvoicingNamedOption, InvoicingFieldHelp, InvoicingFieldHelpByCode, InvoicingFieldHelpGroup, InvoicingNamedOptionsByKey, InvoicingQboAccountMappingKindOption, InvoicingQboAccountMappingsPayload, InvoicingQboCustomerMatchingMode, InvoicingQboSettingsPayload, } from './entity/invoicing/invoicingCommonPayload';
|
|
1253
1255
|
export { acceptInvoicingTerms, enableInvoicing, fetchInvoicingConfig, resetInvoicingConfigActionStates, updateInvoicingConfig, } from './view/invoicing/invoicingConfigView/invoicingConfigViewReducer';
|
|
1254
1256
|
export { getInvoicingConfigView } from './view/invoicing/invoicingConfigView/invoicingConfigViewSelector';
|
package/lib/index.js
CHANGED
|
@@ -83,7 +83,7 @@ exports.runInvoicingCatalogPlanAction = exports.getInvoicingInvoiceActionState =
|
|
|
83
83
|
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.getInvoicingCustomerListView = exports.INVOICING_CUSTOMER_COLUMNS = exports.ALL_INVOICING_CUSTOMER_TAB_IDS = exports.ALL_INVOICING_CUSTOMER_SORT_KEYS = exports.updateInvoicingCustomerFilters = exports.setInvoicingCustomerActiveTab = exports.fetchInvoicingCustomerListPage = exports.fetchInvoicingCustomerList = exports.fetchInvoicingCustomerCounts = exports.updateInvoicingCustomers = exports.removeInvoicingCustomer = exports.INVOICING_LIST_PAGE_SIZE = exports.getInvoicingDataImportActionState = exports.uploadInvoicingMigrationFiles = exports.startInvoicingMigration = exports.rollbackInvoicingMigration = exports.retryInvoicingMigration = exports.connectInvoicingChargebee = exports.getInvoicingDataImportView = exports.setInvoicingActiveMigrationSessionId = exports.fetchInvoicingMigrationSessions = exports.fetchInvoicingMigrationSession = exports.fetchInvoicingMigrationDiagnostics = exports.fetchInvoicingDataImportStatus = exports.getInvoicingPaymentActionState = exports.runInvoicingPaymentAction = exports.getInvoicingDunningActionState = exports.runInvoicingDunningAction = exports.getInvoicingSubscriptionActionState = exports.runInvoicingSubscriptionAction = exports.getInvoicingDiscountActionState = exports.runInvoicingDiscountAction = exports.getInvoicingCatalogActionState = exports.runInvoicingCatalogProductAction = void 0;
|
|
84
84
|
exports.updateInvoicingCouponFilters = exports.setInvoicingCouponActiveTab = exports.fetchInvoicingCouponListPage = exports.fetchInvoicingCouponList = exports.fetchInvoicingCouponCounts = exports.updateInvoicingCoupons = exports.removeInvoicingCoupon = exports.getInvoicingCreditNoteDetail = exports.getInvoicingCreditNoteById = exports.fetchInvoicingCreditNoteDetail = exports.getInvoicingCreditNoteListView = 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.updateInvoicingCreditNotes = exports.removeInvoicingCreditNote = exports.getInvoicingTransactionDetail = exports.getInvoicingTransactionById = exports.fetchInvoicingTransactionDetail = exports.getInvoicingTransactionListView = exports.INVOICING_TRANSACTION_COLUMNS = exports.ALL_INVOICING_TRANSACTION_TAB_IDS = exports.ALL_INVOICING_TRANSACTION_SORT_KEYS = exports.updateInvoicingTransactionFilters = exports.setInvoicingTransactionActiveTab = exports.fetchInvoicingTransactionListPage = exports.fetchInvoicingTransactionList = exports.updateInvoicingTransactions = exports.removeInvoicingTransaction = exports.getInvoicingSubscriptionDetail = exports.getInvoicingSubscriptionById = exports.fetchInvoicingSubscriptionDetail = exports.getInvoicingSubscriptionListView = 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.updateInvoicingSubscriptions = exports.removeInvoicingSubscription = exports.resetPromotionalCreditAction = exports.submitAddPromotionalCredits = void 0;
|
|
85
85
|
exports.connectInvoicingStripe = exports.getInvoicingProductById = exports.getInvoicingPlanById = exports.getInvoicingCatalogItemDetail = exports.fetchInvoicingCatalogItemDetail = 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.updateInvoicingProducts = exports.removeInvoicingProduct = exports.updateInvoicingPlans = exports.removeInvoicingPlan = exports.mergeInvoicingPlanSubFamily = exports.getInvoicingDunningEmailPreview = exports.getInvoicingDunningCaseDetail = exports.getInvoicingDunningCaseById = exports.invalidateInvoicingDunningEmailPreview = exports.fetchInvoicingDunningEmailPreviewPage = exports.fetchInvoicingDunningCaseDetail = exports.clearInvoicingDunningCaseDetailView = exports.getInvoicingDunningCaseListView = 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.updateInvoicingDunningCases = exports.removeInvoicingDunningCase = exports.getInvoicingCouponDetail = exports.fetchInvoicingCouponDetail = exports.getInvoicingCouponById = exports.getInvoicingCouponListView = exports.getInvoicingCouponListNextCursor = exports.getInvoicingCouponListItems = exports.getInvoicingCouponListHasMore = exports.getInvoicingCouponListFilters = exports.getInvoicingCouponListFetchState = exports.getInvoicingCouponCounts = exports.INVOICING_COUPON_COLUMNS = exports.ALL_INVOICING_COUPON_TAB_IDS = exports.ALL_INVOICING_COUPON_SORT_KEYS = void 0;
|
|
86
|
-
exports.getInvoicingOnboardingGateView = exports.getInvoicingConfigView = exports.updateInvoicingConfig = exports.resetInvoicingConfigActionStates = exports.fetchInvoicingConfig = exports.enableInvoicing = exports.acceptInvoicingTerms = exports.
|
|
86
|
+
exports.getInvoicingOnboardingGateView = exports.getInvoicingConfigView = exports.updateInvoicingConfig = exports.resetInvoicingConfigActionStates = exports.fetchInvoicingConfig = exports.enableInvoicing = exports.acceptInvoicingTerms = exports.toInvoicingQboCustomerMatchingMode = exports.toInvoicingNamedOptionsByKey = exports.getInvoicingQboAccountMappingId = exports.INVOICING_QBO_CUSTOMER_MATCHING_MODES = exports.getInvoicingQboView = exports.invoicingAccountsForQboAccountTypes = exports.INVOICING_INCOME_ACCOUNT_TYPES = exports.startInvoicingQboBackfill = exports.retryInvoicingQboSyncTask = exports.fetchInvoicingQboSyncHealth = exports.fetchInvoicingQboConnection = exports.fetchInvoicingAccountingPickers = exports.isStripeConnectedFromSettings = exports.initialInvoicingBrandingFormLocalData = exports.entityToInvoicingBrandingFormLocalData = exports.INVOICING_BUSINESS_ADDRESS_TYPE = exports.invoicingQboSettingsLocalDataToPayload = exports.initialInvoicingQboSettingsLocalData = exports.entityToInvoicingQboSettingsLocalData = exports.getInvoicingSettingsView = exports.getInvoicingSettingsHubView = exports.getInvoicingSettingsFetchState = exports.getInvoicingSettings = exports.getInvoicingQboSettingsFormView = exports.getInvoicingBrandingFormView = exports.updateInvoicingSettings = exports.updateInvoicingQboSettingsDraft = exports.updateInvoicingBrandingFormDraft = exports.submitInvoicingQboSettings = exports.submitInvoicingBrandingForm = exports.saveInvoicingSettings = exports.resetSaveInvoicingSettings = exports.resetInvoicingQboSettingsDraft = exports.resetInvoicingBrandingFormDraft = exports.fetchInvoicingSettings = exports.disconnectInvoicingStripe = void 0;
|
|
87
87
|
const allowedValue_1 = require("./commonStateTypes/allowedValue");
|
|
88
88
|
Object.defineProperty(exports, "isAllowedValueWithCode", { enumerable: true, get: function () { return allowedValue_1.isAllowedValueWithCode; } });
|
|
89
89
|
Object.defineProperty(exports, "isAllowedValueWithID", { enumerable: true, get: function () { return allowedValue_1.isAllowedValueWithID; } });
|
|
@@ -982,10 +982,6 @@ Object.defineProperty(exports, "TRANSACTION_FILTER_CATEGORIES", { enumerable: tr
|
|
|
982
982
|
const completedSubTab_1 = require("./view/expenseAutomationView/types/completedSubTab");
|
|
983
983
|
Object.defineProperty(exports, "DEFAULT_COMPLETED_SUB_TAB", { enumerable: true, get: function () { return completedSubTab_1.DEFAULT_COMPLETED_SUB_TAB; } });
|
|
984
984
|
Object.defineProperty(exports, "toCompletedSubTab", { enumerable: true, get: function () { return completedSubTab_1.toCompletedSubTab; } });
|
|
985
|
-
const transactionGroup_1 = require("./view/expenseAutomationView/types/transactionGroup");
|
|
986
|
-
Object.defineProperty(exports, "DEFAULT_TRANSACTION_GROUP", { enumerable: true, get: function () { return transactionGroup_1.DEFAULT_TRANSACTION_GROUP; } });
|
|
987
|
-
Object.defineProperty(exports, "TRANSACTION_GROUPS", { enumerable: true, get: function () { return transactionGroup_1.TRANSACTION_GROUPS; } });
|
|
988
|
-
Object.defineProperty(exports, "toTransactionGroup", { enumerable: true, get: function () { return transactionGroup_1.toTransactionGroup; } });
|
|
989
985
|
const jeSchedulesViewState_1 = require("./view/expenseAutomationView/types/jeSchedulesViewState");
|
|
990
986
|
Object.defineProperty(exports, "toExpenseAutomationJEScheduleMainTab", { enumerable: true, get: function () { return jeSchedulesViewState_1.toJEScheduleMainTab; } });
|
|
991
987
|
Object.defineProperty(exports, "toExpenseAutomationJEScheduleSortKey", { enumerable: true, get: function () { return jeSchedulesViewState_1.toJEScheduleSortKey; } });
|
|
@@ -1003,6 +999,10 @@ const missingReceiptsViewState_2 = require("./view/expenseAutomationView/types/m
|
|
|
1003
999
|
Object.defineProperty(exports, "toExpenseAutomationMissingReceiptsSortKey", { enumerable: true, get: function () { return missingReceiptsViewState_2.toMissingReceiptsSortKey; } });
|
|
1004
1000
|
const reconciliationViewState_1 = require("./view/expenseAutomationView/types/reconciliationViewState");
|
|
1005
1001
|
Object.defineProperty(exports, "toReconciliationTabsType", { enumerable: true, get: function () { return reconciliationViewState_1.toReconciliationTabsType; } });
|
|
1002
|
+
const transactionGroup_1 = require("./view/expenseAutomationView/types/transactionGroup");
|
|
1003
|
+
Object.defineProperty(exports, "DEFAULT_TRANSACTION_GROUP", { enumerable: true, get: function () { return transactionGroup_1.DEFAULT_TRANSACTION_GROUP; } });
|
|
1004
|
+
Object.defineProperty(exports, "TRANSACTION_GROUPS", { enumerable: true, get: function () { return transactionGroup_1.TRANSACTION_GROUPS; } });
|
|
1005
|
+
Object.defineProperty(exports, "toTransactionGroup", { enumerable: true, get: function () { return transactionGroup_1.toTransactionGroup; } });
|
|
1006
1006
|
const transactionsViewState_1 = require("./view/expenseAutomationView/types/transactionsViewState");
|
|
1007
1007
|
Object.defineProperty(exports, "toExpenseAutomationTransactionsTabKey", { enumerable: true, get: function () { return transactionsViewState_1.toTransactionsTabKey; } });
|
|
1008
1008
|
Object.defineProperty(exports, "toTransactionsSortKey", { enumerable: true, get: function () { return transactionsViewState_1.toTransactionsSortKey; } });
|
|
@@ -3091,17 +3091,25 @@ Object.defineProperty(exports, "connectInvoicingStripe", { enumerable: true, get
|
|
|
3091
3091
|
Object.defineProperty(exports, "disconnectInvoicingStripe", { enumerable: true, get: function () { return settingsViewReducer_2.disconnectInvoicingStripe; } });
|
|
3092
3092
|
Object.defineProperty(exports, "fetchInvoicingSettings", { enumerable: true, get: function () { return settingsViewReducer_2.fetchInvoicingSettings; } });
|
|
3093
3093
|
Object.defineProperty(exports, "resetInvoicingBrandingFormDraft", { enumerable: true, get: function () { return settingsViewReducer_2.resetInvoicingBrandingFormDraft; } });
|
|
3094
|
+
Object.defineProperty(exports, "resetInvoicingQboSettingsDraft", { enumerable: true, get: function () { return settingsViewReducer_2.resetInvoicingQboSettingsDraft; } });
|
|
3094
3095
|
Object.defineProperty(exports, "resetSaveInvoicingSettings", { enumerable: true, get: function () { return settingsViewReducer_2.resetSaveInvoicingSettings; } });
|
|
3095
3096
|
Object.defineProperty(exports, "saveInvoicingSettings", { enumerable: true, get: function () { return settingsViewReducer_2.saveInvoicingSettings; } });
|
|
3096
3097
|
Object.defineProperty(exports, "submitInvoicingBrandingForm", { enumerable: true, get: function () { return settingsViewReducer_2.submitInvoicingBrandingForm; } });
|
|
3098
|
+
Object.defineProperty(exports, "submitInvoicingQboSettings", { enumerable: true, get: function () { return settingsViewReducer_2.submitInvoicingQboSettings; } });
|
|
3097
3099
|
Object.defineProperty(exports, "updateInvoicingBrandingFormDraft", { enumerable: true, get: function () { return settingsViewReducer_2.updateInvoicingBrandingFormDraft; } });
|
|
3100
|
+
Object.defineProperty(exports, "updateInvoicingQboSettingsDraft", { enumerable: true, get: function () { return settingsViewReducer_2.updateInvoicingQboSettingsDraft; } });
|
|
3098
3101
|
Object.defineProperty(exports, "updateInvoicingSettings", { enumerable: true, get: function () { return settingsViewReducer_2.updateInvoicingSettings; } });
|
|
3099
3102
|
var settingsViewSelector_2 = require("./view/invoicing/settingsView/settingsViewSelector");
|
|
3100
3103
|
Object.defineProperty(exports, "getInvoicingBrandingFormView", { enumerable: true, get: function () { return settingsViewSelector_2.getInvoicingBrandingFormView; } });
|
|
3104
|
+
Object.defineProperty(exports, "getInvoicingQboSettingsFormView", { enumerable: true, get: function () { return settingsViewSelector_2.getInvoicingQboSettingsFormView; } });
|
|
3101
3105
|
Object.defineProperty(exports, "getInvoicingSettings", { enumerable: true, get: function () { return settingsViewSelector_2.getInvoicingSettings; } });
|
|
3102
3106
|
Object.defineProperty(exports, "getInvoicingSettingsFetchState", { enumerable: true, get: function () { return settingsViewSelector_2.getInvoicingSettingsFetchState; } });
|
|
3103
3107
|
Object.defineProperty(exports, "getInvoicingSettingsHubView", { enumerable: true, get: function () { return settingsViewSelector_2.getInvoicingSettingsHubView; } });
|
|
3104
3108
|
Object.defineProperty(exports, "getInvoicingSettingsView", { enumerable: true, get: function () { return settingsViewSelector_2.getInvoicingSettingsView; } });
|
|
3109
|
+
var invoicingQboSettingsFormConfig_1 = require("./view/invoicing/settingsView/invoicingQboSettingsFormConfig");
|
|
3110
|
+
Object.defineProperty(exports, "entityToInvoicingQboSettingsLocalData", { enumerable: true, get: function () { return invoicingQboSettingsFormConfig_1.entityToInvoicingQboSettingsLocalData; } });
|
|
3111
|
+
Object.defineProperty(exports, "initialInvoicingQboSettingsLocalData", { enumerable: true, get: function () { return invoicingQboSettingsFormConfig_1.initialInvoicingQboSettingsLocalData; } });
|
|
3112
|
+
Object.defineProperty(exports, "invoicingQboSettingsLocalDataToPayload", { enumerable: true, get: function () { return invoicingQboSettingsFormConfig_1.invoicingQboSettingsLocalDataToPayload; } });
|
|
3105
3113
|
var invoicingBrandingFormConfig_1 = require("./view/invoicing/settingsView/invoicingBrandingFormConfig");
|
|
3106
3114
|
Object.defineProperty(exports, "INVOICING_BUSINESS_ADDRESS_TYPE", { enumerable: true, get: function () { return invoicingBrandingFormConfig_1.INVOICING_BUSINESS_ADDRESS_TYPE; } });
|
|
3107
3115
|
Object.defineProperty(exports, "entityToInvoicingBrandingFormLocalData", { enumerable: true, get: function () { return invoicingBrandingFormConfig_1.entityToInvoicingBrandingFormLocalData; } });
|
|
@@ -3125,7 +3133,6 @@ Object.defineProperty(exports, "INVOICING_QBO_CUSTOMER_MATCHING_MODES", { enumer
|
|
|
3125
3133
|
Object.defineProperty(exports, "getInvoicingQboAccountMappingId", { enumerable: true, get: function () { return invoicingCommonPayload_2.getInvoicingQboAccountMappingId; } });
|
|
3126
3134
|
Object.defineProperty(exports, "toInvoicingNamedOptionsByKey", { enumerable: true, get: function () { return invoicingCommonPayload_2.toInvoicingNamedOptionsByKey; } });
|
|
3127
3135
|
Object.defineProperty(exports, "toInvoicingQboCustomerMatchingMode", { enumerable: true, get: function () { return invoicingCommonPayload_2.toInvoicingQboCustomerMatchingMode; } });
|
|
3128
|
-
Object.defineProperty(exports, "withInvoicingQboAccountMappingId", { enumerable: true, get: function () { return invoicingCommonPayload_2.withInvoicingQboAccountMappingId; } });
|
|
3129
3136
|
// ── Invoicing: config ─────────────────────────────────────────────────────────
|
|
3130
3137
|
var invoicingConfigViewReducer_1 = require("./view/invoicing/invoicingConfigView/invoicingConfigViewReducer");
|
|
3131
3138
|
Object.defineProperty(exports, "acceptInvoicingTerms", { enumerable: true, get: function () { return invoicingConfigViewReducer_1.acceptInvoicingTerms; } });
|
|
@@ -232,7 +232,7 @@ export interface ReconciliationTabsState {
|
|
|
232
232
|
uiState: ReconciliationReviewTabViewUiState;
|
|
233
233
|
};
|
|
234
234
|
}
|
|
235
|
-
declare const toReconReviewSortKey: (v: string) => "date" | "amount" | "memo" | "
|
|
235
|
+
declare const toReconReviewSortKey: (v: string) => "date" | "amount" | "memo" | "match" | "payee" | "direction";
|
|
236
236
|
export type ReconReviewSortKey = ReturnType<typeof toReconReviewSortKey>;
|
|
237
237
|
export interface ReconciliationReviewTabViewUiState {
|
|
238
238
|
scrollPosition: {
|