platform-types 1.10.802 → 1.10.803

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.
@@ -734,6 +734,10 @@ exports.isSocketAction = isSocketAction;
734
734
  * {@link ProductRemovedFrameData} marker instead of a priced patch.
735
735
  * `catalogStatus` is carried for the same reason: a stock movement on a draft or
736
736
  * archived product becomes that marker too, never a republished row.
737
+ *
738
+ * `ivaType` is an INPUT to the shopper copy's `prices[].netOfIva`: the customer
739
+ * fan-out re-prices the frame, and without the rate a merged frame would leave a
740
+ * stale net beside a new gross. The customer copy still drops the Id itself.
737
741
  */
738
742
  exports.PRODUCT_STOCK_FRAME_FIELDS = [
739
743
  'stock',
@@ -745,6 +749,7 @@ exports.PRODUCT_STOCK_FRAME_FIELDS = [
745
749
  'catalogStatus',
746
750
  'updatedAt',
747
751
  'lastMovementAt',
752
+ 'ivaType',
748
753
  ];
749
754
  /* Agent diagnostic commands */
750
755
  /**
@@ -114,12 +114,15 @@ const LIVE_METADATA = {
114
114
  ownership: 'storefront-operation',
115
115
  excludedFromSnapshot: true,
116
116
  };
117
- const liveToggle = (key, labelKey, helpKey, label, help) => ({
117
+ const liveToggle = (key, labelKey, helpKey, label, help,
118
+ // Per key: a toggle that changes what a shopper sees for every store that has
119
+ // never written it ships `false`. Defaults to `true`, the three original toggles.
120
+ defaultValue = true) => ({
118
121
  ...LIVE_METADATA,
119
122
  key,
120
123
  allowedLayers: ['WEB#store'],
121
124
  storage: { source: 'store', override: 'ecommerce.config' },
122
- defaultValue: true,
125
+ defaultValue,
123
126
  valueType: 'boolean',
124
127
  valueSchema: { type: 'boolean' },
125
128
  literal: { kind: 'key', label: labelKey, help: helpKey, defaults: { label, help } },
@@ -145,6 +148,13 @@ exports.STOREFRONT_DESIGN_REGISTRY = {
145
148
  showIvaAlert: liveToggle('showIvaAlert', 'STOREFRONT_SHOW_IVA_ALERT_LABEL', 'STOREFRONT_SHOW_IVA_ALERT_HELP', 'Mostrar aviso de IVA', 'Mostrar el aviso de IVA incluido en los precios.'),
146
149
  showCurrencySelector: liveToggle('showCurrencySelector', 'STOREFRONT_SHOW_CURRENCY_SELECTOR_LABEL', 'STOREFRONT_SHOW_CURRENCY_SELECTOR_HELP', 'Mostrar selector de moneda', 'Permitir elegir la moneda de visualización en la tienda.'),
147
150
  enableSaveForLater: liveToggle('enableSaveForLater', 'STOREFRONT_ENABLE_SAVE_FOR_LATER_LABEL', 'STOREFRONT_ENABLE_SAVE_FOR_LATER_HELP', 'Permitir guardar para después', 'Mostrar los controles para guardar productos de la cesta para después.'),
151
+ /*
152
+ * Display only: every public price slot carries `netOfIva` whatever this says
153
+ * (absent only for a product with no declarable IVA rate), so a flip needs no
154
+ * catalogue refetch. The storefront shows the «+ IVA» line when this is on AND
155
+ * the block is present. Default off: a store opts in.
156
+ */
157
+ showNetPlusIva: liveToggle('showNetPlusIva', 'STOREFRONT_SHOW_NET_PLUS_IVA_LABEL', 'STOREFRONT_SHOW_NET_PLUS_IVA_HELP', 'Mostrar precio neto + IVA', 'Mostrar también el precio sin IVA, con la leyenda «+ IVA», junto al precio final. Nunca reemplaza al precio final.', false),
148
158
  prices: { ...LIVE_METADATA, storage: { source: 'catalogue' } },
149
159
  stock: { ...LIVE_METADATA, storage: { source: 'catalogue' } },
150
160
  checkout: { ...LIVE_METADATA, storage: { source: 'store' } },
package/dist/pricing.d.ts CHANGED
@@ -109,5 +109,43 @@ declare global {
109
109
  promo?: PricePromo;
110
110
  visibleOnStorefront?: boolean;
111
111
  } & CurrencyStamp);
112
+ /**
113
+ * Net-of-IVA display figures for one public price slot, computed server-side
114
+ * as `calculateItemNeto(figure, 1, ivaPercent, 1, 'decimal').neto` from the
115
+ * product's `ivaType`, each figure first rounded to the store's `priceDecimals`
116
+ * as it is charged — for a unit in the voucher's currency, the per-unit `neto`
117
+ * a new invoice prints for the same undiscounted unit (gross rounded to 2 dp
118
+ * first, then backed out). Absent, too, when a figure cannot be netted.
119
+ *
120
+ * ⚠️ DISPLAY ONLY: nothing charges, quotes, totals or invoices these. The
121
+ * charged figure is the slot's `amount`, always.
122
+ *
123
+ * Each net shares the stamp of the gross it nets, with no FX step: `amount`
124
+ * and `baseAmount` the slot's, `promo` the promo's, each break its own.
125
+ *
126
+ * Sent whatever `ecommerce.config.showNetPlusIva` says; that setting only
127
+ * decides whether the storefront renders it. ABSENT when the product carries
128
+ * no declarable IVA rate — never a 0 % fallback.
129
+ */
130
+ interface PublicPriceNet {
131
+ amount: number;
132
+ /** Present iff the slot carries `baseAmount`. */
133
+ baseAmount?: number;
134
+ /** Net of `promo.amount`; present iff the slot carries `promo`. */
135
+ promo?: number;
136
+ /** One per `breaks` entry of the slot, same `minQty`, same order. */
137
+ breaks?: Array<{
138
+ minQty: number;
139
+ amount: number;
140
+ }>;
141
+ }
142
+ /**
143
+ * A price slot as a PUBLIC read emits it (web catalogue reads, customer
144
+ * `products` frames). A read-time extension of {@link PriceSlot}, never
145
+ * stored: `Product.prices` stays `PriceSlot[]`, so no writer can persist a net.
146
+ */
147
+ type PublicPriceSlot = PriceSlot & {
148
+ netOfIva?: PublicPriceNet;
149
+ };
112
150
  }
113
151
  export {};
package/dist/product.d.ts CHANGED
@@ -32,8 +32,10 @@ declare global {
32
32
  type ProductUnitsInput = Omit<ProductUnits, 'unitRevision'>;
33
33
  /** The display declaration plus the purchase-unit factor; `unitRevision` stays server-only. */
34
34
  type PublicProductUnits = Pick<ProductUnits, 'baseUnit' | 'purchaseUnit' | 'packLabel' | 'baseUnitsPerPurchaseUnit'>;
35
- type PublicProduct = Omit<Partial<Product>, 'units' | 'unitRevisionGeneration'> & {
35
+ type PublicProduct = Omit<Partial<Product>, 'units' | 'unitRevisionGeneration' | 'prices'> & {
36
36
  units?: PublicProductUnits | null;
37
+ /** The shopper's one applicable slot, with its read-time `netOfIva` when the product is rated. */
38
+ prices?: PublicPriceSlot[];
37
39
  };
38
40
  /** Anonymous Web GET /products lookup; the tenant comes from the public store context. */
39
41
  interface PublicProductsByIdsInput {
package/dist/socket.d.ts CHANGED
@@ -172,8 +172,12 @@ export interface SocketMessage<T = unknown> {
172
172
  * {@link ProductRemovedFrameData} marker instead of a priced patch.
173
173
  * `catalogStatus` is carried for the same reason: a stock movement on a draft or
174
174
  * archived product becomes that marker too, never a republished row.
175
+ *
176
+ * `ivaType` is an INPUT to the shopper copy's `prices[].netOfIva`: the customer
177
+ * fan-out re-prices the frame, and without the rate a merged frame would leave a
178
+ * stale net beside a new gross. The customer copy still drops the Id itself.
175
179
  */
176
- export declare const PRODUCT_STOCK_FRAME_FIELDS: readonly ["stock", "prices", "cost", "currency", "hiddenFromStorefront", "disabled", "catalogStatus", "updatedAt", "lastMovementAt"];
180
+ export declare const PRODUCT_STOCK_FRAME_FIELDS: readonly ["stock", "prices", "cost", "currency", "hiddenFromStorefront", "disabled", "catalogStatus", "updatedAt", "lastMovementAt", "ivaType"];
177
181
  /**
178
182
  * `data` of a **partial** `products` frame — the projection every stock-moving
179
183
  * write announces, and the only `products` shape that is not a whole `Product`.
package/dist/socket.js CHANGED
@@ -730,6 +730,10 @@ export const isSocketAction = (value) => typeof value === 'string' && SOCKET_ACT
730
730
  * {@link ProductRemovedFrameData} marker instead of a priced patch.
731
731
  * `catalogStatus` is carried for the same reason: a stock movement on a draft or
732
732
  * archived product becomes that marker too, never a republished row.
733
+ *
734
+ * `ivaType` is an INPUT to the shopper copy's `prices[].netOfIva`: the customer
735
+ * fan-out re-prices the frame, and without the rate a merged frame would leave a
736
+ * stale net beside a new gross. The customer copy still drops the Id itself.
733
737
  */
734
738
  export const PRODUCT_STOCK_FRAME_FIELDS = [
735
739
  'stock',
@@ -741,6 +745,7 @@ export const PRODUCT_STOCK_FRAME_FIELDS = [
741
745
  'catalogStatus',
742
746
  'updatedAt',
743
747
  'lastMovementAt',
748
+ 'ivaType',
744
749
  ];
745
750
  /* Agent diagnostic commands */
746
751
  /**
@@ -1035,7 +1035,7 @@ export declare const STOREFRONT_DESIGN_REGISTRY: {
1035
1035
  readonly source: "store";
1036
1036
  readonly override: "ecommerce.config";
1037
1037
  };
1038
- readonly defaultValue: true;
1038
+ readonly defaultValue: boolean;
1039
1039
  readonly valueType: "boolean";
1040
1040
  readonly valueSchema: {
1041
1041
  readonly type: "boolean";
@@ -1061,7 +1061,7 @@ export declare const STOREFRONT_DESIGN_REGISTRY: {
1061
1061
  readonly source: "store";
1062
1062
  readonly override: "ecommerce.config";
1063
1063
  };
1064
- readonly defaultValue: true;
1064
+ readonly defaultValue: boolean;
1065
1065
  readonly valueType: "boolean";
1066
1066
  readonly valueSchema: {
1067
1067
  readonly type: "boolean";
@@ -1087,7 +1087,7 @@ export declare const STOREFRONT_DESIGN_REGISTRY: {
1087
1087
  readonly source: "store";
1088
1088
  readonly override: "ecommerce.config";
1089
1089
  };
1090
- readonly defaultValue: true;
1090
+ readonly defaultValue: boolean;
1091
1091
  readonly valueType: "boolean";
1092
1092
  readonly valueSchema: {
1093
1093
  readonly type: "boolean";
@@ -1106,6 +1106,32 @@ export declare const STOREFRONT_DESIGN_REGISTRY: {
1106
1106
  readonly ownership: "storefront-operation";
1107
1107
  readonly excludedFromSnapshot: true;
1108
1108
  };
1109
+ readonly showNetPlusIva: {
1110
+ readonly key: "showNetPlusIva";
1111
+ readonly allowedLayers: readonly ["WEB#store"];
1112
+ readonly storage: {
1113
+ readonly source: "store";
1114
+ readonly override: "ecommerce.config";
1115
+ };
1116
+ readonly defaultValue: boolean;
1117
+ readonly valueType: "boolean";
1118
+ readonly valueSchema: {
1119
+ readonly type: "boolean";
1120
+ };
1121
+ readonly literal: {
1122
+ readonly kind: "key";
1123
+ readonly label: "STOREFRONT_SHOW_NET_PLUS_IVA_LABEL";
1124
+ readonly help: "STOREFRONT_SHOW_NET_PLUS_IVA_HELP";
1125
+ readonly defaults: {
1126
+ readonly label: string;
1127
+ readonly help: string;
1128
+ };
1129
+ };
1130
+ readonly audience: "public";
1131
+ readonly lifecycle: "live";
1132
+ readonly ownership: "storefront-operation";
1133
+ readonly excludedFromSnapshot: true;
1134
+ };
1109
1135
  readonly prices: {
1110
1136
  readonly storage: {
1111
1137
  readonly source: "catalogue";
@@ -106,12 +106,15 @@ const LIVE_METADATA = {
106
106
  ownership: 'storefront-operation',
107
107
  excludedFromSnapshot: true,
108
108
  };
109
- const liveToggle = (key, labelKey, helpKey, label, help) => ({
109
+ const liveToggle = (key, labelKey, helpKey, label, help,
110
+ // Per key: a toggle that changes what a shopper sees for every store that has
111
+ // never written it ships `false`. Defaults to `true`, the three original toggles.
112
+ defaultValue = true) => ({
110
113
  ...LIVE_METADATA,
111
114
  key,
112
115
  allowedLayers: ['WEB#store'],
113
116
  storage: { source: 'store', override: 'ecommerce.config' },
114
- defaultValue: true,
117
+ defaultValue,
115
118
  valueType: 'boolean',
116
119
  valueSchema: { type: 'boolean' },
117
120
  literal: { kind: 'key', label: labelKey, help: helpKey, defaults: { label, help } },
@@ -137,6 +140,13 @@ export const STOREFRONT_DESIGN_REGISTRY = {
137
140
  showIvaAlert: liveToggle('showIvaAlert', 'STOREFRONT_SHOW_IVA_ALERT_LABEL', 'STOREFRONT_SHOW_IVA_ALERT_HELP', 'Mostrar aviso de IVA', 'Mostrar el aviso de IVA incluido en los precios.'),
138
141
  showCurrencySelector: liveToggle('showCurrencySelector', 'STOREFRONT_SHOW_CURRENCY_SELECTOR_LABEL', 'STOREFRONT_SHOW_CURRENCY_SELECTOR_HELP', 'Mostrar selector de moneda', 'Permitir elegir la moneda de visualización en la tienda.'),
139
142
  enableSaveForLater: liveToggle('enableSaveForLater', 'STOREFRONT_ENABLE_SAVE_FOR_LATER_LABEL', 'STOREFRONT_ENABLE_SAVE_FOR_LATER_HELP', 'Permitir guardar para después', 'Mostrar los controles para guardar productos de la cesta para después.'),
143
+ /*
144
+ * Display only: every public price slot carries `netOfIva` whatever this says
145
+ * (absent only for a product with no declarable IVA rate), so a flip needs no
146
+ * catalogue refetch. The storefront shows the «+ IVA» line when this is on AND
147
+ * the block is present. Default off: a store opts in.
148
+ */
149
+ showNetPlusIva: liveToggle('showNetPlusIva', 'STOREFRONT_SHOW_NET_PLUS_IVA_LABEL', 'STOREFRONT_SHOW_NET_PLUS_IVA_HELP', 'Mostrar precio neto + IVA', 'Mostrar también el precio sin IVA, con la leyenda «+ IVA», junto al precio final. Nunca reemplaza al precio final.', false),
140
150
  prices: { ...LIVE_METADATA, storage: { source: 'catalogue' } },
141
151
  stock: { ...LIVE_METADATA, storage: { source: 'catalogue' } },
142
152
  checkout: { ...LIVE_METADATA, storage: { source: 'store' } },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "platform-types",
3
- "version": "1.10.802",
3
+ "version": "1.10.803",
4
4
  "description": "Shared wire and entity contracts for the platform.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",