@zeniai/client-epic-state 5.2.53 → 5.2.54

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.
@@ -1,8 +1,17 @@
1
1
  import { Amount } from '../../../commonStateTypes/amount';
2
2
  import { ID } from '../../../commonStateTypes/common';
3
+ import { InvoicingProduct } from '../product/productState';
3
4
  import { InvoicingPlan, InvoicingPlanState } from './planState';
4
5
  export declare function getInvoicingPlansByIds(planState: InvoicingPlanState, ids: ID[]): InvoicingPlan[];
5
6
  export declare function getInvoicingPlanById(planState: InvoicingPlanState, id: ID): InvoicingPlan | undefined;
7
+ /**
8
+ * The amount to show for one price point: what the service computed for a
9
+ * single unit. `price` is only a fallback for responses predating
10
+ * `display_price` — reading it first would show `0` for every tiered, volume
11
+ * and stairstep model, whose configured price is legitimately zero because the
12
+ * money lives in its tiers.
13
+ */
14
+ export declare const invoicingPricePointDisplayAmount: (pricePoint: InvoicingProduct) => Amount | undefined;
6
15
  /**
7
16
  * The lowest amount a catalog item can be bought at: the smallest single-unit
8
17
  * price across its active price points.
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getLowestInvoicingPlanPricePointAmount = void 0;
6
+ exports.getLowestInvoicingPlanPricePointAmount = exports.invoicingPricePointDisplayAmount = void 0;
7
7
  exports.getInvoicingPlansByIds = getInvoicingPlansByIds;
8
8
  exports.getInvoicingPlanById = getInvoicingPlanById;
9
9
  const get_1 = __importDefault(require("lodash/get"));
@@ -29,6 +29,7 @@ const isActiveInvoicingPricePoint = (pricePoint) => pricePoint.status == null ||
29
29
  * money lives in its tiers.
30
30
  */
31
31
  const invoicingPricePointDisplayAmount = (pricePoint) => pricePoint.displayPrice ?? pricePoint.price;
32
+ exports.invoicingPricePointDisplayAmount = invoicingPricePointDisplayAmount;
32
33
  /**
33
34
  * The lowest amount a catalog item can be bought at: the smallest single-unit
34
35
  * price across its active price points.
@@ -41,7 +42,7 @@ const invoicingPricePointDisplayAmount = (pricePoint) => pricePoint.displayPrice
41
42
  const getLowestInvoicingPlanPricePointAmount = (plan) => {
42
43
  const amounts = (plan?.subFamilies ?? [])
43
44
  .filter(isActiveInvoicingPricePoint)
44
- .map(invoicingPricePointDisplayAmount)
45
+ .map(exports.invoicingPricePointDisplayAmount)
45
46
  .filter((amount) => amount != null);
46
47
  if (amounts.length === 0) {
47
48
  return undefined;
@@ -60,7 +60,7 @@ export interface InvoicingProductPayload {
60
60
  period_unit?: string;
61
61
  price?: number;
62
62
  price_code?: string;
63
- pricing_model?: string;
63
+ pricing_model?: string | null;
64
64
  product_code?: string;
65
65
  proration_type?: string;
66
66
  shipping_period?: number;
@@ -71,7 +71,7 @@ const mapInvoicingProductPayloadToState = (payload) => {
71
71
  ? (0, amount_1.toAmount)(payload.price, currencyCode, currencySymbol)
72
72
  : undefined,
73
73
  priceCode: payload.price_code,
74
- pricingModel: payload.pricing_model,
74
+ pricingModel: payload.pricing_model ?? undefined,
75
75
  productCode: payload.product_code,
76
76
  prorationType: payload.proration_type,
77
77
  shippingPeriod: payload.shipping_period,
@@ -16,6 +16,11 @@ export interface InvoicingAccountingDetail {
16
16
  accountingCode?: string;
17
17
  sku?: string;
18
18
  }
19
+ /**
20
+ * Pricing models the catalog supports. The service has no enum for them yet,
21
+ * so this union is the single place they are named on the client.
22
+ */
23
+ export type InvoicingCatalogPricingModel = 'flat_fee' | 'per_unit' | 'tiered' | 'volume' | 'stairstep';
19
24
  export interface InvoicingProduct {
20
25
  id: ID;
21
26
  accountingDetail?: InvoicingAccountingDetail;
@@ -50,6 +55,11 @@ export interface InvoicingProduct {
50
55
  periodUnit?: string;
51
56
  price?: Amount;
52
57
  priceCode?: string;
58
+ /**
59
+ * One of [[InvoicingCatalogPricingModel]] for records written by this app;
60
+ * kept `string` because the service has no enum yet and imports may carry
61
+ * other values. Absent means `per_unit` (the service default).
62
+ */
53
63
  pricingModel?: string;
54
64
  productCode?: string;
55
65
  prorationType?: string;
@@ -20,7 +20,7 @@ const isActiveInvoicingPricePoint = (pricePoint) => pricePoint.status == null ||
20
20
  * and stairstep model, whose configured price is legitimately zero because the
21
21
  * money lives in its tiers.
22
22
  */
23
- const invoicingPricePointDisplayAmount = (pricePoint) => pricePoint.displayPrice ?? pricePoint.price;
23
+ export const invoicingPricePointDisplayAmount = (pricePoint) => pricePoint.displayPrice ?? pricePoint.price;
24
24
  /**
25
25
  * The lowest amount a catalog item can be bought at: the smallest single-unit
26
26
  * price across its active price points.
@@ -67,7 +67,7 @@ export const mapInvoicingProductPayloadToState = (payload) => {
67
67
  ? toAmount(payload.price, currencyCode, currencySymbol)
68
68
  : undefined,
69
69
  priceCode: payload.price_code,
70
- pricingModel: payload.pricing_model,
70
+ pricingModel: payload.pricing_model ?? undefined,
71
71
  productCode: payload.product_code,
72
72
  prorationType: payload.proration_type,
73
73
  shippingPeriod: payload.shipping_period,
@@ -1,8 +1,35 @@
1
1
  import { getAddressByAddressId } from '../../../entity/address/addressSelector';
2
+ import { invoicingPricePointDisplayAmount } from '../../../entity/invoicing/plan/planSelector';
2
3
  import { getInvoicingCatalogListView, getInvoicingCatalogPrices, } from '../invoicingCatalogListView/invoicingCatalogListViewSelector';
3
4
  import { invoicingFieldHelpForGroup } from '../invoicingConfigView/invoicingConfigViewSelector';
4
5
  import { getInvoicingCustomerListView } from '../invoicingCustomerListView/invoicingCustomerListViewSelector';
5
6
  import { getInvoicingSettings } from '../settingsView/settingsViewSelector';
7
+ /**
8
+ * Pricing models whose single-unit amount is a true per-unit rate — the only
9
+ * ones a Create Invoice line may be prefilled from. Typed against the entity
10
+ * union so a misspelt member fails to compile; a model added to the union
11
+ * still has to be classified here by hand (it is left out, so it fails closed:
12
+ * no prefill). The complement is `isTieredCatalogPricingModel`.
13
+ */
14
+ const PER_UNIT_RATE_PRICING_MODELS = [
15
+ 'per_unit',
16
+ 'flat_fee',
17
+ ];
18
+ /**
19
+ * Whether a price point's single-unit amount is a per-unit rate. A missing
20
+ * model means per-unit: the service defaults `pricing_model` to `per_unit`
21
+ * and older records may omit it.
22
+ */
23
+ const hasPerUnitRate = (pricingModel) => pricingModel == null ||
24
+ pricingModel === '' ||
25
+ PER_UNIT_RATE_PRICING_MODELS.some((model) => model === pricingModel);
26
+ /**
27
+ * The amount to prefill on a Create Invoice line for a price point, or
28
+ * `undefined` when there is no safe per-unit rate to prefill.
29
+ */
30
+ const planNamePrefillPrice = (pricePoint) => hasPerUnitRate(pricePoint.pricingModel)
31
+ ? invoicingPricePointDisplayAmount(pricePoint)?.amount
32
+ : undefined;
6
33
  /**
7
34
  * Display name for a customer option: company, else the full name, else the
8
35
  * email, else the raw id.
@@ -47,7 +74,7 @@ export const getCreateInvoiceFormView = (state) => {
47
74
  .filter((subFamily) => (subFamily.name ?? '') !== '')
48
75
  .map((subFamily) => ({
49
76
  planName: plan.name ?? '',
50
- price: subFamily.price?.amount,
77
+ price: planNamePrefillPrice(subFamily),
51
78
  subFamilyName: subFamily.name ?? '',
52
79
  }))),
53
80
  products: getInvoicingCatalogPrices(catalogListView.products),
@@ -3,13 +3,7 @@
3
3
  * for pricing model, tier type, proration or applicability yet, so these stay
4
4
  * here until it does. Everything else on this form comes from `/1.0/config`.
5
5
  */
6
- export const INVOICING_CATALOG_PRICING_MODEL_VALUES = [
7
- 'flat_fee',
8
- 'per_unit',
9
- 'tiered',
10
- 'volume',
11
- 'stairstep',
12
- ];
6
+ export const INVOICING_CATALOG_PRICING_MODEL_VALUES = ['flat_fee', 'per_unit', 'tiered', 'volume', 'stairstep'];
13
7
  export const INVOICING_CATALOG_TIER_TYPE_VALUES = [
14
8
  'per_unit',
15
9
  'flat_fee',
@@ -9,8 +9,13 @@ import { InvoicingCreateInvoiceFormLocalData } from './createInvoiceState';
9
9
  * One catalog plan price, split into its two naming parts so consumers can
10
10
  * compose the label themselves (the plan family name and the price point/price
11
11
  * name are separate columns in the catalog). `price` is the price point's
12
- * catalog price in whole USD (never minor units), absent when the catalog
13
- * carries no price for it.
12
+ * per-unit amount in whole USD (never minor units): the service-computed
13
+ * single-unit display price, falling back to the configured price for
14
+ * responses predating it. It is absent when the catalog carries no price for
15
+ * it, and deliberately absent for tiered, volume and stairstep price points —
16
+ * their single-unit figure is a step/band fee, not a rate, so multiplying it
17
+ * by a quantity (which is what the Create Invoice line prefill does) would
18
+ * produce a plausible-looking wrong total. Those lines start unpriced.
14
19
  */
15
20
  export interface InvoicingPlanNameOption {
16
21
  planName: string;
@@ -2,10 +2,37 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCreateInvoiceFormView = void 0;
4
4
  const addressSelector_1 = require("../../../entity/address/addressSelector");
5
+ const planSelector_1 = require("../../../entity/invoicing/plan/planSelector");
5
6
  const invoicingCatalogListViewSelector_1 = require("../invoicingCatalogListView/invoicingCatalogListViewSelector");
6
7
  const invoicingConfigViewSelector_1 = require("../invoicingConfigView/invoicingConfigViewSelector");
7
8
  const invoicingCustomerListViewSelector_1 = require("../invoicingCustomerListView/invoicingCustomerListViewSelector");
8
9
  const settingsViewSelector_1 = require("../settingsView/settingsViewSelector");
10
+ /**
11
+ * Pricing models whose single-unit amount is a true per-unit rate — the only
12
+ * ones a Create Invoice line may be prefilled from. Typed against the entity
13
+ * union so a misspelt member fails to compile; a model added to the union
14
+ * still has to be classified here by hand (it is left out, so it fails closed:
15
+ * no prefill). The complement is `isTieredCatalogPricingModel`.
16
+ */
17
+ const PER_UNIT_RATE_PRICING_MODELS = [
18
+ 'per_unit',
19
+ 'flat_fee',
20
+ ];
21
+ /**
22
+ * Whether a price point's single-unit amount is a per-unit rate. A missing
23
+ * model means per-unit: the service defaults `pricing_model` to `per_unit`
24
+ * and older records may omit it.
25
+ */
26
+ const hasPerUnitRate = (pricingModel) => pricingModel == null ||
27
+ pricingModel === '' ||
28
+ PER_UNIT_RATE_PRICING_MODELS.some((model) => model === pricingModel);
29
+ /**
30
+ * The amount to prefill on a Create Invoice line for a price point, or
31
+ * `undefined` when there is no safe per-unit rate to prefill.
32
+ */
33
+ const planNamePrefillPrice = (pricePoint) => hasPerUnitRate(pricePoint.pricingModel)
34
+ ? (0, planSelector_1.invoicingPricePointDisplayAmount)(pricePoint)?.amount
35
+ : undefined;
9
36
  /**
10
37
  * Display name for a customer option: company, else the full name, else the
11
38
  * email, else the raw id.
@@ -50,7 +77,7 @@ const getCreateInvoiceFormView = (state) => {
50
77
  .filter((subFamily) => (subFamily.name ?? '') !== '')
51
78
  .map((subFamily) => ({
52
79
  planName: plan.name ?? '',
53
- price: subFamily.price?.amount,
80
+ price: planNamePrefillPrice(subFamily),
54
81
  subFamilyName: subFamily.name ?? '',
55
82
  }))),
56
83
  products: (0, invoicingCatalogListViewSelector_1.getInvoicingCatalogPrices)(catalogListView.products),
@@ -1,12 +1,12 @@
1
1
  import { InvoicingPlan } from '../../../entity/invoicing/plan/planState';
2
- import { InvoicingProduct } from '../../../entity/invoicing/product/productState';
2
+ import { InvoicingCatalogPricingModel, InvoicingProduct } from '../../../entity/invoicing/product/productState';
3
3
  import { InvoicingCatalogItemFormLocalData, InvoicingCatalogItemFormSubFamily, InvoicingCatalogItemFormTier } from './editInvoicingCatalogItemDetailViewState';
4
4
  /**
5
5
  * Value sets the catalog item form still owns locally: the backend has no enum
6
6
  * for pricing model, tier type, proration or applicability yet, so these stay
7
7
  * here until it does. Everything else on this form comes from `/1.0/config`.
8
8
  */
9
- export declare const INVOICING_CATALOG_PRICING_MODEL_VALUES: readonly ["flat_fee", "per_unit", "tiered", "volume", "stairstep"];
9
+ export declare const INVOICING_CATALOG_PRICING_MODEL_VALUES: readonly InvoicingCatalogPricingModel[];
10
10
  export declare const INVOICING_CATALOG_TIER_TYPE_VALUES: readonly ["per_unit", "flat_fee", "package"];
11
11
  export declare const INVOICING_CATALOG_PRORATION_VALUES: readonly ["site_default", "partial_term", "full_term"];
12
12
  export declare const INVOICING_CATALOG_APPLICABILITY_VALUES: readonly ["all", "restricted"];
@@ -6,13 +6,7 @@ exports.entityToInvoicingCatalogItemFormLocalData = exports.initialInvoicingCata
6
6
  * for pricing model, tier type, proration or applicability yet, so these stay
7
7
  * here until it does. Everything else on this form comes from `/1.0/config`.
8
8
  */
9
- exports.INVOICING_CATALOG_PRICING_MODEL_VALUES = [
10
- 'flat_fee',
11
- 'per_unit',
12
- 'tiered',
13
- 'volume',
14
- 'stairstep',
15
- ];
9
+ exports.INVOICING_CATALOG_PRICING_MODEL_VALUES = ['flat_fee', 'per_unit', 'tiered', 'volume', 'stairstep'];
16
10
  exports.INVOICING_CATALOG_TIER_TYPE_VALUES = [
17
11
  'per_unit',
18
12
  'flat_fee',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "5.2.53",
3
+ "version": "5.2.54",
4
4
  "description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/esm/index.js",