@zeniai/client-epic-state 5.2.41-beta6MM → 5.2.41-beta7MM
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/billPay/billTransaction/billTransactionReducer.d.ts +5 -1
- package/lib/entity/billPay/billTransaction/billTransactionReducer.js +17 -2
- package/lib/entity/invoicing/coupon/couponPayload.d.ts +8 -0
- package/lib/entity/invoicing/coupon/couponPayload.js +8 -0
- package/lib/entity/invoicing/coupon/couponState.d.ts +6 -0
- package/lib/entity/invoicing/dunningCase/dunningCaseTypes.d.ts +1 -1
- package/lib/entity/invoicing/plan/planSelector.d.ts +20 -0
- package/lib/entity/invoicing/plan/planSelector.js +42 -0
- package/lib/entity/invoicing/product/productPayload.d.ts +8 -1
- package/lib/entity/invoicing/product/productPayload.js +4 -1
- package/lib/entity/invoicing/product/productState.d.ts +16 -0
- package/lib/entity/jeSchedules/jeSchedulesReducer.d.ts +4 -1
- package/lib/entity/jeSchedules/jeSchedulesReducer.js +79 -5
- package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
- package/lib/entity/snackbar/snackbarTypes.js +1 -0
- package/lib/entity/task/taskState.d.ts +1 -1
- package/lib/epic.d.ts +4 -1
- package/lib/epic.js +10 -4
- package/lib/esm/entity/billPay/billTransaction/billTransactionReducer.js +16 -1
- package/lib/esm/entity/invoicing/coupon/couponPayload.js +8 -0
- package/lib/esm/entity/invoicing/plan/planSelector.js +39 -0
- package/lib/esm/entity/invoicing/product/productPayload.js +4 -1
- package/lib/esm/entity/jeSchedules/jeSchedulesReducer.js +78 -4
- package/lib/esm/entity/snackbar/snackbarTypes.js +1 -0
- package/lib/esm/epic.js +10 -4
- package/lib/esm/index.js +8 -7
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.js +3 -2
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchFailedJePostingsEpic.js +39 -0
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +14 -1
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +10 -13
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/initializeJeScheduleLocalDataEpic.js +38 -17
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/retryJeSchedulesEpic.js +17 -1
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +15 -4
- package/lib/esm/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +6 -0
- package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +74 -1
- package/lib/esm/view/expenseAutomationView/reducers/reconciliationViewReducer.js +80 -53
- package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +10 -0
- package/lib/esm/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +6 -2
- package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +49 -14
- package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +28 -11
- package/lib/esm/view/invoicing/createInvoice/createInvoiceSelector.js +28 -1
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +67 -35
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewReducer.js +22 -11
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +23 -4
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/invoicingCatalogItemFormHelper.js +1 -7
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +19 -5
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/seedInvoicingCatalogItemFormDraftEpic.js +30 -7
- package/lib/esm/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewPayload.js +16 -1
- package/lib/esm/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewReducer.js +22 -11
- package/lib/esm/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewSelector.js +69 -6
- package/lib/esm/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewState.js +22 -0
- package/lib/esm/view/invoicing/editInvoicingCouponDetailView/fetchInvoicingCouponDetailPageEpic.js +22 -4
- package/lib/esm/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +18 -4
- package/lib/esm/view/invoicing/editInvoicingCouponDetailView/seedInvoicingCouponFormDraftEpic.js +29 -6
- package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer.js +28 -12
- package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewSelector.js +37 -2
- package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/initializeInvoicingCustomerAddressEpic.js +43 -17
- package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +1 -1
- package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/seedInvoicingCustomerFormDraftEpic.js +29 -6
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewReducer.js +30 -14
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewSelector.js +143 -8
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/fetchInvoicingSubscriptionFormPageEpic.js +4 -1
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/initializeInvoicingSubscriptionAddressEpic.js +44 -18
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +1 -1
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/seedInvoicingSubscriptionFormDraftEpic.js +29 -8
- package/lib/esm/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewSelector.js +12 -0
- package/lib/esm/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewState.js +6 -6
- package/lib/esm/view/invoicing/invoicingFormDraft.js +78 -0
- package/lib/esm/view/invoicing/invoicingQboView/invoicingQboViewSelector.js +57 -9
- package/lib/esm/view/recommendation/recommendationPayload.js +3 -1
- package/lib/esm/view/recommendation/recommendationReducer.js +27 -7
- package/lib/esm/view/recommendation/recommendationSelector.js +1 -0
- package/lib/esm/view/recommendation/submitRecommendationFeedbackEpic.js +20 -8
- package/lib/esm/view/spendManagement/billPay/billDetailView/billDetailViewReducer.js +87 -1
- package/lib/esm/view/spendManagement/billPay/billDetailView/billDetailViewSelector.js +1 -0
- package/lib/esm/view/spendManagement/billPay/billDetailView/billDetailViewState.js +4 -0
- package/lib/esm/view/spendManagement/billPay/billDetailView/epics/fetchBillRecommendationsEpic.js +97 -0
- package/lib/esm/view/spendManagement/billPay/billDetailView/epics/fetchRecommendationsForBill.js +85 -0
- package/lib/esm/view/spendManagement/billPay/editBillView/editBillViewReducer.js +18 -1
- package/lib/esm/view/spendManagement/billPay/editBillView/editBillViewSelector.js +3 -0
- package/lib/esm/view/spendManagement/billPay/editBillView/epics/applyBillRecommendationsToLocalStoreEpic.js +95 -0
- package/lib/index.d.ts +9 -8
- package/lib/index.js +54 -48
- package/lib/view/expenseAutomationView/epics/jeSchedule/actualMatching/ignoreActualMatchingSuggestionEpic.js +3 -2
- package/lib/view/expenseAutomationView/epics/jeSchedule/fetchFailedJePostingsEpic.d.ts +20 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/fetchFailedJePostingsEpic.js +43 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.d.ts +2 -2
- package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +13 -0
- package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +8 -11
- package/lib/view/expenseAutomationView/epics/jeSchedule/initializeJeScheduleLocalDataEpic.js +38 -17
- package/lib/view/expenseAutomationView/epics/jeSchedule/retryJeSchedulesEpic.d.ts +2 -2
- package/lib/view/expenseAutomationView/epics/jeSchedule/retryJeSchedulesEpic.js +17 -1
- package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +15 -4
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
- package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.d.ts +18 -0
- package/lib/view/expenseAutomationView/payload/transactionCategorizationPayload.d.ts +18 -7
- package/lib/view/expenseAutomationView/reducers/actualMatchingViewReducer.js +6 -0
- package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +10 -3
- package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +76 -3
- package/lib/view/expenseAutomationView/reducers/reconciliationViewReducer.js +80 -53
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +10 -0
- package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +3 -0
- package/lib/view/expenseAutomationView/selectorTypes/transactionsViewSelectorTypes.d.ts +8 -4
- package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.d.ts +1 -0
- package/lib/view/expenseAutomationView/selectors/actualMatchingViewSelector.js +7 -2
- package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +49 -14
- package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +27 -10
- package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +16 -0
- package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +8 -5
- package/lib/view/invoicing/createInvoice/createInvoiceSelector.d.ts +7 -2
- package/lib/view/invoicing/createInvoice/createInvoiceSelector.js +28 -1
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.d.ts +46 -5
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +69 -36
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewReducer.d.ts +3 -1
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewReducer.js +22 -11
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.d.ts +17 -0
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +22 -3
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewState.d.ts +2 -1
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/invoicingCatalogItemFormHelper.d.ts +2 -2
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/invoicingCatalogItemFormHelper.js +1 -7
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +17 -3
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/seedInvoicingCatalogItemFormDraftEpic.d.ts +10 -6
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/seedInvoicingCatalogItemFormDraftEpic.js +29 -6
- package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewPayload.d.ts +5 -1
- package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewPayload.js +16 -1
- package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewReducer.d.ts +3 -1
- package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewReducer.js +22 -11
- package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewSelector.d.ts +46 -0
- package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewSelector.js +68 -5
- package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewState.d.ts +21 -1
- package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewState.js +24 -1
- package/lib/view/invoicing/editInvoicingCouponDetailView/fetchInvoicingCouponDetailPageEpic.d.ts +9 -5
- package/lib/view/invoicing/editInvoicingCouponDetailView/fetchInvoicingCouponDetailPageEpic.js +22 -4
- package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +18 -4
- package/lib/view/invoicing/editInvoicingCouponDetailView/seedInvoicingCouponFormDraftEpic.d.ts +10 -6
- package/lib/view/invoicing/editInvoicingCouponDetailView/seedInvoicingCouponFormDraftEpic.js +28 -5
- package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer.d.ts +5 -1
- package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer.js +29 -13
- package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewSelector.d.ts +16 -7
- package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewSelector.js +37 -2
- package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewState.d.ts +8 -1
- package/lib/view/invoicing/editInvoicingCustomerDetailView/initializeInvoicingCustomerAddressEpic.d.ts +15 -10
- package/lib/view/invoicing/editInvoicingCustomerDetailView/initializeInvoicingCustomerAddressEpic.js +42 -16
- package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +1 -1
- package/lib/view/invoicing/editInvoicingCustomerDetailView/seedInvoicingCustomerFormDraftEpic.d.ts +10 -6
- package/lib/view/invoicing/editInvoicingCustomerDetailView/seedInvoicingCustomerFormDraftEpic.js +28 -5
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewReducer.d.ts +5 -1
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewReducer.js +31 -15
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewSelector.d.ts +79 -12
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewSelector.js +145 -9
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewState.d.ts +8 -1
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/fetchInvoicingSubscriptionFormPageEpic.js +4 -1
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/initializeInvoicingSubscriptionAddressEpic.d.ts +15 -11
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/initializeInvoicingSubscriptionAddressEpic.js +42 -16
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +1 -1
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/seedInvoicingSubscriptionFormDraftEpic.d.ts +10 -6
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/seedInvoicingSubscriptionFormDraftEpic.js +28 -7
- package/lib/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewSelector.d.ts +10 -0
- package/lib/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewSelector.js +12 -0
- package/lib/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewReducer.d.ts +1 -1
- package/lib/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewState.d.ts +2 -2
- package/lib/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewState.js +6 -6
- package/lib/view/invoicing/invoicingFormDraft.d.ts +63 -0
- package/lib/view/invoicing/invoicingFormDraft.js +86 -0
- package/lib/view/invoicing/invoicingQboView/invoicingQboViewSelector.d.ts +49 -0
- package/lib/view/invoicing/invoicingQboView/invoicingQboViewSelector.js +59 -10
- package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewReducer.d.ts +1 -1
- package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewState.d.ts +1 -1
- package/lib/view/recommendation/recommendationPayload.d.ts +1 -0
- package/lib/view/recommendation/recommendationPayload.js +5 -0
- package/lib/view/recommendation/recommendationReducer.d.ts +7 -1
- package/lib/view/recommendation/recommendationReducer.js +28 -8
- package/lib/view/recommendation/recommendationSelector.d.ts +2 -0
- package/lib/view/recommendation/recommendationSelector.js +3 -1
- package/lib/view/recommendation/recommendationState.d.ts +2 -1
- package/lib/view/recommendation/submitRecommendationFeedbackEpic.d.ts +2 -2
- package/lib/view/recommendation/submitRecommendationFeedbackEpic.js +18 -6
- package/lib/view/spendManagement/billPay/billDetailView/billDetailViewPayload.d.ts +19 -0
- package/lib/view/spendManagement/billPay/billDetailView/billDetailViewReducer.d.ts +10 -1
- package/lib/view/spendManagement/billPay/billDetailView/billDetailViewReducer.js +88 -2
- package/lib/view/spendManagement/billPay/billDetailView/billDetailViewSelector.d.ts +1 -0
- package/lib/view/spendManagement/billPay/billDetailView/billDetailViewSelector.js +1 -0
- package/lib/view/spendManagement/billPay/billDetailView/billDetailViewState.d.ts +7 -0
- package/lib/view/spendManagement/billPay/billDetailView/billDetailViewState.js +4 -0
- package/lib/view/spendManagement/billPay/billDetailView/epics/fetchBillRecommendationsEpic.d.ts +37 -0
- package/lib/view/spendManagement/billPay/billDetailView/epics/fetchBillRecommendationsEpic.js +104 -0
- package/lib/view/spendManagement/billPay/billDetailView/epics/fetchRecommendationsForBill.d.ts +24 -0
- package/lib/view/spendManagement/billPay/billDetailView/epics/fetchRecommendationsForBill.js +92 -0
- package/lib/view/spendManagement/billPay/editBillView/editBillViewReducer.d.ts +4 -1
- package/lib/view/spendManagement/billPay/editBillView/editBillViewReducer.js +19 -2
- package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.d.ts +1 -0
- package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.js +3 -0
- package/lib/view/spendManagement/billPay/editBillView/epics/applyBillRecommendationsToLocalStoreEpic.d.ts +18 -0
- package/lib/view/spendManagement/billPay/editBillView/epics/applyBillRecommendationsToLocalStoreEpic.js +102 -0
- package/package.json +2 -2
package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js
CHANGED
|
@@ -20,8 +20,9 @@ const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actions$.pip
|
|
|
20
20
|
// class become the records the service stores. Price points ride along
|
|
21
21
|
// nested, so the detail page and the create/edit form share one request.
|
|
22
22
|
const viewState = state.editInvoicingCatalogItemDetailViewState;
|
|
23
|
-
const localData = (id != null
|
|
24
|
-
viewState.
|
|
23
|
+
const localData = (id != null
|
|
24
|
+
? viewState.editDraftById[id]?.localData
|
|
25
|
+
: viewState.newItemDraft) ?? viewState.newItemDraft;
|
|
25
26
|
const data = (0, editInvoicingCatalogItemDetailViewPayload_1.localDataToSaveInvoicingCatalogItemPayload)(localData, id == null, accountingLookup);
|
|
26
27
|
const baseUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0`;
|
|
27
28
|
const path = id != null
|
|
@@ -83,7 +84,20 @@ const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actions$.pip
|
|
|
83
84
|
}));
|
|
84
85
|
return resultActions;
|
|
85
86
|
};
|
|
86
|
-
|
|
87
|
+
// Price points added on an edit form cannot ride in the update:
|
|
88
|
+
// it addresses them by id and they have none yet. They are created
|
|
89
|
+
// against the item that was just saved, and their responses join
|
|
90
|
+
// the same success — one of them failing is the whole save
|
|
91
|
+
// failing, since the item on screen would otherwise claim price
|
|
92
|
+
// points the service never stored. A create needs none of this:
|
|
93
|
+
// its price points are nested in the item body.
|
|
94
|
+
const newProductPayloads = id != null
|
|
95
|
+
? (0, editInvoicingCatalogItemDetailViewPayload_1.localDataToCreateInvoicingCatalogProductPayloads)(localData, savedItem.id, accountingLookup)
|
|
96
|
+
: [];
|
|
97
|
+
if (newProductPayloads.length === 0) {
|
|
98
|
+
return completeSave([]);
|
|
99
|
+
}
|
|
100
|
+
return (0, rxjs_1.forkJoin)(newProductPayloads.map((productPayload) => zeniAPI.postAndGetJSON(`${baseUrl}/catalog/products`, productPayload))).pipe((0, operators_1.mergeMap)((productResponses) => completeSave(productResponses)));
|
|
87
101
|
}
|
|
88
102
|
return (0, rxjs_1.from)([
|
|
89
103
|
(0, editInvoicingCatalogItemDetailViewReducer_1.submitInvoicingCatalogItemFormFailure)(response.status),
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
import { RootState } from '../../../rootStateTypes';
|
|
4
|
-
import { seedInvoicingCatalogItemFormDraft, updateInvoicingCatalogItemDetail } from './editInvoicingCatalogItemDetailViewReducer';
|
|
5
|
-
export type ActionType = ReturnType<typeof updateInvoicingCatalogItemDetail> | ReturnType<typeof seedInvoicingCatalogItemFormDraft>;
|
|
4
|
+
import { fetchInvoicingCatalogItemDetailPage, seedInvoicingCatalogItemFormDraft, updateInvoicingCatalogItemDetail } from './editInvoicingCatalogItemDetailViewReducer';
|
|
5
|
+
export type ActionType = ReturnType<typeof fetchInvoicingCatalogItemDetailPage> | ReturnType<typeof updateInvoicingCatalogItemDetail> | ReturnType<typeof seedInvoicingCatalogItemFormDraft>;
|
|
6
6
|
/**
|
|
7
|
-
* Seeds the edit draft from the record the
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* Seeds the edit draft from the record, so the form has its values before it
|
|
8
|
+
* mounts. The reducer ignores a seed once the draft holds the record, which is
|
|
9
|
+
* what stops a background refetch from overwriting edits in progress.
|
|
10
|
+
*
|
|
11
|
+
* Opening the page counts as a trigger, not just the detail response: the page
|
|
12
|
+
* fetch is cache-guarded, so re-opening a form for a record already loaded this
|
|
13
|
+
* session issues no request at all — and a draft cleared in between (by a save
|
|
14
|
+
* or a cancel) would have nothing left to seed it.
|
|
11
15
|
*/
|
|
12
16
|
export declare const seedInvoicingCatalogItemFormDraftEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>) => Observable<ActionType>;
|
|
@@ -7,13 +7,36 @@ const planSelector_1 = require("../../../entity/invoicing/plan/planSelector");
|
|
|
7
7
|
const editInvoicingCatalogItemDetailViewReducer_1 = require("./editInvoicingCatalogItemDetailViewReducer");
|
|
8
8
|
const invoicingCatalogItemFormHelper_1 = require("./invoicingCatalogItemFormHelper");
|
|
9
9
|
/**
|
|
10
|
-
* Seeds the edit draft from the record the
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* Seeds the edit draft from the record, so the form has its values before it
|
|
11
|
+
* mounts. The reducer ignores a seed once the draft holds the record, which is
|
|
12
|
+
* what stops a background refetch from overwriting edits in progress.
|
|
13
|
+
*
|
|
14
|
+
* Opening the page counts as a trigger, not just the detail response: the page
|
|
15
|
+
* fetch is cache-guarded, so re-opening a form for a record already loaded this
|
|
16
|
+
* session issues no request at all — and a draft cleared in between (by a save
|
|
17
|
+
* or a cancel) would have nothing left to seed it.
|
|
14
18
|
*/
|
|
15
|
-
const seedInvoicingCatalogItemFormDraftEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)(editInvoicingCatalogItemDetailViewReducer_1.updateInvoicingCatalogItemDetail.match
|
|
16
|
-
|
|
19
|
+
const seedInvoicingCatalogItemFormDraftEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)((action) => editInvoicingCatalogItemDetailViewReducer_1.updateInvoicingCatalogItemDetail.match(action) ||
|
|
20
|
+
editInvoicingCatalogItemDetailViewReducer_1.fetchInvoicingCatalogItemDetailPage.match(action)), (0, operators_1.withLatestFrom)(state$), (0, operators_1.mergeMap)(([action, state]) => {
|
|
21
|
+
const id = action.payload.id;
|
|
22
|
+
if (id == null) {
|
|
23
|
+
return rxjs_1.EMPTY;
|
|
24
|
+
}
|
|
25
|
+
// The entity alone does not say the whole record is loaded — the list
|
|
26
|
+
// endpoints merge their own list-shaped rows into the same store. Only a
|
|
27
|
+
// completed detail load does, which is also exactly when the page's
|
|
28
|
+
// cache-guarded fetch issues no request and this is the sole seed.
|
|
29
|
+
// A forced refetch is the caller asking for fresh data: the response will
|
|
30
|
+
// seed, and seeding first from the entity as it stands would mark the
|
|
31
|
+
// draft loaded and lock that response out.
|
|
32
|
+
if (editInvoicingCatalogItemDetailViewReducer_1.fetchInvoicingCatalogItemDetailPage.match(action) &&
|
|
33
|
+
(action.payload.cacheOverride === true ||
|
|
34
|
+
state.editInvoicingCatalogItemDetailViewState.recordStateById[id]
|
|
35
|
+
?.fetchState !== 'Completed')) {
|
|
36
|
+
return rxjs_1.EMPTY;
|
|
37
|
+
}
|
|
38
|
+
// Nothing to seed from on a cold open; the detail response triggers this
|
|
39
|
+
// again once it lands.
|
|
17
40
|
const plan = (0, planSelector_1.getInvoicingPlanById)(state.invoicingPlanState, id);
|
|
18
41
|
if (plan == null) {
|
|
19
42
|
return rxjs_1.EMPTY;
|
package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewPayload.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AccountBase } from '../../../entity/account/accountState';
|
|
1
2
|
import { InvoicingCouponPayload } from '../../../entity/invoicing/coupon/couponPayload';
|
|
2
3
|
import { ZeniAPIResponse } from '../../../responsePayload';
|
|
3
4
|
import { InvoicingCouponFormLocalData } from './editInvoicingCouponDetailViewState';
|
|
@@ -6,7 +7,10 @@ export type InvoicingCouponWriteResponse = ZeniAPIResponse<InvoicingCouponPayloa
|
|
|
6
7
|
* Build the create/update discount request body from the form draft (snake_case
|
|
7
8
|
* matching the `/discounts` schema). On create the coupon id is part of the
|
|
8
9
|
* body; on edit it is the URL param, so it is omitted here.
|
|
10
|
+
*
|
|
11
|
+
* `accountByQboId` resolves the discounts-account picker back to the account
|
|
12
|
+
* record the body carries, the same way the catalog and QBO settings bodies do.
|
|
9
13
|
*/
|
|
10
|
-
export declare const localDataToSaveInvoicingCouponPayload: (localData: InvoicingCouponFormLocalData, isCreate: boolean) => Record<string, unknown>;
|
|
14
|
+
export declare const localDataToSaveInvoicingCouponPayload: (localData: InvoicingCouponFormLocalData, isCreate: boolean, accountByQboId?: (qboId: string) => AccountBase | undefined) => Record<string, unknown>;
|
|
11
15
|
export type RunInvoicingDiscountActionResponse = ZeniAPIResponse<InvoicingCouponPayload>;
|
|
12
16
|
export type InvoicingCouponDetailResponse = ZeniAPIResponse<InvoicingCouponPayload>;
|
package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewPayload.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.localDataToSaveInvoicingCouponPayload = void 0;
|
|
4
|
+
const accountPayload_1 = require("../../../entity/account/accountPayload");
|
|
4
5
|
/**
|
|
5
6
|
* Build the create/update discount request body from the form draft (snake_case
|
|
6
7
|
* matching the `/discounts` schema). On create the coupon id is part of the
|
|
7
8
|
* body; on edit it is the URL param, so it is omitted here.
|
|
9
|
+
*
|
|
10
|
+
* `accountByQboId` resolves the discounts-account picker back to the account
|
|
11
|
+
* record the body carries, the same way the catalog and QBO settings bodies do.
|
|
8
12
|
*/
|
|
9
|
-
const localDataToSaveInvoicingCouponPayload = (localData, isCreate) => {
|
|
13
|
+
const localDataToSaveInvoicingCouponPayload = (localData, isCreate, accountByQboId) => {
|
|
10
14
|
const data = {
|
|
11
15
|
apply_on: localData.applyOn,
|
|
12
16
|
discount_type: localData.discountType,
|
|
@@ -57,6 +61,17 @@ const localDataToSaveInvoicingCouponPayload = (localData, isCreate) => {
|
|
|
57
61
|
if (invoiceNotes !== '') {
|
|
58
62
|
data.invoice_notes = invoiceNotes;
|
|
59
63
|
}
|
|
64
|
+
// Omitted rather than sent as `null` when there is none: the service reads a
|
|
65
|
+
// blank discounts account as "not given" and leaves what it has, which is
|
|
66
|
+
// what keeps a form that never showed the picker — QBO disconnected — from
|
|
67
|
+
// clearing an account set elsewhere.
|
|
68
|
+
const discountsAccountId = localData.discountsAccountId.trim();
|
|
69
|
+
const discountsAccount = discountsAccountId !== ''
|
|
70
|
+
? accountByQboId?.(discountsAccountId)
|
|
71
|
+
: undefined;
|
|
72
|
+
if (discountsAccount != null) {
|
|
73
|
+
data.discounts_account = (0, accountPayload_1.toAccountPayload)(discountsAccount);
|
|
74
|
+
}
|
|
60
75
|
return data;
|
|
61
76
|
};
|
|
62
77
|
exports.localDataToSaveInvoicingCouponPayload = localDataToSaveInvoicingCouponPayload;
|
package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewReducer.d.ts
CHANGED
|
@@ -48,6 +48,8 @@ export declare const updateInvoicingCouponFormDraft: import("@reduxjs/toolkit").
|
|
|
48
48
|
id: ID;
|
|
49
49
|
}, "editInvoicingCouponDetailView/runInvoicingDiscountActionFailure">, submitInvoicingCouponForm: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: SubmitInvoicingCouponFormPayload], SubmitInvoicingCouponFormPayload, "editInvoicingCouponDetailView/submitInvoicingCouponForm", never, never>, saveInvoicingCoupon: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: SaveInvoicingCouponPayload], SaveInvoicingCouponPayload, "editInvoicingCouponDetailView/saveInvoicingCoupon", never, never>, submitInvoicingCouponFormSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
50
50
|
couponId: ID;
|
|
51
|
-
}, "editInvoicingCouponDetailView/submitInvoicingCouponFormSuccess">, submitInvoicingCouponFormFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "editInvoicingCouponDetailView/submitInvoicingCouponFormFailure">, resetEditInvoicingCouponDetailView: import("@reduxjs/toolkit").
|
|
51
|
+
}, "editInvoicingCouponDetailView/submitInvoicingCouponFormSuccess">, submitInvoicingCouponFormFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "editInvoicingCouponDetailView/submitInvoicingCouponFormFailure">, resetEditInvoicingCouponDetailView: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<{
|
|
52
|
+
id?: ID;
|
|
53
|
+
} | undefined, "editInvoicingCouponDetailView/resetEditInvoicingCouponDetailView">;
|
|
52
54
|
declare const _default: import("redux").Reducer<EditInvoicingCouponDetailViewState>;
|
|
53
55
|
export default _default;
|
package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewReducer.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.resetEditInvoicingCouponDetailView = exports.submitInvoicingCouponFormFailure = exports.submitInvoicingCouponFormSuccess = exports.saveInvoicingCoupon = exports.submitInvoicingCouponForm = exports.runInvoicingDiscountActionFailure = exports.runInvoicingDiscountActionSuccess = exports.runInvoicingDiscountAction = exports.updateInvoicingCouponDetailFailure = exports.updateInvoicingCouponDetail = exports.seedInvoicingCouponFormDraft = exports.fetchInvoicingCouponDetailPage = exports.fetchInvoicingCouponDetail = exports.updateInvoicingCouponFormDraft = exports.initialState = void 0;
|
|
5
5
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
6
6
|
const rootActions_1 = require("../../../rootActions");
|
|
7
|
+
const invoicingFormDraft_1 = require("../invoicingFormDraft");
|
|
7
8
|
const editInvoicingCouponDetailViewState_1 = require("./editInvoicingCouponDetailViewState");
|
|
8
9
|
exports.initialState = {
|
|
9
10
|
fetchState: 'Not-Started',
|
|
@@ -24,7 +25,7 @@ const editInvoicingCouponDetailView = (0, toolkit_1.createSlice)({
|
|
|
24
25
|
updateInvoicingCouponFormDraft(draft, action) {
|
|
25
26
|
const { id, localData } = action.payload;
|
|
26
27
|
if (id != null) {
|
|
27
|
-
draft.editDraftById
|
|
28
|
+
(0, invoicingFormDraft_1.applyInvoicingFormDraftEdit)(draft.editDraftById, id, localData);
|
|
28
29
|
}
|
|
29
30
|
else {
|
|
30
31
|
draft.newCouponDraft = localData;
|
|
@@ -54,6 +55,9 @@ const editInvoicingCouponDetailView = (0, toolkit_1.createSlice)({
|
|
|
54
55
|
draft.fetchState = 'Completed';
|
|
55
56
|
draft.error = undefined;
|
|
56
57
|
draft.savedCouponId = action.payload.couponId;
|
|
58
|
+
// An edit is refetched on success; keep the saved values on screen until
|
|
59
|
+
// that lands, and let it replace them.
|
|
60
|
+
(0, invoicingFormDraft_1.applyInvoicingFormDraftSaved)(draft.editDraftById, action.payload.couponId);
|
|
57
61
|
},
|
|
58
62
|
submitInvoicingCouponFormFailure(draft, action) {
|
|
59
63
|
draft.fetchState = 'Error';
|
|
@@ -89,15 +93,12 @@ const editInvoicingCouponDetailView = (0, toolkit_1.createSlice)({
|
|
|
89
93
|
fetchState: 'Error',
|
|
90
94
|
error: action.payload.status,
|
|
91
95
|
};
|
|
96
|
+
(0, invoicingFormDraft_1.applyInvoicingFormDraftFailure)(draft.editDraftById, action.payload.id, editInvoicingCouponDetailViewState_1.initialInvoicingCouponFormLocalData);
|
|
92
97
|
},
|
|
93
|
-
/**
|
|
94
|
-
* Seed the draft from the loaded record, once. Skipped when a draft already
|
|
95
|
-
* exists so a late refetch cannot overwrite in-progress edits.
|
|
96
|
-
*/
|
|
98
|
+
/** Fill the draft from the loaded record — see `applyInvoicingFormDraftSeed`. */
|
|
97
99
|
seedInvoicingCouponFormDraft(draft, action) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
100
|
+
const { id, localData } = action.payload;
|
|
101
|
+
(0, invoicingFormDraft_1.applyInvoicingFormDraftSeed)(draft.editDraftById, id, localData);
|
|
101
102
|
},
|
|
102
103
|
runInvoicingDiscountAction(draft, action) {
|
|
103
104
|
draft.actionStateById[action.payload.id] = {
|
|
@@ -117,12 +118,22 @@ const editInvoicingCouponDetailView = (0, toolkit_1.createSlice)({
|
|
|
117
118
|
error: action.payload.error,
|
|
118
119
|
};
|
|
119
120
|
},
|
|
120
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Discard a form's draft — the coupon's own when `id` is given,
|
|
123
|
+
* the create draft otherwise. Scoped to the one form on purpose: another
|
|
124
|
+
* coupon's half-finished edit is not this form's to throw away.
|
|
125
|
+
* Clearing every draft at once is what `clearAll` is for.
|
|
126
|
+
*/
|
|
127
|
+
resetEditInvoicingCouponDetailView(draft, action) {
|
|
121
128
|
draft.fetchState = 'Not-Started';
|
|
122
129
|
draft.error = undefined;
|
|
123
130
|
draft.savedCouponId = undefined;
|
|
124
|
-
|
|
125
|
-
|
|
131
|
+
const id = action.payload?.id;
|
|
132
|
+
if (id == null) {
|
|
133
|
+
draft.newCouponDraft = { ...editInvoicingCouponDetailViewState_1.initialInvoicingCouponFormLocalData };
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
delete draft.editDraftById[id];
|
|
126
137
|
},
|
|
127
138
|
},
|
|
128
139
|
extraReducers: (builder) => {
|
package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewSelector.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NestedAccountHierarchyForReport } from '../../../commonStateTypes/accountView/nestedAccountID';
|
|
1
2
|
import { FetchState, FetchStateAndError, ID } from '../../../commonStateTypes/common';
|
|
2
3
|
import { SelectorView } from '../../../commonStateTypes/viewAndReport/viewAndReport';
|
|
3
4
|
import { InvoicingCoupon } from '../../../entity/invoicing/coupon/couponState';
|
|
@@ -18,6 +19,19 @@ export interface EditInvoicingCouponDetailView extends SelectorView {
|
|
|
18
19
|
* Folded in here so the screen never reaches for the config view itself.
|
|
19
20
|
*/
|
|
20
21
|
fieldHelp: InvoicingFieldHelpByCode;
|
|
22
|
+
/**
|
|
23
|
+
* True while the coupon being edited is still on its way to the form. The
|
|
24
|
+
* form holds a skeleton on this rather than mount: it seeds react-hook-form
|
|
25
|
+
* once, at first render, so fields mounted against the blank draft stay blank
|
|
26
|
+
* and the first change writes that blankness back over the coupon. A later
|
|
27
|
+
* refetch does not raise this again, so a refresh leaves the form on screen
|
|
28
|
+
* instead of blanking it mid-edit.
|
|
29
|
+
*
|
|
30
|
+
* Narrower than `pageFetchState`, which also waits on the accounting lists:
|
|
31
|
+
* the discounts-account picker carries its own loading state, so the form is
|
|
32
|
+
* useful before the lists land.
|
|
33
|
+
*/
|
|
34
|
+
isFormLoading: boolean;
|
|
21
35
|
/**
|
|
22
36
|
* Every request the page renders from, reduced to one state: the record and
|
|
23
37
|
* the config behind its dropdowns and field help. The page holds a skeleton
|
|
@@ -30,6 +44,15 @@ export interface EditInvoicingCouponDetailView extends SelectorView {
|
|
|
30
44
|
*/
|
|
31
45
|
recordState: FetchStateAndError;
|
|
32
46
|
coupon?: InvoicingCoupon;
|
|
47
|
+
/**
|
|
48
|
+
* The name of the account the coupon's discount line posts to, resolved from
|
|
49
|
+
* the id the coupon stores against the shared QuickBooks account list.
|
|
50
|
+
* Resolved here rather than carried on the entity: the account is a record
|
|
51
|
+
* the accounting lists already own, and the coupon only ever stored a
|
|
52
|
+
* reference to it. Absent while the list is still loading, or when the id
|
|
53
|
+
* names an account this tenant can no longer see.
|
|
54
|
+
*/
|
|
55
|
+
discountsAccountName?: string;
|
|
33
56
|
savedCouponId?: ID;
|
|
34
57
|
}
|
|
35
58
|
export declare const getEditInvoicingCouponDetailViewState: (state: RootState, couponId?: ID) => EditInvoicingCouponDetailView;
|
|
@@ -42,9 +65,32 @@ export interface InvoicingCouponFormView extends EditInvoicingCouponDetailView {
|
|
|
42
65
|
* Folded in here so the screen never reaches for the config view itself.
|
|
43
66
|
*/
|
|
44
67
|
fieldHelp: InvoicingFieldHelpByCode;
|
|
68
|
+
/**
|
|
69
|
+
* False hides the discounts-account picker outright: with no QuickBooks
|
|
70
|
+
* connection there are no accounts to offer, and a coupon saves fine without
|
|
71
|
+
* one.
|
|
72
|
+
*/
|
|
73
|
+
isQboConnected: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* True while the accounting lists are still loading, so the discounts-account
|
|
76
|
+
* picker can show as busy rather than as an empty list.
|
|
77
|
+
*/
|
|
78
|
+
isQboPickerDataLoading: boolean;
|
|
45
79
|
localData: InvoicingCouponFormLocalData;
|
|
46
80
|
mode: 'create' | 'edit';
|
|
47
81
|
periodUnitOptions: InvoicingFormOption[];
|
|
82
|
+
/**
|
|
83
|
+
* The account tree the discounts-account picker renders, and the QuickBooks
|
|
84
|
+
* ids within it the discounts slot accepts. Two values rather than a filtered
|
|
85
|
+
* tree: the picker flattens the tree into options by walking each node's
|
|
86
|
+
* children, so dropping a parent that is not itself an income account would
|
|
87
|
+
* drop its income descendants with it.
|
|
88
|
+
*
|
|
89
|
+
* Empty until QBO is connected — the form must not offer a mapping that
|
|
90
|
+
* cannot be pushed.
|
|
91
|
+
*/
|
|
92
|
+
qboAccountHierarchy: NestedAccountHierarchyForReport[];
|
|
93
|
+
qboIncomeAccountIds: string[];
|
|
48
94
|
}
|
|
49
95
|
/**
|
|
50
96
|
* Bundled view for the discount form screen: the edit view (save state + the
|
package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewSelector.js
CHANGED
|
@@ -1,16 +1,35 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getInvoicingCouponFormView = exports.getEditInvoicingCouponDetailViewState = void 0;
|
|
4
|
+
const toolkit_1 = require("@reduxjs/toolkit");
|
|
4
5
|
const reduceFetchState_1 = require("../../../commonStateTypes/reduceFetchState");
|
|
5
6
|
const couponSelector_1 = require("../../../entity/invoicing/coupon/couponSelector");
|
|
6
7
|
const invoicingCommonPayload_1 = require("../../../entity/invoicing/invoicingCommonPayload");
|
|
7
8
|
const invoicingConfigViewSelector_1 = require("../invoicingConfigView/invoicingConfigViewSelector");
|
|
9
|
+
const invoicingFormDraft_1 = require("../invoicingFormDraft");
|
|
10
|
+
const invoicingQboViewSelector_1 = require("../invoicingQboView/invoicingQboViewSelector");
|
|
11
|
+
const settingsViewSelector_1 = require("../settingsView/settingsViewSelector");
|
|
8
12
|
const editInvoicingCouponDetailViewState_1 = require("./editInvoicingCouponDetailViewState");
|
|
9
13
|
/**
|
|
10
14
|
* Bundled view for the discount create/edit form: the save fetch state/error,
|
|
11
15
|
* the id of the coupon last saved, and — when a `couponId` is passed (edit
|
|
12
16
|
* mode) — the existing coupon entity to prefill the form.
|
|
13
17
|
*/
|
|
18
|
+
/**
|
|
19
|
+
* The QuickBooks ids the discounts account may be picked from.
|
|
20
|
+
*
|
|
21
|
+
* Memoized, and collapsing to one shared empty array while QBO is disconnected:
|
|
22
|
+
* the form turns this into its picker options and re-seeds its defaults when
|
|
23
|
+
* those change, so a fresh array on every store change would reset the form
|
|
24
|
+
* under the user until their first edit.
|
|
25
|
+
*/
|
|
26
|
+
const getInvoicingCouponDiscountsAccountIds = (0, toolkit_1.createSelector)([
|
|
27
|
+
invoicingQboViewSelector_1.getInvoicingQboAccountOptions,
|
|
28
|
+
(state) => (0, invoicingConfigViewSelector_1.getInvoicingConfigView)(state).qboAccountMappingKindOptions,
|
|
29
|
+
invoicingQboViewSelector_1.isInvoicingQboConnected,
|
|
30
|
+
], (accounts, qboAccountMappingKindOptions, isQboConnected) => isQboConnected
|
|
31
|
+
? (0, invoicingQboViewSelector_1.invoicingQboAccountIdsForMappingSlot)(accounts, qboAccountMappingKindOptions, invoicingQboViewSelector_1.INVOICING_DISCOUNTS_ACCOUNT_MAPPING_SLOT, invoicingQboViewSelector_1.INVOICING_DEFAULT_INCOME_ACCOUNT_TYPES)
|
|
32
|
+
: invoicingQboViewSelector_1.NO_INVOICING_ACCOUNT_IDS);
|
|
14
33
|
const NOT_STARTED = {
|
|
15
34
|
error: undefined,
|
|
16
35
|
fetchState: 'Not-Started',
|
|
@@ -26,6 +45,9 @@ const getEditInvoicingCouponDetailViewState = (state, couponId) => {
|
|
|
26
45
|
fetchState: 'Not-Started',
|
|
27
46
|
})
|
|
28
47
|
: { error: undefined, fetchState: 'Completed' };
|
|
48
|
+
const coupon = couponId != null
|
|
49
|
+
? (0, couponSelector_1.getInvoicingCouponById)(state.invoicingCouponState, couponId)
|
|
50
|
+
: undefined;
|
|
29
51
|
return {
|
|
30
52
|
actionState: couponId != null
|
|
31
53
|
? (state.editInvoicingCouponDetailViewState.actionStateById[couponId] ??
|
|
@@ -39,9 +61,9 @@ const getEditInvoicingCouponDetailViewState = (state, couponId) => {
|
|
|
39
61
|
{ error: undefined, fetchState: configFetchState },
|
|
40
62
|
]),
|
|
41
63
|
recordState,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
64
|
+
isFormLoading: (0, invoicingFormDraft_1.isInvoicingFormDraftPending)(state.editInvoicingCouponDetailViewState.editDraftById, couponId),
|
|
65
|
+
coupon,
|
|
66
|
+
discountsAccountName: (0, invoicingQboViewSelector_1.invoicingQboAccountByQboId)(state, coupon?.discountsAccountId)?.accountName,
|
|
45
67
|
savedCouponId,
|
|
46
68
|
fetchState,
|
|
47
69
|
error,
|
|
@@ -62,17 +84,58 @@ const getInvoicingCouponFormView = (state, couponId) => {
|
|
|
62
84
|
// `seedInvoicingCouponFormDraftEpic` when the detail load lands. Until then
|
|
63
85
|
// the page is showing its skeleton.
|
|
64
86
|
const localData = couponId != null
|
|
65
|
-
? (editDraftById
|
|
87
|
+
? (0, invoicingFormDraft_1.getInvoicingFormDraftLocalData)(editDraftById, couponId, editInvoicingCouponDetailViewState_1.initialInvoicingCouponFormLocalData)
|
|
66
88
|
: newCouponDraft;
|
|
67
89
|
const { billingPeriodUnitOptions, discountApplyOnOptions, discountDurationTypeOptions, discountTypeOptions, } = (0, invoicingConfigViewSelector_1.getInvoicingConfigView)(state);
|
|
90
|
+
const isQboConnected = (0, invoicingQboViewSelector_1.isInvoicingQboConnected)(state);
|
|
91
|
+
const qboView = isQboConnected ? (0, invoicingQboViewSelector_1.getInvoicingQboView)(state) : undefined;
|
|
92
|
+
const isQboPickerDataLoading = (0, invoicingQboViewSelector_1.isInvoicingAccountingPickerDataLoading)(state);
|
|
93
|
+
const settingsFetchState = (0, settingsViewSelector_1.getInvoicingSettingsFetchState)(state).fetchState;
|
|
94
|
+
// Only a create reads the settings, and only until they arrive: an `Error`
|
|
95
|
+
// is a create that starts on no account, not a page that never renders.
|
|
96
|
+
const isCreateSeedPending = couponId == null &&
|
|
97
|
+
(settingsFetchState === 'Not-Started' ||
|
|
98
|
+
settingsFetchState === 'In-Progress');
|
|
68
99
|
return {
|
|
69
100
|
...base,
|
|
70
101
|
applyOnOptions: discountApplyOnOptions.map(invoicingCommonPayload_1.toInvoicingFormOption),
|
|
71
102
|
discountTypeOptions: discountTypeOptions.map(invoicingCommonPayload_1.toInvoicingFormOption),
|
|
72
103
|
durationTypeOptions: discountDurationTypeOptions.map(invoicingCommonPayload_1.toInvoicingFormOption),
|
|
73
|
-
|
|
104
|
+
isQboConnected,
|
|
105
|
+
isQboPickerDataLoading,
|
|
106
|
+
// Widened past the record and config the detail page waits on: the form
|
|
107
|
+
// also renders from the account list, and seeds a create from the settings
|
|
108
|
+
// discounts account. A form that mounted before those landed would offer an
|
|
109
|
+
// empty picker and save a coupon with no account of its own — not wrong,
|
|
110
|
+
// since blank means "use the settings account", but not what the user was
|
|
111
|
+
// shown either. Widened here rather than on the base view, so the detail
|
|
112
|
+
// page does not start waiting on lists it never renders.
|
|
113
|
+
//
|
|
114
|
+
// Only while they are still coming, though, and the settings only on a
|
|
115
|
+
// create: a coupon saves fine without a discounts account, so neither is
|
|
116
|
+
// allowed to hold the form behind a skeleton once it has failed.
|
|
117
|
+
pageFetchState: (0, reduceFetchState_1.reduceAllFetchState)([
|
|
118
|
+
base.pageFetchState,
|
|
119
|
+
{
|
|
120
|
+
error: undefined,
|
|
121
|
+
fetchState: isQboPickerDataLoading || isCreateSeedPending
|
|
122
|
+
? 'In-Progress'
|
|
123
|
+
: 'Completed',
|
|
124
|
+
},
|
|
125
|
+
]),
|
|
126
|
+
localData: couponId != null
|
|
127
|
+
? localData
|
|
128
|
+
: {
|
|
129
|
+
...localData,
|
|
130
|
+
// Seeded from settings only while the draft has none of its own, so
|
|
131
|
+
// the picker shows the account a create would post against before
|
|
132
|
+
// the user touches it, and stops seeding the moment they pick.
|
|
133
|
+
discountsAccountId: (0, editInvoicingCouponDetailViewState_1.invoicingCouponDiscountsAccountIdForCreate)(localData.discountsAccountId, (0, settingsViewSelector_1.getInvoicingSettings)(state)?.qbo?.account_mappings),
|
|
134
|
+
},
|
|
74
135
|
mode: couponId != null ? 'edit' : 'create',
|
|
75
136
|
periodUnitOptions: billingPeriodUnitOptions.map(invoicingCommonPayload_1.toInvoicingFormOption),
|
|
137
|
+
qboAccountHierarchy: qboView?.nestedAccountHierarchy ?? invoicingQboViewSelector_1.NO_INVOICING_ACCOUNT_HIERARCHY,
|
|
138
|
+
qboIncomeAccountIds: getInvoicingCouponDiscountsAccountIds(state),
|
|
76
139
|
};
|
|
77
140
|
};
|
|
78
141
|
exports.getInvoicingCouponFormView = getInvoicingCouponFormView;
|
package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewState.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Amount } from '../../../commonStateTypes/amount';
|
|
2
2
|
import { FetchStateAndError, FetchedState, ID } from '../../../commonStateTypes/common';
|
|
3
3
|
import { InvoicingCoupon } from '../../../entity/invoicing/coupon/couponState';
|
|
4
|
+
import { InvoicingQboAccountMappingsPayload } from '../../../entity/invoicing/invoicingCommonPayload';
|
|
5
|
+
import { InvoicingFormDraftById } from '../invoicingFormDraft';
|
|
4
6
|
/**
|
|
5
7
|
* Draft form state for the create/edit discount-coupon form. Held in CES so the
|
|
6
8
|
* form flows its data from here (mirrors the customer form pattern). Dates are
|
|
@@ -13,6 +15,13 @@ export interface InvoicingCouponFormLocalData {
|
|
|
13
15
|
couponId: string;
|
|
14
16
|
discountPercentage: string;
|
|
15
17
|
discountQuantity: string;
|
|
18
|
+
/**
|
|
19
|
+
* The income account for this coupon's discount line, as the id its picker
|
|
20
|
+
* submits. Blank means "no account of its own", which is what makes the QBO
|
|
21
|
+
* settings discounts account apply instead — so on create it is seeded from
|
|
22
|
+
* that setting rather than left empty.
|
|
23
|
+
*/
|
|
24
|
+
discountsAccountId: string;
|
|
16
25
|
discountType: string;
|
|
17
26
|
durationType: string;
|
|
18
27
|
invoiceName: string;
|
|
@@ -29,7 +38,7 @@ export interface InvoicingCouponFormLocalData {
|
|
|
29
38
|
export interface EditInvoicingCouponDetailViewState extends FetchedState {
|
|
30
39
|
/** Lifecycle action (archive, activate, …) fetch state per coupon id. */
|
|
31
40
|
actionStateById: Record<ID, FetchStateAndError>;
|
|
32
|
-
editDraftById:
|
|
41
|
+
editDraftById: InvoicingFormDraftById<InvoicingCouponFormLocalData>;
|
|
33
42
|
newCouponDraft: InvoicingCouponFormLocalData;
|
|
34
43
|
/** Detail-load state per coupon id. */
|
|
35
44
|
recordStateById: Record<ID, FetchStateAndError>;
|
|
@@ -38,3 +47,14 @@ export interface EditInvoicingCouponDetailViewState extends FetchedState {
|
|
|
38
47
|
export declare const initialInvoicingCouponFormLocalData: InvoicingCouponFormLocalData;
|
|
39
48
|
/** Seed the form draft from an existing coupon entity (edit mode). */
|
|
40
49
|
export declare const entityToInvoicingCouponFormLocalData: (coupon?: InvoicingCoupon) => InvoicingCouponFormLocalData;
|
|
50
|
+
/**
|
|
51
|
+
* The discounts account a create starts from: the draft's own pick, or the QBO
|
|
52
|
+
* settings discounts account while the user has not made one. Read by both the
|
|
53
|
+
* form view and the save, so what the picker shows is what the request sends —
|
|
54
|
+
* a create that leaves the picker alone still stores the settings account on
|
|
55
|
+
* the coupon rather than relying on the setting staying put.
|
|
56
|
+
*
|
|
57
|
+
* Create only. An edit shows the coupon's stored account, so a coupon saved
|
|
58
|
+
* without one keeps showing none.
|
|
59
|
+
*/
|
|
60
|
+
export declare const invoicingCouponDiscountsAccountIdForCreate: (discountsAccountId: string, accountMappings: InvoicingQboAccountMappingsPayload | null | undefined) => string;
|
package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewState.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.entityToInvoicingCouponFormLocalData = exports.initialInvoicingCouponFormLocalData = void 0;
|
|
3
|
+
exports.invoicingCouponDiscountsAccountIdForCreate = exports.entityToInvoicingCouponFormLocalData = exports.initialInvoicingCouponFormLocalData = void 0;
|
|
4
|
+
const invoicingCommonPayload_1 = require("../../../entity/invoicing/invoicingCommonPayload");
|
|
4
5
|
exports.initialInvoicingCouponFormLocalData = {
|
|
5
6
|
applyOn: 'invoice_amount',
|
|
6
7
|
couponCode: '',
|
|
7
8
|
couponId: '',
|
|
8
9
|
discountPercentage: '',
|
|
9
10
|
discountQuantity: '',
|
|
11
|
+
discountsAccountId: '',
|
|
10
12
|
discountType: 'percentage',
|
|
11
13
|
durationType: 'one_time',
|
|
12
14
|
invoiceName: '',
|
|
@@ -32,6 +34,10 @@ const entityToInvoicingCouponFormLocalData = (coupon) => {
|
|
|
32
34
|
? String(coupon.discountPercentage)
|
|
33
35
|
: '',
|
|
34
36
|
discountQuantity: coupon.discountQuantity != null ? String(coupon.discountQuantity) : '',
|
|
37
|
+
// The coupon's own account, never the current setting: an edit shows what
|
|
38
|
+
// this coupon will post against, which is what was stored when it was
|
|
39
|
+
// saved even if the settings default has moved since.
|
|
40
|
+
discountsAccountId: coupon.discountsAccountId ?? '',
|
|
35
41
|
discountType: coupon.discountType ?? 'percentage',
|
|
36
42
|
durationType: coupon.durationType ?? 'one_time',
|
|
37
43
|
invoiceName: coupon.invoiceName ?? '',
|
|
@@ -45,3 +51,20 @@ const entityToInvoicingCouponFormLocalData = (coupon) => {
|
|
|
45
51
|
};
|
|
46
52
|
};
|
|
47
53
|
exports.entityToInvoicingCouponFormLocalData = entityToInvoicingCouponFormLocalData;
|
|
54
|
+
/**
|
|
55
|
+
* The discounts account a create starts from: the draft's own pick, or the QBO
|
|
56
|
+
* settings discounts account while the user has not made one. Read by both the
|
|
57
|
+
* form view and the save, so what the picker shows is what the request sends —
|
|
58
|
+
* a create that leaves the picker alone still stores the settings account on
|
|
59
|
+
* the coupon rather than relying on the setting staying put.
|
|
60
|
+
*
|
|
61
|
+
* Create only. An edit shows the coupon's stored account, so a coupon saved
|
|
62
|
+
* without one keeps showing none.
|
|
63
|
+
*/
|
|
64
|
+
const invoicingCouponDiscountsAccountIdForCreate = (discountsAccountId, accountMappings) => {
|
|
65
|
+
const pickedAccountId = discountsAccountId.trim();
|
|
66
|
+
return pickedAccountId !== ''
|
|
67
|
+
? pickedAccountId
|
|
68
|
+
: ((0, invoicingCommonPayload_1.getInvoicingQboAccountMappingId)(accountMappings ?? undefined, 'discounts_account') ?? '');
|
|
69
|
+
};
|
|
70
|
+
exports.invoicingCouponDiscountsAccountIdForCreate = invoicingCouponDiscountsAccountIdForCreate;
|
package/lib/view/invoicing/editInvoicingCouponDetailView/fetchInvoicingCouponDetailPageEpic.d.ts
CHANGED
|
@@ -2,12 +2,16 @@ import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
import { RootState } from '../../../rootStateTypes';
|
|
4
4
|
import { fetchInvoicingConfig } from '../invoicingConfigView/invoicingConfigViewReducer';
|
|
5
|
+
import { fetchInvoicingAccountingPickers, fetchInvoicingQboConnection } from '../invoicingQboView/invoicingQboViewReducer';
|
|
6
|
+
import { fetchInvoicingSettings } from '../settingsView/settingsViewReducer';
|
|
5
7
|
import { fetchInvoicingCouponDetail, fetchInvoicingCouponDetailPage } from './editInvoicingCouponDetailViewReducer';
|
|
6
|
-
export type ActionType = ReturnType<typeof fetchInvoicingCouponDetailPage> | ReturnType<typeof fetchInvoicingCouponDetail> | ReturnType<typeof fetchInvoicingConfig>;
|
|
8
|
+
export type ActionType = ReturnType<typeof fetchInvoicingCouponDetailPage> | ReturnType<typeof fetchInvoicingCouponDetail> | ReturnType<typeof fetchInvoicingConfig> | ReturnType<typeof fetchInvoicingQboConnection> | ReturnType<typeof fetchInvoicingAccountingPickers> | ReturnType<typeof fetchInvoicingSettings>;
|
|
7
9
|
/**
|
|
8
|
-
* Orchestrates the discount
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* Orchestrates the discount pages: one action fans out to the coupon record,
|
|
11
|
+
* the invoicing config behind its dropdowns and field help, and the QuickBooks
|
|
12
|
+
* connection, account list and settings the form's Discounts account picker
|
|
13
|
+
* renders and seeds from — each skipped when already cached. The page reads a
|
|
14
|
+
* single reduced fetch state off the view, so the form mounts once with real
|
|
15
|
+
* values.
|
|
12
16
|
*/
|
|
13
17
|
export declare const fetchInvoicingCouponDetailPageEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>) => Observable<ActionType>;
|
package/lib/view/invoicing/editInvoicingCouponDetailView/fetchInvoicingCouponDetailPageEpic.js
CHANGED
|
@@ -4,6 +4,8 @@ exports.fetchInvoicingCouponDetailPageEpic = void 0;
|
|
|
4
4
|
const rxjs_1 = require("rxjs");
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
6
|
const invoicingConfigViewReducer_1 = require("../invoicingConfigView/invoicingConfigViewReducer");
|
|
7
|
+
const invoicingQboViewReducer_1 = require("../invoicingQboView/invoicingQboViewReducer");
|
|
8
|
+
const settingsViewReducer_1 = require("../settingsView/settingsViewReducer");
|
|
7
9
|
const editInvoicingCouponDetailViewReducer_1 = require("./editInvoicingCouponDetailViewReducer");
|
|
8
10
|
/**
|
|
9
11
|
* Fetch unless the endpoint is already loaded or in flight — or always when the
|
|
@@ -13,10 +15,12 @@ const shouldFetch = (fetchStateAndError, cacheOverride) => cacheOverride ||
|
|
|
13
15
|
(fetchStateAndError.fetchState !== 'Completed' &&
|
|
14
16
|
fetchStateAndError.fetchState !== 'In-Progress');
|
|
15
17
|
/**
|
|
16
|
-
* Orchestrates the discount
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
18
|
+
* Orchestrates the discount pages: one action fans out to the coupon record,
|
|
19
|
+
* the invoicing config behind its dropdowns and field help, and the QuickBooks
|
|
20
|
+
* connection, account list and settings the form's Discounts account picker
|
|
21
|
+
* renders and seeds from — each skipped when already cached. The page reads a
|
|
22
|
+
* single reduced fetch state off the view, so the form mounts once with real
|
|
23
|
+
* values.
|
|
20
24
|
*/
|
|
21
25
|
const fetchInvoicingCouponDetailPageEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)(editInvoicingCouponDetailViewReducer_1.fetchInvoicingCouponDetailPage.match), (0, operators_1.withLatestFrom)(state$), (0, operators_1.mergeMap)(([action, state]) => {
|
|
22
26
|
const { cacheOverride = false, id } = action.payload;
|
|
@@ -35,6 +39,20 @@ const fetchInvoicingCouponDetailPageEpic = (actions$, state$) => actions$.pipe((
|
|
|
35
39
|
if (shouldFetch({ error: configState.error, fetchState: configState.fetchState }, cacheOverride)) {
|
|
36
40
|
pageActions.push((0, invoicingConfigViewReducer_1.fetchInvoicingConfig)());
|
|
37
41
|
}
|
|
42
|
+
const qboState = state.invoicingQboViewState;
|
|
43
|
+
if (shouldFetch(qboState.connectionFetchState, cacheOverride)) {
|
|
44
|
+
pageActions.push((0, invoicingQboViewReducer_1.fetchInvoicingQboConnection)());
|
|
45
|
+
}
|
|
46
|
+
// The picker epic tops up the shared account list and skips what the
|
|
47
|
+
// store already holds, so this is safe to ask for on every open.
|
|
48
|
+
pageActions.push((0, invoicingQboViewReducer_1.fetchInvoicingAccountingPickers)());
|
|
49
|
+
const settingsState = state.invoicingSettingsViewState;
|
|
50
|
+
if (shouldFetch({ error: settingsState.error, fetchState: settingsState.fetchState }, cacheOverride)) {
|
|
51
|
+
// A create seeds its Discounts account from the settings mapping, so
|
|
52
|
+
// the settings are page data here rather than a settings-screen
|
|
53
|
+
// concern.
|
|
54
|
+
pageActions.push((0, settingsViewReducer_1.fetchInvoicingSettings)());
|
|
55
|
+
}
|
|
38
56
|
return pageActions.length > 0 ? (0, rxjs_1.from)(pageActions) : rxjs_1.EMPTY;
|
|
39
57
|
}));
|
|
40
58
|
exports.fetchInvoicingCouponDetailPageEpic = fetchInvoicingCouponDetailPageEpic;
|