@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
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.syncInvoicingSubscriptionCoupons = exports.initializeInvoicingSubscriptionAddress = exports.resetEditInvoicingSubscriptionDetailView = exports.submitInvoicingSubscriptionFormFailure = exports.submitInvoicingSubscriptionFormSuccess = exports.submitInvoicingSubscriptionForm = exports.updateInvoicingSubscriptionFormDraft = exports.updateInvoicingSubscriptionDetailFailure = exports.updateInvoicingSubscriptionDetail = exports.seedInvoicingSubscriptionFormDraft = exports.fetchInvoicingSubscriptionFormPage = exports.fetchInvoicingSubscriptionDetailPage = exports.fetchInvoicingSubscriptionDetail = exports.runInvoicingSubscriptionActionSuccess = exports.runInvoicingSubscriptionActionFailure = exports.runInvoicingSubscriptionAction = exports.initialState = void 0;
|
|
4
|
+
exports.syncInvoicingSubscriptionCoupons = exports.claimInvoicingSubscriptionShippingAddress = exports.initializeInvoicingSubscriptionAddress = exports.resetEditInvoicingSubscriptionDetailView = exports.submitInvoicingSubscriptionFormFailure = exports.submitInvoicingSubscriptionFormSuccess = exports.submitInvoicingSubscriptionForm = exports.updateInvoicingSubscriptionFormDraft = exports.updateInvoicingSubscriptionDetailFailure = exports.updateInvoicingSubscriptionDetail = exports.seedInvoicingSubscriptionFormDraft = exports.fetchInvoicingSubscriptionFormPage = exports.fetchInvoicingSubscriptionDetailPage = exports.fetchInvoicingSubscriptionDetail = exports.runInvoicingSubscriptionActionSuccess = exports.runInvoicingSubscriptionActionFailure = exports.runInvoicingSubscriptionAction = 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 invoicingSubscriptionFormConfig_1 = require("./invoicingSubscriptionFormConfig");
|
|
8
9
|
exports.initialState = {
|
|
9
10
|
fetchState: 'Not-Started',
|
|
@@ -11,6 +12,7 @@ exports.initialState = {
|
|
|
11
12
|
editDraftById: {},
|
|
12
13
|
actionStateById: {},
|
|
13
14
|
recordStateById: {},
|
|
15
|
+
shippingAddressOwnerId: undefined,
|
|
14
16
|
newSubscriptionDraft: { ...invoicingSubscriptionFormConfig_1.initialInvoicingSubscriptionFormLocalData },
|
|
15
17
|
savedSubscriptionId: undefined,
|
|
16
18
|
hasValidState() {
|
|
@@ -69,15 +71,12 @@ const editInvoicingSubscriptionDetailView = (0, toolkit_1.createSlice)({
|
|
|
69
71
|
fetchState: 'Error',
|
|
70
72
|
error: action.payload.error,
|
|
71
73
|
};
|
|
74
|
+
(0, invoicingFormDraft_1.applyInvoicingFormDraftFailure)(draft.editDraftById, action.payload.id, invoicingSubscriptionFormConfig_1.initialInvoicingSubscriptionFormLocalData);
|
|
72
75
|
},
|
|
73
|
-
/**
|
|
74
|
-
* Seed the draft from the loaded record, once. Skipped when a draft already
|
|
75
|
-
* exists so a late refetch cannot overwrite in-progress edits.
|
|
76
|
-
*/
|
|
76
|
+
/** Fill the draft from the loaded record — see `applyInvoicingFormDraftSeed`. */
|
|
77
77
|
seedInvoicingSubscriptionFormDraft(draft, action) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
78
|
+
const { id, localData } = action.payload;
|
|
79
|
+
(0, invoicingFormDraft_1.applyInvoicingFormDraftSeed)(draft.editDraftById, id, localData);
|
|
81
80
|
},
|
|
82
81
|
fetchInvoicingSubscriptionFormPage: {
|
|
83
82
|
reducer() {
|
|
@@ -91,7 +90,7 @@ const editInvoicingSubscriptionDetailView = (0, toolkit_1.createSlice)({
|
|
|
91
90
|
updateInvoicingSubscriptionFormDraft(draft, action) {
|
|
92
91
|
const { id, localData } = action.payload;
|
|
93
92
|
if (id != null) {
|
|
94
|
-
draft.editDraftById
|
|
93
|
+
(0, invoicingFormDraft_1.applyInvoicingFormDraftEdit)(draft.editDraftById, id, localData);
|
|
95
94
|
}
|
|
96
95
|
else {
|
|
97
96
|
draft.newSubscriptionDraft = localData;
|
|
@@ -111,19 +110,32 @@ const editInvoicingSubscriptionDetailView = (0, toolkit_1.createSlice)({
|
|
|
111
110
|
draft.fetchState = 'Completed';
|
|
112
111
|
draft.error = undefined;
|
|
113
112
|
draft.savedSubscriptionId = action.payload.subscriptionId;
|
|
113
|
+
// An edit is refetched on success; keep the saved values on screen until
|
|
114
|
+
// that lands, and let it replace them.
|
|
115
|
+
(0, invoicingFormDraft_1.applyInvoicingFormDraftSaved)(draft.editDraftById, action.payload.subscriptionId);
|
|
114
116
|
},
|
|
115
117
|
submitInvoicingSubscriptionFormFailure(draft, action) {
|
|
116
118
|
draft.fetchState = 'Error';
|
|
117
119
|
draft.error = action.payload;
|
|
118
120
|
},
|
|
119
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Discard a form's draft — the subscription's own when `id` is given,
|
|
123
|
+
* the create draft otherwise. Scoped to the one form on purpose: another
|
|
124
|
+
* subscription'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
|
+
resetEditInvoicingSubscriptionDetailView(draft, action) {
|
|
120
128
|
draft.fetchState = 'Not-Started';
|
|
121
129
|
draft.error = undefined;
|
|
122
130
|
draft.savedSubscriptionId = undefined;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
131
|
+
const id = action.payload?.id;
|
|
132
|
+
if (id == null) {
|
|
133
|
+
draft.newSubscriptionDraft = {
|
|
134
|
+
...invoicingSubscriptionFormConfig_1.initialInvoicingSubscriptionFormLocalData,
|
|
135
|
+
};
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
delete draft.editDraftById[id];
|
|
127
139
|
},
|
|
128
140
|
// Trigger only — handled by initializeInvoicingSubscriptionAddressEpic.
|
|
129
141
|
initializeInvoicingSubscriptionAddress: {
|
|
@@ -132,6 +144,10 @@ const editInvoicingSubscriptionDetailView = (0, toolkit_1.createSlice)({
|
|
|
132
144
|
return { payload };
|
|
133
145
|
},
|
|
134
146
|
},
|
|
147
|
+
/** Record which subscription the shared shipping-address slot now belongs to. */
|
|
148
|
+
claimInvoicingSubscriptionShippingAddress(draft, action) {
|
|
149
|
+
draft.shippingAddressOwnerId = action.payload.id;
|
|
150
|
+
},
|
|
135
151
|
// Trigger only — handled by syncInvoicingSubscriptionCouponsEpic.
|
|
136
152
|
syncInvoicingSubscriptionCoupons: {
|
|
137
153
|
reducer() { },
|
|
@@ -146,5 +162,5 @@ const editInvoicingSubscriptionDetailView = (0, toolkit_1.createSlice)({
|
|
|
146
162
|
});
|
|
147
163
|
},
|
|
148
164
|
});
|
|
149
|
-
_a = editInvoicingSubscriptionDetailView.actions, exports.runInvoicingSubscriptionAction = _a.runInvoicingSubscriptionAction, exports.runInvoicingSubscriptionActionFailure = _a.runInvoicingSubscriptionActionFailure, exports.runInvoicingSubscriptionActionSuccess = _a.runInvoicingSubscriptionActionSuccess, exports.fetchInvoicingSubscriptionDetail = _a.fetchInvoicingSubscriptionDetail, exports.fetchInvoicingSubscriptionDetailPage = _a.fetchInvoicingSubscriptionDetailPage, exports.fetchInvoicingSubscriptionFormPage = _a.fetchInvoicingSubscriptionFormPage, exports.seedInvoicingSubscriptionFormDraft = _a.seedInvoicingSubscriptionFormDraft, exports.updateInvoicingSubscriptionDetail = _a.updateInvoicingSubscriptionDetail, exports.updateInvoicingSubscriptionDetailFailure = _a.updateInvoicingSubscriptionDetailFailure, exports.updateInvoicingSubscriptionFormDraft = _a.updateInvoicingSubscriptionFormDraft, exports.submitInvoicingSubscriptionForm = _a.submitInvoicingSubscriptionForm, exports.submitInvoicingSubscriptionFormSuccess = _a.submitInvoicingSubscriptionFormSuccess, exports.submitInvoicingSubscriptionFormFailure = _a.submitInvoicingSubscriptionFormFailure, exports.resetEditInvoicingSubscriptionDetailView = _a.resetEditInvoicingSubscriptionDetailView, exports.initializeInvoicingSubscriptionAddress = _a.initializeInvoicingSubscriptionAddress, exports.syncInvoicingSubscriptionCoupons = _a.syncInvoicingSubscriptionCoupons;
|
|
165
|
+
_a = editInvoicingSubscriptionDetailView.actions, exports.runInvoicingSubscriptionAction = _a.runInvoicingSubscriptionAction, exports.runInvoicingSubscriptionActionFailure = _a.runInvoicingSubscriptionActionFailure, exports.runInvoicingSubscriptionActionSuccess = _a.runInvoicingSubscriptionActionSuccess, exports.fetchInvoicingSubscriptionDetail = _a.fetchInvoicingSubscriptionDetail, exports.fetchInvoicingSubscriptionDetailPage = _a.fetchInvoicingSubscriptionDetailPage, exports.fetchInvoicingSubscriptionFormPage = _a.fetchInvoicingSubscriptionFormPage, exports.seedInvoicingSubscriptionFormDraft = _a.seedInvoicingSubscriptionFormDraft, exports.updateInvoicingSubscriptionDetail = _a.updateInvoicingSubscriptionDetail, exports.updateInvoicingSubscriptionDetailFailure = _a.updateInvoicingSubscriptionDetailFailure, exports.updateInvoicingSubscriptionFormDraft = _a.updateInvoicingSubscriptionFormDraft, exports.submitInvoicingSubscriptionForm = _a.submitInvoicingSubscriptionForm, exports.submitInvoicingSubscriptionFormSuccess = _a.submitInvoicingSubscriptionFormSuccess, exports.submitInvoicingSubscriptionFormFailure = _a.submitInvoicingSubscriptionFormFailure, exports.resetEditInvoicingSubscriptionDetailView = _a.resetEditInvoicingSubscriptionDetailView, exports.initializeInvoicingSubscriptionAddress = _a.initializeInvoicingSubscriptionAddress, exports.claimInvoicingSubscriptionShippingAddress = _a.claimInvoicingSubscriptionShippingAddress, exports.syncInvoicingSubscriptionCoupons = _a.syncInvoicingSubscriptionCoupons;
|
|
150
166
|
exports.default = editInvoicingSubscriptionDetailView.reducer;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
+
import { Amount } from '../../../commonStateTypes/amount';
|
|
1
2
|
import { FetchStateAndError, ID } from '../../../commonStateTypes/common';
|
|
2
3
|
import { SelectorView } from '../../../commonStateTypes/viewAndReport/viewAndReport';
|
|
3
|
-
import { InvoicingCoupon } from '../../../entity/invoicing/coupon/couponState';
|
|
4
4
|
import { InvoicingFieldHelpByCode, InvoicingNamedOption, InvoicingSubscriptionLifecycleActionOption } from '../../../entity/invoicing/invoicingCommonPayload';
|
|
5
|
-
import { InvoicingCustomer } from '../../../entity/invoicing/invoicingCustomer/invoicingCustomerState';
|
|
6
5
|
import { InvoicingSubscription } from '../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionState';
|
|
7
6
|
import { InvoicingProduct } from '../../../entity/invoicing/product/productState';
|
|
8
7
|
import { RootState } from '../../../rootStateTypes';
|
|
@@ -25,22 +24,35 @@ export interface EditInvoicingSubscriptionDetailView extends SelectorView {
|
|
|
25
24
|
* The full data the subscription form screen needs in one selector: the draft
|
|
26
25
|
* `localData` (seeded from the existing subscription in edit mode until the user
|
|
27
26
|
* edits), the shipping-address label (from the shared Address screen), the
|
|
28
|
-
* canonical billing-frequency value set, the
|
|
29
|
-
*
|
|
30
|
-
*
|
|
27
|
+
* canonical billing-frequency value set, the picker option lists (customers,
|
|
28
|
+
* plans, add-ons, charges, coupons) and the save state. The options are plain
|
|
29
|
+
* `{label, value}` records, so this stays free of any web-components
|
|
30
|
+
* dependency while leaving the screen nothing to derive.
|
|
31
31
|
*/
|
|
32
32
|
export interface InvoicingSubscriptionFormView extends SelectorView {
|
|
33
33
|
/** Lifecycle action in flight, folded in from the record view. */
|
|
34
34
|
actionState: FetchStateAndError;
|
|
35
|
+
/**
|
|
36
|
+
* Picker options, built here rather than by each screen so the create form
|
|
37
|
+
* and the detail page's inline edit cannot drift. `addons` and `charges` are
|
|
38
|
+
* already narrowed to what the selected plan allows.
|
|
39
|
+
*/
|
|
40
|
+
addons: InvoicingSubscriptionOption[];
|
|
35
41
|
/** Cancel reasons from `/1.0/config`, so the dialog hardcodes nothing. */
|
|
36
42
|
cancelReasonCodeOptions: InvoicingNamedOption[];
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
charges: InvoicingSubscriptionOption[];
|
|
44
|
+
coupons: InvoicingSubscriptionOption[];
|
|
45
|
+
customers: InvoicingSubscriptionOption[];
|
|
46
|
+
fieldHelp: InvoicingFieldHelpByCode;
|
|
39
47
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
48
|
+
* True while the subscription being edited is still on its way to the form.
|
|
49
|
+
* The form holds a skeleton on this rather than mount: it seeds
|
|
50
|
+
* react-hook-form once, at first render, so fields mounted against the blank
|
|
51
|
+
* draft stay blank and the first change writes that blankness back over the
|
|
52
|
+
* subscription. A later refetch does not raise this again, so a refresh
|
|
53
|
+
* leaves the form on screen instead of blanking it mid-edit.
|
|
42
54
|
*/
|
|
43
|
-
|
|
55
|
+
isFormLoading: boolean;
|
|
44
56
|
localData: InvoicingSubscriptionFormLocalData;
|
|
45
57
|
mode: 'create' | 'edit';
|
|
46
58
|
/**
|
|
@@ -54,16 +66,71 @@ export interface InvoicingSubscriptionFormView extends SelectorView {
|
|
|
54
66
|
* real values.
|
|
55
67
|
*/
|
|
56
68
|
pageFetchState: FetchStateAndError;
|
|
57
|
-
plans:
|
|
58
|
-
products: InvoicingProduct[];
|
|
69
|
+
plans: InvoicingSubscriptionOption[];
|
|
59
70
|
recordState: FetchStateAndError;
|
|
60
71
|
/** Config-owned edit/lifecycle rules, folded in so the screen reads one selector. */
|
|
61
72
|
subscriptionCommercialEditAllowedFromStatuses: string[];
|
|
62
73
|
subscriptionLifecycleActionOptions: InvoicingSubscriptionLifecycleActionOption[];
|
|
63
74
|
subscriptionMetadataEditAllowedFromStatuses: string[];
|
|
75
|
+
/**
|
|
76
|
+
* A shipping address entered on the Address screen that the subscription has
|
|
77
|
+
* not saved yet. The inline-edit form cannot see it — the address lives in the
|
|
78
|
+
* shared address store, not in a field — so the detail page reads this to
|
|
79
|
+
* offer Save, or the address could never be linked.
|
|
80
|
+
*/
|
|
81
|
+
hasUnsavedShippingAddress?: boolean;
|
|
64
82
|
savedSubscriptionId?: ID;
|
|
65
83
|
shippingAddressLabel?: string;
|
|
66
84
|
subscription?: InvoicingSubscription;
|
|
67
85
|
}
|
|
68
86
|
export declare const getEditInvoicingSubscriptionDetailViewState: (state: RootState, invoicingSubscriptionID?: ID) => EditInvoicingSubscriptionDetailView;
|
|
87
|
+
/**
|
|
88
|
+
* The add-ons / one-time charges a plan actually accepts.
|
|
89
|
+
*
|
|
90
|
+
* A catalog item is either `restricted` — it names the item ids it may be
|
|
91
|
+
* subscribed alongside in `applicableItems` — or unrestricted, in which case
|
|
92
|
+
* every item is fair game. Matching is on `itemID` (the catalog item the price
|
|
93
|
+
* row was flattened from), not the price code, because applicability is
|
|
94
|
+
* declared item-to-item.
|
|
95
|
+
*
|
|
96
|
+
* Fails open where the rule is unknown: no plan selected yet, a plan that is
|
|
97
|
+
* not `restricted`, or a `restricted` plan whose allow-list never came down all
|
|
98
|
+
* return the full list. The create/update endpoint rejects a disallowed item
|
|
99
|
+
* with a 422 regardless, so offering one too many costs a server error the user
|
|
100
|
+
* already gets today, where hiding one too few makes a legitimate add-on
|
|
101
|
+
* unreachable with nothing on screen to explain why.
|
|
102
|
+
*
|
|
103
|
+
* An allow-list that arrived *empty* is not unknown — a restricted item is
|
|
104
|
+
* saved with `applicable_items: []` when nothing was picked — so that narrows
|
|
105
|
+
* to nothing, as the server does.
|
|
106
|
+
*
|
|
107
|
+
* Lives here rather than in a screen so the create/edit form and the detail
|
|
108
|
+
* page's inline edit narrow their pickers by the same rule.
|
|
109
|
+
*/
|
|
110
|
+
export declare const getInvoicingItemsAllowedForPlan: (products: InvoicingProduct[], plan: InvoicingProduct | undefined) => InvoicingProduct[];
|
|
111
|
+
/**
|
|
112
|
+
* One entry in a subscription-form picker, ready for the screen to render.
|
|
113
|
+
*
|
|
114
|
+
* `label` and `value` are the whole contract for a coupon or a customer. A
|
|
115
|
+
* catalog item adds the pieces its subtitle is built from — `productCode`,
|
|
116
|
+
* `price`, `billingPeriodUnit` — rather than a finished string, because
|
|
117
|
+
* formatting money is the UI's job: CES holds {@link Amount} as data and has
|
|
118
|
+
* no currency formatter. `subtitle` is the escape hatch for a caller that
|
|
119
|
+
* already has the line it wants.
|
|
120
|
+
*
|
|
121
|
+
* A plan carries the extra fields the form prefills from it: its paid-cycle
|
|
122
|
+
* limit, its cadence, and its trial length.
|
|
123
|
+
*/
|
|
124
|
+
export interface InvoicingSubscriptionOption {
|
|
125
|
+
label: string;
|
|
126
|
+
value: string;
|
|
127
|
+
billingCycles?: number;
|
|
128
|
+
billingPeriod?: number;
|
|
129
|
+
billingPeriodUnit?: string;
|
|
130
|
+
price?: Amount;
|
|
131
|
+
productCode?: string;
|
|
132
|
+
subtitle?: string;
|
|
133
|
+
trialPeriod?: number;
|
|
134
|
+
trialPeriodUnit?: string;
|
|
135
|
+
}
|
|
69
136
|
export declare const getInvoicingSubscriptionFormView: (state: RootState, invoicingSubscriptionID?: ID) => InvoicingSubscriptionFormView;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getInvoicingSubscriptionFormView = exports.getEditInvoicingSubscriptionDetailViewState = void 0;
|
|
3
|
+
exports.getInvoicingSubscriptionFormView = exports.getInvoicingItemsAllowedForPlan = exports.getEditInvoicingSubscriptionDetailViewState = void 0;
|
|
4
4
|
const reduceFetchState_1 = require("../../../commonStateTypes/reduceFetchState");
|
|
5
|
+
const addressSelector_1 = require("../../../entity/address/addressSelector");
|
|
5
6
|
const invoicingSubscriptionSelector_1 = require("../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionSelector");
|
|
6
7
|
const addressViewSelector_1 = require("../../addressView/addressViewSelector");
|
|
7
8
|
const couponViewSelector_1 = require("../couponView/couponViewSelector");
|
|
8
9
|
const invoicingCatalogListViewSelector_1 = require("../invoicingCatalogListView/invoicingCatalogListViewSelector");
|
|
9
10
|
const invoicingConfigViewSelector_1 = require("../invoicingConfigView/invoicingConfigViewSelector");
|
|
10
11
|
const invoicingCustomerListViewSelector_1 = require("../invoicingCustomerListView/invoicingCustomerListViewSelector");
|
|
12
|
+
const invoicingFormDraft_1 = require("../invoicingFormDraft");
|
|
11
13
|
const invoicingSubscriptionFormConfig_1 = require("./invoicingSubscriptionFormConfig");
|
|
12
14
|
const invoicingSubscriptionFormConfig_2 = require("./invoicingSubscriptionFormConfig");
|
|
13
15
|
const getEditInvoicingSubscriptionDetailViewState = (state, invoicingSubscriptionID) => {
|
|
@@ -27,6 +29,130 @@ const getEditInvoicingSubscriptionDetailViewState = (state, invoicingSubscriptio
|
|
|
27
29
|
};
|
|
28
30
|
};
|
|
29
31
|
exports.getEditInvoicingSubscriptionDetailViewState = getEditInvoicingSubscriptionDetailViewState;
|
|
32
|
+
/**
|
|
33
|
+
* Whether the shipping address entered on the Address screen is a change the
|
|
34
|
+
* subscription has not saved. Presence alone cannot say so: the detail page seeds
|
|
35
|
+
* the address store with the saved address on load so the Address screen opens
|
|
36
|
+
* prefilled. Only a pending address that differs from the saved one — or one
|
|
37
|
+
* where nothing is saved yet — is an unsaved change. Compared on what the user
|
|
38
|
+
* enters; a saved address's coordinates and timestamps are left out.
|
|
39
|
+
*/
|
|
40
|
+
const isShippingAddressUnsaved = (state, id, savedShippingAddressId) => {
|
|
41
|
+
// The slot is keyed by address type alone; only a draft this subscription owns counts.
|
|
42
|
+
if (id == null ||
|
|
43
|
+
state.editInvoicingSubscriptionDetailViewState.shippingAddressOwnerId !== id) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
const pending = state.addressViewState.newAddressState?.[invoicingSubscriptionFormConfig_2.INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE]?.addressToCreate;
|
|
47
|
+
if (pending == null) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
const saved = savedShippingAddressId != null
|
|
51
|
+
? (0, addressSelector_1.getAddressByAddressId)(state.addressState, savedShippingAddressId)
|
|
52
|
+
: undefined;
|
|
53
|
+
if (saved == null) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
return !(pending.street.join('\u0000') === saved.street.join('\u0000') &&
|
|
57
|
+
pending.city === saved.city &&
|
|
58
|
+
pending.state === saved.state &&
|
|
59
|
+
pending.postalCode === saved.postalCode &&
|
|
60
|
+
pending.country === saved.country &&
|
|
61
|
+
(pending.countryCode ?? '') === (saved.countryCode ?? ''));
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* The add-ons / one-time charges a plan actually accepts.
|
|
65
|
+
*
|
|
66
|
+
* A catalog item is either `restricted` — it names the item ids it may be
|
|
67
|
+
* subscribed alongside in `applicableItems` — or unrestricted, in which case
|
|
68
|
+
* every item is fair game. Matching is on `itemID` (the catalog item the price
|
|
69
|
+
* row was flattened from), not the price code, because applicability is
|
|
70
|
+
* declared item-to-item.
|
|
71
|
+
*
|
|
72
|
+
* Fails open where the rule is unknown: no plan selected yet, a plan that is
|
|
73
|
+
* not `restricted`, or a `restricted` plan whose allow-list never came down all
|
|
74
|
+
* return the full list. The create/update endpoint rejects a disallowed item
|
|
75
|
+
* with a 422 regardless, so offering one too many costs a server error the user
|
|
76
|
+
* already gets today, where hiding one too few makes a legitimate add-on
|
|
77
|
+
* unreachable with nothing on screen to explain why.
|
|
78
|
+
*
|
|
79
|
+
* An allow-list that arrived *empty* is not unknown — a restricted item is
|
|
80
|
+
* saved with `applicable_items: []` when nothing was picked — so that narrows
|
|
81
|
+
* to nothing, as the server does.
|
|
82
|
+
*
|
|
83
|
+
* Lives here rather than in a screen so the create/edit form and the detail
|
|
84
|
+
* page's inline edit narrow their pickers by the same rule.
|
|
85
|
+
*/
|
|
86
|
+
const getInvoicingItemsAllowedForPlan = (products, plan) => {
|
|
87
|
+
const allowedItemIDs = plan?.applicableItems;
|
|
88
|
+
if (plan?.itemApplicability !== 'restricted' || allowedItemIDs == null) {
|
|
89
|
+
return products;
|
|
90
|
+
}
|
|
91
|
+
return products.filter((product) => product.itemID != null && allowedItemIDs.includes(product.itemID));
|
|
92
|
+
};
|
|
93
|
+
exports.getInvoicingItemsAllowedForPlan = getInvoicingItemsAllowedForPlan;
|
|
94
|
+
/**
|
|
95
|
+
* A price row can only be subscribed by its price code, so one without a code
|
|
96
|
+
* is not an option the form can offer.
|
|
97
|
+
*/
|
|
98
|
+
const hasInvoicingPriceCode = (product) => product.priceCode != null && product.priceCode.trim() !== '';
|
|
99
|
+
/**
|
|
100
|
+
* `displayPrice` is the service-computed single-unit amount. Tiered, volume and
|
|
101
|
+
* stairstep price points store `price` as `0` because the money lives in their
|
|
102
|
+
* tiers, so `price` is only a fallback for responses predating `displayPrice`.
|
|
103
|
+
*/
|
|
104
|
+
const invoicingUnitPrice = (product) => product.displayPrice ?? product.price;
|
|
105
|
+
const toInvoicingPlanOption = (plan) => ({
|
|
106
|
+
billingCycles: plan.billingCycles,
|
|
107
|
+
// The price point's own cadence: the backend derives billing period from the
|
|
108
|
+
// price point and rejects a subscription that claims a different one.
|
|
109
|
+
billingPeriod: plan.period,
|
|
110
|
+
billingPeriodUnit: plan.periodUnit,
|
|
111
|
+
label: plan.name ?? plan.id,
|
|
112
|
+
price: invoicingUnitPrice(plan),
|
|
113
|
+
productCode: plan.productCode,
|
|
114
|
+
trialPeriod: plan.trialPeriod,
|
|
115
|
+
trialPeriodUnit: plan.trialPeriodUnit,
|
|
116
|
+
value: plan.priceCode,
|
|
117
|
+
});
|
|
118
|
+
const toInvoicingCatalogItemOption = (product) => ({
|
|
119
|
+
// A one-time charge has no cadence, so its price is quoted flat rather than
|
|
120
|
+
// per period.
|
|
121
|
+
billingPeriodUnit: product.itemType === 'charge' ? undefined : product.periodUnit,
|
|
122
|
+
label: product.name ?? product.id,
|
|
123
|
+
price: invoicingUnitPrice(product),
|
|
124
|
+
productCode: product.productCode,
|
|
125
|
+
value: product.priceCode,
|
|
126
|
+
});
|
|
127
|
+
const toInvoicingCouponOption = (coupon) => ({
|
|
128
|
+
label: coupon.name ?? coupon.couponCode ?? coupon.id,
|
|
129
|
+
// Create/apply/remove coupon APIs resolve by coupon_code.
|
|
130
|
+
value: coupon.couponCode ?? coupon.id,
|
|
131
|
+
});
|
|
132
|
+
/**
|
|
133
|
+
* Company first, then the person's name, then the email — whichever the
|
|
134
|
+
* customer actually has. The id is the last resort so a record with no
|
|
135
|
+
* identifying field at all is still selectable rather than a blank row.
|
|
136
|
+
*/
|
|
137
|
+
const invoicingCustomerDisplayName = (customer) => {
|
|
138
|
+
const fullName = [customer.firstName, customer.lastName]
|
|
139
|
+
.filter((part) => part != null && part.trim() !== '')
|
|
140
|
+
.join(' ')
|
|
141
|
+
.trim();
|
|
142
|
+
const company = customer.company?.trim() ?? '';
|
|
143
|
+
const email = customer.email?.trim() ?? '';
|
|
144
|
+
return company !== ''
|
|
145
|
+
? company
|
|
146
|
+
: fullName !== ''
|
|
147
|
+
? fullName
|
|
148
|
+
: email !== ''
|
|
149
|
+
? email
|
|
150
|
+
: customer.id;
|
|
151
|
+
};
|
|
152
|
+
const toInvoicingCustomerOption = (customer) => ({
|
|
153
|
+
label: invoicingCustomerDisplayName(customer),
|
|
154
|
+
value: customer.id,
|
|
155
|
+
});
|
|
30
156
|
const getInvoicingSubscriptionFormView = (state, invoicingSubscriptionID) => {
|
|
31
157
|
const { editDraftById, error, fetchState, newSubscriptionDraft, savedSubscriptionId, } = state.editInvoicingSubscriptionDetailViewState;
|
|
32
158
|
const mode = invoicingSubscriptionID != null ? 'edit' : 'create';
|
|
@@ -37,8 +163,7 @@ const getInvoicingSubscriptionFormView = (state, invoicingSubscriptionID) => {
|
|
|
37
163
|
// `seedInvoicingSubscriptionFormDraftEpic` when the detail load lands. Until
|
|
38
164
|
// then the page is showing its skeleton.
|
|
39
165
|
const localData = invoicingSubscriptionID != null
|
|
40
|
-
? (editDraftById
|
|
41
|
-
invoicingSubscriptionFormConfig_1.initialInvoicingSubscriptionFormLocalData)
|
|
166
|
+
? (0, invoicingFormDraft_1.getInvoicingFormDraftLocalData)(editDraftById, invoicingSubscriptionID, invoicingSubscriptionFormConfig_1.initialInvoicingSubscriptionFormLocalData)
|
|
42
167
|
: newSubscriptionDraft;
|
|
43
168
|
// Shipping address is captured via the shared Address screen and seeded there
|
|
44
169
|
// (looked up in the shared address store by `shippingAddressId`) on detail
|
|
@@ -47,9 +172,17 @@ const getInvoicingSubscriptionFormView = (state, invoicingSubscriptionID) => {
|
|
|
47
172
|
const shippingAddressLabel = newAddress?.addressToCreate != null
|
|
48
173
|
? (0, addressViewSelector_1.getFormattedAddress)(newAddress.addressToCreate)
|
|
49
174
|
: undefined;
|
|
175
|
+
const hasUnsavedShippingAddress = isShippingAddressUnsaved(state, invoicingSubscriptionID, subscription?.shippingAddressId);
|
|
50
176
|
const catalogListView = (0, invoicingCatalogListViewSelector_1.getInvoicingCatalogListView)(state);
|
|
51
|
-
const planPrices = (0, invoicingCatalogListViewSelector_1.getInvoicingCatalogPrices)(catalogListView.plans);
|
|
52
|
-
|
|
177
|
+
const planPrices = (0, invoicingCatalogListViewSelector_1.getInvoicingCatalogPrices)(catalogListView.plans).filter(hasInvoicingPriceCode);
|
|
178
|
+
// A restricted plan names the catalog items it may be sold with, so the
|
|
179
|
+
// pickers offer only those: subscription create rejects the rest with a 422,
|
|
180
|
+
// and an option that can only fail is not a choice. The applicability rides
|
|
181
|
+
// on the price rows already in the store, so this is a join, not a refetch.
|
|
182
|
+
const allowedCatalogPrices = (0, exports.getInvoicingItemsAllowedForPlan)((0, invoicingCatalogListViewSelector_1.getInvoicingCatalogPrices)(catalogListView.products), planPrices.find((plan) => plan.priceCode === localData.planPriceCode)).filter(hasInvoicingPriceCode);
|
|
183
|
+
const catalogItemOptionsOfType = (itemType) => allowedCatalogPrices
|
|
184
|
+
.filter((product) => product.itemType === itemType)
|
|
185
|
+
.map(toInvoicingCatalogItemOption);
|
|
53
186
|
// In create mode there is nothing to load, so the record state only applies
|
|
54
187
|
// when editing an existing subscription.
|
|
55
188
|
const recordState = invoicingSubscriptionID != null
|
|
@@ -69,15 +202,18 @@ const getInvoicingSubscriptionFormView = (state, invoicingSubscriptionID) => {
|
|
|
69
202
|
subscriptionLifecycleActionOptions: configState.subscriptionLifecycleActionOptions,
|
|
70
203
|
subscriptionMetadataEditAllowedFromStatuses: configState.subscriptionMetadataEditAllowedFromStatuses,
|
|
71
204
|
recordState,
|
|
205
|
+
isFormLoading: (0, invoicingFormDraft_1.isInvoicingFormDraftPending)(editDraftById, invoicingSubscriptionID),
|
|
72
206
|
fieldHelp: (0, invoicingConfigViewSelector_1.invoicingFieldHelpForGroup)(state, 'subscription'),
|
|
73
|
-
|
|
74
|
-
|
|
207
|
+
addons: catalogItemOptionsOfType('addon'),
|
|
208
|
+
charges: catalogItemOptionsOfType('charge'),
|
|
209
|
+
coupons: (0, couponViewSelector_1.getInvoicingCouponListItems)(state).map(toInvoicingCouponOption),
|
|
210
|
+
customers: (0, invoicingCustomerListViewSelector_1.getInvoicingCustomerListView)(state).customers.map(toInvoicingCustomerOption),
|
|
75
211
|
localData,
|
|
76
212
|
mode,
|
|
77
|
-
plans: planPrices,
|
|
78
|
-
products: addonAndChargePrices,
|
|
213
|
+
plans: planPrices.map(toInvoicingPlanOption),
|
|
79
214
|
savedSubscriptionId,
|
|
80
215
|
shippingAddressLabel,
|
|
216
|
+
hasUnsavedShippingAddress,
|
|
81
217
|
subscription,
|
|
82
218
|
fetchState,
|
|
83
219
|
error,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Amount } from '../../../commonStateTypes/amount';
|
|
2
2
|
import { FetchStateAndError, FetchedState, ID } from '../../../commonStateTypes/common';
|
|
3
|
+
import { InvoicingFormDraftById } from '../invoicingFormDraft';
|
|
3
4
|
/**
|
|
4
5
|
* Draft form state for the create/edit subscription form. Held in CES so the
|
|
5
6
|
* form flows its data from here (mirrors the customer form / bill-pay pattern).
|
|
@@ -41,9 +42,15 @@ export interface InvoicingSubscriptionFormLocalData {
|
|
|
41
42
|
export interface EditInvoicingSubscriptionDetailViewState extends FetchedState {
|
|
42
43
|
/** Lifecycle action fetch state per subscription id. */
|
|
43
44
|
actionStateById: Record<ID, FetchStateAndError>;
|
|
44
|
-
editDraftById:
|
|
45
|
+
editDraftById: InvoicingFormDraftById<InvoicingSubscriptionFormLocalData>;
|
|
45
46
|
newSubscriptionDraft: InvoicingSubscriptionFormLocalData;
|
|
46
47
|
/** Detail-load state per subscription id. */
|
|
47
48
|
recordStateById: Record<ID, FetchStateAndError>;
|
|
48
49
|
savedSubscriptionId?: ID;
|
|
50
|
+
/**
|
|
51
|
+
* The subscription whose shipping address currently occupies the shared address
|
|
52
|
+
* store slot. That slot is keyed by address type alone, so without this a
|
|
53
|
+
* draft seeded or edited for one subscription would pass for the next one's.
|
|
54
|
+
*/
|
|
55
|
+
shippingAddressOwnerId?: ID;
|
|
49
56
|
}
|
|
@@ -19,8 +19,11 @@ const fetchInvoicingSubscriptionFormPageEpic = (actions$) => actions$.pipe((0, o
|
|
|
19
19
|
const { subscriptionId } = action.payload;
|
|
20
20
|
const pageActions = [
|
|
21
21
|
(0, invoicingCustomerListViewReducer_1.fetchInvoicingCustomerList)({ filters: {}, keepExistingListItems: false }),
|
|
22
|
+
// Plans only: the form's plan picker is the one consumer, and an
|
|
23
|
+
// unfiltered list would replace the store's plans with every catalog
|
|
24
|
+
// item.
|
|
22
25
|
(0, invoicingCatalogListViewReducer_1.fetchInvoicingCatalogPlanList)({
|
|
23
|
-
filters: {},
|
|
26
|
+
filters: { type: 'plan' },
|
|
24
27
|
keepExistingListItems: false,
|
|
25
28
|
}),
|
|
26
29
|
(0, couponViewReducer_1.fetchInvoicingCouponList)({ filters: {}, keepExistingListItems: false }),
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
import { RootState } from '../../../rootStateTypes';
|
|
4
|
-
import { newAddressInLocalStore } from '../../addressView/addressViewReducer';
|
|
5
|
-
import { updateInvoicingSubscriptionDetail } from './editInvoicingSubscriptionDetailViewReducer';
|
|
6
|
-
|
|
7
|
-
export type ActionType = ReturnType<typeof initializeInvoicingSubscriptionAddress> | ReturnType<typeof updateInvoicingSubscriptionDetail> | ReturnType<typeof newAddressInLocalStore>;
|
|
4
|
+
import { newAddressInLocalStore, removeNewAddressDataInLocalStore } from '../../addressView/addressViewReducer';
|
|
5
|
+
import { claimInvoicingSubscriptionShippingAddress, fetchInvoicingSubscriptionDetail, fetchInvoicingSubscriptionDetailPage, initializeInvoicingSubscriptionAddress, updateInvoicingSubscriptionDetail } from './editInvoicingSubscriptionDetailViewReducer';
|
|
6
|
+
export type ActionType = ReturnType<typeof initializeInvoicingSubscriptionAddress> | ReturnType<typeof updateInvoicingSubscriptionDetail> | ReturnType<typeof fetchInvoicingSubscriptionDetailPage> | ReturnType<typeof fetchInvoicingSubscriptionDetail> | ReturnType<typeof claimInvoicingSubscriptionShippingAddress> | ReturnType<typeof newAddressInLocalStore> | ReturnType<typeof removeNewAddressDataInLocalStore>;
|
|
8
7
|
/**
|
|
9
|
-
* Seed the shared Address screen with
|
|
10
|
-
*
|
|
11
|
-
* the
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
8
|
+
* Seed the shared Address screen with the subscription's saved shipping address, and
|
|
9
|
+
* record that the slot is this subscription's. Runs when a detail request is issued
|
|
10
|
+
* (every path that loads a record issues one — the detail page when not cached,
|
|
11
|
+
* the create/edit form always), when the page opens, when the detail load
|
|
12
|
+
* lands, and on an explicit initialize trigger.
|
|
13
|
+
*
|
|
14
|
+
* The address store slot is keyed by address type alone, so it can still hold
|
|
15
|
+
* another subscription's draft. Only a draft this subscription owns is left alone —
|
|
16
|
+
* that is what lets an address the user just entered survive a trip to the
|
|
17
|
+
* Address screen. Anything else is replaced by this subscription's saved address,
|
|
18
|
+
* or cleared when it has none. Opening the page counts as a trigger because a
|
|
19
|
+
* record already loaded this session issues no detail request at all.
|
|
16
20
|
*/
|
|
17
21
|
export declare const initializeInvoicingSubscriptionAddressEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>) => Observable<ActionType>;
|
|
@@ -7,34 +7,60 @@ const addressSelector_1 = require("../../../entity/address/addressSelector");
|
|
|
7
7
|
const invoicingSubscriptionSelector_1 = require("../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionSelector");
|
|
8
8
|
const addressViewReducer_1 = require("../../addressView/addressViewReducer");
|
|
9
9
|
const editInvoicingSubscriptionDetailViewReducer_1 = require("./editInvoicingSubscriptionDetailViewReducer");
|
|
10
|
-
const editInvoicingSubscriptionDetailViewReducer_2 = require("./editInvoicingSubscriptionDetailViewReducer");
|
|
11
10
|
const invoicingSubscriptionFormConfig_1 = require("./invoicingSubscriptionFormConfig");
|
|
12
11
|
/**
|
|
13
|
-
* Seed the shared Address screen with
|
|
14
|
-
*
|
|
15
|
-
* the
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
12
|
+
* Seed the shared Address screen with the subscription's saved shipping address, and
|
|
13
|
+
* record that the slot is this subscription's. Runs when a detail request is issued
|
|
14
|
+
* (every path that loads a record issues one — the detail page when not cached,
|
|
15
|
+
* the create/edit form always), when the page opens, when the detail load
|
|
16
|
+
* lands, and on an explicit initialize trigger.
|
|
17
|
+
*
|
|
18
|
+
* The address store slot is keyed by address type alone, so it can still hold
|
|
19
|
+
* another subscription's draft. Only a draft this subscription owns is left alone —
|
|
20
|
+
* that is what lets an address the user just entered survive a trip to the
|
|
21
|
+
* Address screen. Anything else is replaced by this subscription's saved address,
|
|
22
|
+
* or cleared when it has none. Opening the page counts as a trigger because a
|
|
23
|
+
* record already loaded this session issues no detail request at all.
|
|
20
24
|
*/
|
|
21
|
-
const initializeInvoicingSubscriptionAddressEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)((action) =>
|
|
22
|
-
editInvoicingSubscriptionDetailViewReducer_1.updateInvoicingSubscriptionDetail.match(action)
|
|
25
|
+
const initializeInvoicingSubscriptionAddressEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)((action) => editInvoicingSubscriptionDetailViewReducer_1.initializeInvoicingSubscriptionAddress.match(action) ||
|
|
26
|
+
editInvoicingSubscriptionDetailViewReducer_1.updateInvoicingSubscriptionDetail.match(action) ||
|
|
27
|
+
editInvoicingSubscriptionDetailViewReducer_1.fetchInvoicingSubscriptionDetailPage.match(action) ||
|
|
28
|
+
editInvoicingSubscriptionDetailViewReducer_1.fetchInvoicingSubscriptionDetail.match(action)), (0, operators_1.mergeMap)((action) => {
|
|
23
29
|
const { id } = action.payload;
|
|
30
|
+
if (id == null) {
|
|
31
|
+
return rxjs_1.EMPTY;
|
|
32
|
+
}
|
|
24
33
|
const rootState = state$.value;
|
|
25
|
-
const
|
|
26
|
-
|
|
34
|
+
const pending = rootState.addressViewState.newAddressState?.[invoicingSubscriptionFormConfig_1.INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE]?.addressToCreate;
|
|
35
|
+
const ownerId = rootState.editInvoicingSubscriptionDetailViewState
|
|
36
|
+
.shippingAddressOwnerId;
|
|
37
|
+
// A detail response speaks for the record it loaded, which may no longer
|
|
38
|
+
// be the one on screen: its request keeps running when the user moves on
|
|
39
|
+
// to a cached record, which issues no request of its own to cancel it.
|
|
40
|
+
// Only the page-open and explicit triggers define the current record.
|
|
41
|
+
if (editInvoicingSubscriptionDetailViewReducer_1.updateInvoicingSubscriptionDetail.match(action) &&
|
|
42
|
+
ownerId != null &&
|
|
43
|
+
ownerId !== id) {
|
|
44
|
+
return rxjs_1.EMPTY;
|
|
45
|
+
}
|
|
46
|
+
if (pending != null && ownerId === id) {
|
|
27
47
|
return rxjs_1.EMPTY;
|
|
28
48
|
}
|
|
29
49
|
const subscription = (0, invoicingSubscriptionSelector_1.getInvoicingSubscriptionById)(rootState.invoicingSubscriptionState, id);
|
|
30
50
|
const address = subscription?.shippingAddressId != null
|
|
31
51
|
? (0, addressSelector_1.getAddressByAddressId)(rootState.addressState, subscription.shippingAddressId)
|
|
32
52
|
: undefined;
|
|
33
|
-
|
|
34
|
-
|
|
53
|
+
const actions = [];
|
|
54
|
+
if (address != null) {
|
|
55
|
+
actions.push((0, addressViewReducer_1.newAddressInLocalStore)({
|
|
35
56
|
addressType: invoicingSubscriptionFormConfig_1.INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE,
|
|
36
57
|
addressToCreate: address,
|
|
37
|
-
}))
|
|
38
|
-
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
else if (pending != null) {
|
|
61
|
+
actions.push((0, addressViewReducer_1.removeNewAddressDataInLocalStore)(invoicingSubscriptionFormConfig_1.INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE));
|
|
62
|
+
}
|
|
63
|
+
actions.push((0, editInvoicingSubscriptionDetailViewReducer_1.claimInvoicingSubscriptionShippingAddress)({ id }));
|
|
64
|
+
return (0, rxjs_1.from)(actions);
|
|
39
65
|
}));
|
|
40
66
|
exports.initializeInvoicingSubscriptionAddressEpic = initializeInvoicingSubscriptionAddressEpic;
|
package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js
CHANGED
|
@@ -20,7 +20,7 @@ const saveInvoicingSubscriptionEpic = (actions$, state$, zeniAPI) => actions$.pi
|
|
|
20
20
|
const rootState = state$.value;
|
|
21
21
|
const viewState = rootState.editInvoicingSubscriptionDetailViewState;
|
|
22
22
|
const localData = (id != null
|
|
23
|
-
? viewState.editDraftById[id]
|
|
23
|
+
? viewState.editDraftById[id]?.localData
|
|
24
24
|
: viewState.newSubscriptionDraft) ?? viewState.newSubscriptionDraft;
|
|
25
25
|
// Shipping address captured via the shared Address screen is sent as an
|
|
26
26
|
// object in the payload (same pattern as the customer save flow).
|
|
@@ -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 { seedInvoicingSubscriptionFormDraft, updateInvoicingSubscriptionDetail } from './editInvoicingSubscriptionDetailViewReducer';
|
|
5
|
-
export type ActionType = ReturnType<typeof updateInvoicingSubscriptionDetail> | ReturnType<typeof seedInvoicingSubscriptionFormDraft>;
|
|
4
|
+
import { fetchInvoicingSubscriptionFormPage, seedInvoicingSubscriptionFormDraft, updateInvoicingSubscriptionDetail } from './editInvoicingSubscriptionDetailViewReducer';
|
|
5
|
+
export type ActionType = ReturnType<typeof fetchInvoicingSubscriptionFormPage> | ReturnType<typeof updateInvoicingSubscriptionDetail> | ReturnType<typeof seedInvoicingSubscriptionFormDraft>;
|
|
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 seedInvoicingSubscriptionFormDraftEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>) => Observable<ActionType>;
|