@peabody-soft/mbs-model-ts 1.7.1 → 1.9.0
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/dist/Business.js +2 -1
- package/dist/Catalog.d.ts +19 -7
- package/dist/Catalog.js +119 -39
- package/dist/Constants.d.ts +1 -0
- package/dist/Constants.js +6 -3
- package/dist/Entity.d.ts +1 -0
- package/dist/Entity.js +4 -0
- package/dist/Enums.d.ts +1 -0
- package/dist/Enums.js +1 -0
- package/dist/GeneralSettings.d.ts +5 -4
- package/dist/GeneralSettings.js +9 -8
- package/dist/Item.js +2 -1
- package/dist/Package.d.ts +6 -2
- package/dist/Package.js +11 -5
- package/dist/Price.d.ts +5 -2
- package/dist/Price.js +18 -3
- package/dist/PriceList.d.ts +13 -0
- package/dist/PriceList.js +50 -2
- package/dist/Product.d.ts +6 -2
- package/dist/Product.js +8 -5
- package/dist/ProtoMap.js +60 -68
- package/dist/ShoppingList.js +4 -3
- package/dist/generated/BusinessSyncOutResponse.d.ts +4 -1
- package/dist/generated/Constants.d.ts +0 -4
- package/dist/generated/Constants.js +0 -4
- package/dist/generated/GeneralSettings.d.ts +5 -4
- package/dist/generated/GeneralSettings.js +8 -6
- package/dist/generated/Item.d.ts +4 -3
- package/dist/generated/Message.d.ts +5 -0
- package/dist/generated/OnlineStoreTheme.d.ts +33 -0
- package/dist/generated/OnlineStoreTheme.js +38 -0
- package/dist/generated/Price.d.ts +9 -0
- package/dist/generated/Price.js +9 -1
- package/dist/generated/PriceList.d.ts +13 -2
- package/dist/generated/ProfileSyncOutRequest.d.ts +16 -15
- package/dist/generated/ProfileSyncOutResponse.d.ts +4 -6
- package/dist/generated/SalesOrderPayload.d.ts +6 -3
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -2
- package/package.json +2 -2
package/dist/Business.js
CHANGED
|
@@ -57,7 +57,8 @@ export default class Business extends Entity {
|
|
|
57
57
|
this._orders = value;
|
|
58
58
|
}
|
|
59
59
|
// What this customer has picked and not yet ordered. Null until something is put in a cart, and
|
|
60
|
-
// null again once the cart is ordered. The cart message itself stays, with no list
|
|
60
|
+
// null again once the cart is ordered. The cart message itself stays, with no list, or with a list
|
|
61
|
+
// that has no items (the merchant app stores one), which is null here too. Only the list
|
|
61
62
|
// is exposed here. The fulfillment mode is chosen when an order is placed and is stored on the
|
|
62
63
|
// Order (see defaultFulfillmentMode).
|
|
63
64
|
get cart() {
|
package/dist/Catalog.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import Item from "./Item";
|
|
2
2
|
import Package from "./Package";
|
|
3
|
+
import Price from "./Price";
|
|
3
4
|
import PriceList from "./PriceList";
|
|
4
5
|
import Product from "./Product";
|
|
5
6
|
import ProductCategory from "./ProductCategory";
|
|
6
7
|
export default class Catalog {
|
|
7
|
-
|
|
8
|
-
constructor(categories: ReadonlyArray<ProductCategory>, products: ReadonlyArray<Product>, _priceList: PriceList | null);
|
|
8
|
+
constructor(categories: ReadonlyArray<ProductCategory>, products: ReadonlyArray<Product>, packages: ReadonlyArray<Package>, priceLists: ReadonlyArray<PriceList>, prices: ReadonlyArray<Price>);
|
|
9
9
|
get categories(): ReadonlyArray<ProductCategory>;
|
|
10
10
|
get products(): ReadonlyArray<Product>;
|
|
11
|
+
get currentSalePriceListId(): bigint;
|
|
12
|
+
private set currentSalePriceListId(value);
|
|
11
13
|
get priceList(): PriceList | null;
|
|
12
14
|
get productCount(): number;
|
|
13
15
|
get packageCount(): number;
|
|
@@ -19,10 +21,20 @@ export default class Catalog {
|
|
|
19
21
|
private static compareNames;
|
|
20
22
|
private static compareIds;
|
|
21
23
|
private static comparePrices;
|
|
24
|
+
private applySalePriceList;
|
|
22
25
|
static readonly EMPTY: Catalog;
|
|
23
|
-
private readonly
|
|
24
|
-
private readonly
|
|
25
|
-
private readonly
|
|
26
|
-
private readonly
|
|
27
|
-
private readonly
|
|
26
|
+
private readonly _allCategories;
|
|
27
|
+
private readonly _allProducts;
|
|
28
|
+
private readonly _uncategorized;
|
|
29
|
+
private readonly _candidatePackages;
|
|
30
|
+
private readonly _priceListMap;
|
|
31
|
+
private _currentSalePriceListId;
|
|
32
|
+
private _categories;
|
|
33
|
+
private _products;
|
|
34
|
+
private _categoryMap;
|
|
35
|
+
private _productMap;
|
|
36
|
+
private _packageMap;
|
|
37
|
+
}
|
|
38
|
+
export interface UpdatableCatalog {
|
|
39
|
+
set currentSalePriceListId(value: bigint);
|
|
28
40
|
}
|
package/dist/Catalog.js
CHANGED
|
@@ -1,51 +1,70 @@
|
|
|
1
1
|
import { Constants as proto_Constants } from "./generated/Constants";
|
|
2
|
-
import {
|
|
2
|
+
import { DEFAULT_SALE_PRICE_LIST_ID } from "./Constants";
|
|
3
|
+
import { EntityHeader, UpdatableEntity } from "./Entity";
|
|
3
4
|
import ProductCategory from "./ProductCategory";
|
|
4
5
|
// The catalog of a business: its categories and the products in them. Not an entity and not on the
|
|
5
|
-
// wire. The sync layer
|
|
6
|
+
// wire. The sync layer builds it from the flat item entities of a sync response, as the merchant
|
|
7
|
+
// app's Catalog is built.
|
|
8
|
+
//
|
|
9
|
+
// The constructor links what it is given: a package to its product, a price to its price list and a
|
|
10
|
+
// price list to its parent. It does not depend on any price list being present. Packages are priced
|
|
11
|
+
// from currentSalePriceListId, so setting that id decides which packages and products are buyable.
|
|
6
12
|
class Catalog {
|
|
7
|
-
constructor(categories, products,
|
|
8
|
-
|
|
13
|
+
constructor(categories, products, packages, priceLists, prices) {
|
|
14
|
+
// Every package that has a product, by that product's id, whether it can be bought or not
|
|
15
|
+
this._candidatePackages = new Map();
|
|
16
|
+
this._priceListMap = new Map();
|
|
17
|
+
this._currentSalePriceListId = DEFAULT_SALE_PRICE_LIST_ID;
|
|
18
|
+
// What a customer can reach, rebuilt by applySalePriceList
|
|
19
|
+
this._categories = Object.freeze([]);
|
|
20
|
+
this._products = Object.freeze([]);
|
|
9
21
|
this._categoryMap = new Map();
|
|
10
22
|
this._productMap = new Map();
|
|
11
23
|
this._packageMap = new Map();
|
|
24
|
+
this._allCategories = categories;
|
|
25
|
+
this._allProducts = products;
|
|
12
26
|
// A dummy category for products whose parentItemId is Constants.ENTITY_ID_NULL. Its id is also
|
|
13
27
|
// ENTITY_ID_NULL, so getCategory(product.productCategoryId) resolves it like a real category.
|
|
14
|
-
// It is left out
|
|
15
|
-
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (!product.isBuyable)
|
|
28
|
+
// It is left out like any other category when it has no buyable products.
|
|
29
|
+
this._uncategorized = new ProductCategory(new EntityHeader(BigInt(proto_Constants.ENTITY_ID_NULL), 0n, 0n, 0n, 0n), "", null, BigInt(proto_Constants.ENTITY_ID_NULL), false);
|
|
30
|
+
// A package with no product is dropped
|
|
31
|
+
const productsById = new Map();
|
|
32
|
+
for (const product of products)
|
|
33
|
+
productsById.set(product.id, product);
|
|
34
|
+
for (const pkg of packages) {
|
|
35
|
+
const product = productsById.get(pkg.productId);
|
|
36
|
+
if (product === undefined)
|
|
24
37
|
continue;
|
|
25
|
-
|
|
26
|
-
this.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
productsByCategory.set(product.productCategoryId, [product]);
|
|
38
|
+
UpdatableEntity.setParent(pkg, product);
|
|
39
|
+
const productPackages = this._candidatePackages.get(product.id);
|
|
40
|
+
if (productPackages === undefined)
|
|
41
|
+
this._candidatePackages.set(product.id, [pkg]);
|
|
30
42
|
else
|
|
31
|
-
|
|
32
|
-
for (const pkg of product.packages)
|
|
33
|
-
this._packageMap.set(pkg.id, pkg);
|
|
43
|
+
productPackages.push(pkg);
|
|
34
44
|
}
|
|
35
|
-
|
|
36
|
-
//
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
// The first of two price lists with one id is kept. A price with no price list is dropped, and a
|
|
46
|
+
// list holds one price per package, the first to arrive.
|
|
47
|
+
for (const priceList of priceLists)
|
|
48
|
+
if (!this._priceListMap.has(priceList.id))
|
|
49
|
+
this._priceListMap.set(priceList.id, priceList);
|
|
50
|
+
const pricesByList = new Map();
|
|
51
|
+
for (const price of prices) {
|
|
52
|
+
if (!this._priceListMap.has(price.priceListId))
|
|
42
53
|
continue;
|
|
43
|
-
|
|
44
|
-
|
|
54
|
+
const listPrices = pricesByList.get(price.priceListId);
|
|
55
|
+
if (listPrices === undefined)
|
|
56
|
+
pricesByList.set(price.priceListId, new Map([[price.packageId, price]]));
|
|
57
|
+
else if (!listPrices.has(price.packageId))
|
|
58
|
+
listPrices.set(price.packageId, price);
|
|
45
59
|
}
|
|
46
|
-
|
|
47
|
-
for (const
|
|
48
|
-
|
|
60
|
+
// A parent that was not read, or a list that names itself, leaves the list without a parent
|
|
61
|
+
for (const priceList of this._priceListMap.values()) {
|
|
62
|
+
const updatable = priceList;
|
|
63
|
+
updatable.prices = pricesByList.get(priceList.id) ?? new Map();
|
|
64
|
+
const parent = this._priceListMap.get(priceList.parentPriceListId) ?? null;
|
|
65
|
+
updatable.parentPriceList = parent === priceList ? null : parent;
|
|
66
|
+
}
|
|
67
|
+
this.applySalePriceList();
|
|
49
68
|
}
|
|
50
69
|
// In no particular order - a UI orders these for display
|
|
51
70
|
get categories() {
|
|
@@ -55,11 +74,22 @@ class Catalog {
|
|
|
55
74
|
get products() {
|
|
56
75
|
return this._products;
|
|
57
76
|
}
|
|
58
|
-
// The
|
|
59
|
-
//
|
|
77
|
+
// The id of the price list packages are priced from, DEFAULT_SALE_PRICE_LIST_ID until the sync
|
|
78
|
+
// layer sets it. Setting it prices every package from that list (see PriceList.getPrice), and keeps
|
|
79
|
+
// the packages, products and categories that can then be bought. An id that names no list prices
|
|
80
|
+
// nothing, so the catalog holds nothing.
|
|
81
|
+
get currentSalePriceListId() {
|
|
82
|
+
return this._currentSalePriceListId;
|
|
83
|
+
}
|
|
84
|
+
set currentSalePriceListId(value) {
|
|
85
|
+
this._currentSalePriceListId = value;
|
|
86
|
+
this.applySalePriceList();
|
|
87
|
+
}
|
|
88
|
+
// The price list packages are priced from (MeraBills Online for a storefront). Null when the
|
|
89
|
+
// catalog has no list with the current id, as before the catalog has arrived. A shopping list
|
|
60
90
|
// built from this catalog carries its id, or MERABILLS_ONLINE_PRICE_LIST_ID while it is null.
|
|
61
91
|
get priceList() {
|
|
62
|
-
return this.
|
|
92
|
+
return this._priceListMap.get(this._currentSalePriceListId) ?? null;
|
|
63
93
|
}
|
|
64
94
|
get productCount() {
|
|
65
95
|
return this._products.length;
|
|
@@ -75,7 +105,8 @@ class Catalog {
|
|
|
75
105
|
return this._productMap.get(productId) ?? null;
|
|
76
106
|
}
|
|
77
107
|
// Null for the four reserved package ids a shopping list uses for its charge and summary lines
|
|
78
|
-
// (see Ids.isReservedPackageId), and for a package
|
|
108
|
+
// (see Ids.isReservedPackageId), and for a package that is not buyable or whose product is not
|
|
109
|
+
// buyable
|
|
79
110
|
getPackage(packageId) {
|
|
80
111
|
return this._packageMap.get(packageId) ?? null;
|
|
81
112
|
}
|
|
@@ -111,7 +142,56 @@ class Catalog {
|
|
|
111
142
|
return -1;
|
|
112
143
|
return left.offerPrice - right.offerPrice;
|
|
113
144
|
}
|
|
145
|
+
// Prices the packages from the current sale price list, then rebuilds what a customer can reach.
|
|
146
|
+
// Only a buyable product is part of a catalog: enabled, not sold only offline, with at least one
|
|
147
|
+
// buyable package. Any other is left out of products, getProduct and its categories, and its
|
|
148
|
+
// packages are unreachable by id. A category with no buyable products is left out too, the dummy
|
|
149
|
+
// one included.
|
|
150
|
+
applySalePriceList() {
|
|
151
|
+
const salePriceList = this.priceList;
|
|
152
|
+
const buyableProducts = [];
|
|
153
|
+
const productMap = new Map();
|
|
154
|
+
const packageMap = new Map();
|
|
155
|
+
const productsByCategory = new Map();
|
|
156
|
+
for (const product of this._allProducts) {
|
|
157
|
+
const candidates = this._candidatePackages.get(product.id) ?? [];
|
|
158
|
+
for (const pkg of candidates) {
|
|
159
|
+
const price = salePriceList === null ? null : salePriceList.getPrice(pkg.id);
|
|
160
|
+
pkg.price = price;
|
|
161
|
+
if (price !== null)
|
|
162
|
+
UpdatableEntity.setParent(price, pkg);
|
|
163
|
+
}
|
|
164
|
+
// The product keeps only the buyable ones, and is judged by them
|
|
165
|
+
product.packages = candidates;
|
|
166
|
+
if (!product.isBuyable)
|
|
167
|
+
continue;
|
|
168
|
+
buyableProducts.push(product);
|
|
169
|
+
productMap.set(product.id, product);
|
|
170
|
+
const productsOfCategory = productsByCategory.get(product.productCategoryId);
|
|
171
|
+
if (productsOfCategory === undefined)
|
|
172
|
+
productsByCategory.set(product.productCategoryId, [product]);
|
|
173
|
+
else
|
|
174
|
+
productsOfCategory.push(product);
|
|
175
|
+
for (const pkg of product.packages)
|
|
176
|
+
packageMap.set(pkg.id, pkg);
|
|
177
|
+
}
|
|
178
|
+
const nonEmptyCategories = [];
|
|
179
|
+
const categoryMap = new Map();
|
|
180
|
+
for (const category of [...this._allCategories, this._uncategorized]) {
|
|
181
|
+
const categoryProducts = productsByCategory.get(category.id);
|
|
182
|
+
category.products = Object.freeze(categoryProducts ?? []);
|
|
183
|
+
if (categoryProducts === undefined)
|
|
184
|
+
continue;
|
|
185
|
+
nonEmptyCategories.push(category);
|
|
186
|
+
categoryMap.set(category.id, category);
|
|
187
|
+
}
|
|
188
|
+
this._products = Object.freeze(buyableProducts);
|
|
189
|
+
this._categories = Object.freeze(nonEmptyCategories);
|
|
190
|
+
this._productMap = productMap;
|
|
191
|
+
this._packageMap = packageMap;
|
|
192
|
+
this._categoryMap = categoryMap;
|
|
193
|
+
}
|
|
114
194
|
}
|
|
115
195
|
// A business whose catalog has not arrived yet
|
|
116
|
-
Catalog.EMPTY = new Catalog(
|
|
196
|
+
Catalog.EMPTY = new Catalog([], [], [], [], []);
|
|
117
197
|
export default Catalog;
|
package/dist/Constants.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { Constants } from "./generated/Constants";
|
|
2
2
|
export declare function buildPriceListId(priceList: number): bigint;
|
|
3
|
+
export declare const DEFAULT_SALE_PRICE_LIST_ID: bigint;
|
|
3
4
|
export declare const MERABILLS_ONLINE_PRICE_LIST_ID: bigint;
|
|
4
5
|
export declare const MAX_SCALED_AMOUNT: bigint;
|
|
5
6
|
export declare function amountFromScaledValue(scaledAmount: bigint): number;
|
package/dist/Constants.js
CHANGED
|
@@ -11,9 +11,12 @@ export { Constants } from "./generated/Constants";
|
|
|
11
11
|
export function buildPriceListId(priceList) {
|
|
12
12
|
return Ids.buildId(proto_Constants.PRICE_LIST_ENTITY_TYPE_ID, BigInt(priceList));
|
|
13
13
|
}
|
|
14
|
-
// The
|
|
15
|
-
|
|
16
|
-
//
|
|
14
|
+
// The list a catalog sells from until another is set, as in the merchant app's Catalog
|
|
15
|
+
export const DEFAULT_SALE_PRICE_LIST_ID = buildPriceListId(proto_Constants.DEFAULT_SALE_PRICE_LIST);
|
|
16
|
+
// The list a storefront sells from. A business prices a package in several lists (over the counter,
|
|
17
|
+
// on a marketplace), and a response can carry any of its public ones. ProtoMap.buildBusiness sets
|
|
18
|
+
// the catalog to sell from this one, which can take the amounts of a package from its parent (see
|
|
19
|
+
// PriceList.getPrice).
|
|
17
20
|
export const MERABILLS_ONLINE_PRICE_LIST_ID = buildPriceListId(proto_Constants.MERABILLS_ONLINE_PRICE_LIST);
|
|
18
21
|
// The largest amount the protocol can carry (Java Transaction.MAX_AMOUNT). Kept here because it does
|
|
19
22
|
// not fit a protobuf enum value. It is 2^44 - 1, well below 2^53, so an amount is safe as a number.
|
package/dist/Entity.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export default abstract class Entity {
|
|
|
10
10
|
get isDeleted(): boolean;
|
|
11
11
|
get parent(): Entity | null;
|
|
12
12
|
protected set parent(value: Entity | null);
|
|
13
|
+
protected get header(): EntityHeader;
|
|
13
14
|
private static readonly UPDATE_TYPE_MASK;
|
|
14
15
|
private readonly _header;
|
|
15
16
|
private _parent;
|
package/dist/Entity.js
CHANGED
|
@@ -49,6 +49,10 @@ class Entity {
|
|
|
49
49
|
set parent(value) {
|
|
50
50
|
this._parent = value;
|
|
51
51
|
}
|
|
52
|
+
// For a subclass that builds a variant of itself, which has the same id and update number
|
|
53
|
+
get header() {
|
|
54
|
+
return this._header;
|
|
55
|
+
}
|
|
52
56
|
}
|
|
53
57
|
Entity.UPDATE_TYPE_MASK = BigInt(proto_Constants.UPDATE_TYPE_MASK);
|
|
54
58
|
export default Entity;
|
package/dist/Enums.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { BusinessIdentifierType } from "./generated/BusinessIdentifierType";
|
|
|
5
5
|
export { DimensionUnit } from "./generated/DimensionUnit";
|
|
6
6
|
export { FulfillmentMode } from "./generated/FulfillmentMode";
|
|
7
7
|
export { MessageType } from "./generated/MessageType";
|
|
8
|
+
export { OnlineStoreTheme } from "./generated/OnlineStoreTheme";
|
|
8
9
|
export { OrderStatus } from "./generated/OrderStatus";
|
|
9
10
|
export { PackageIdentifierType } from "./generated/PackageIdentifierType";
|
|
10
11
|
export { PaymentMethod } from "./generated/PaymentMethod";
|
package/dist/Enums.js
CHANGED
|
@@ -8,6 +8,7 @@ export { BusinessIdentifierType } from "./generated/BusinessIdentifierType";
|
|
|
8
8
|
export { DimensionUnit } from "./generated/DimensionUnit";
|
|
9
9
|
export { FulfillmentMode } from "./generated/FulfillmentMode";
|
|
10
10
|
export { MessageType } from "./generated/MessageType";
|
|
11
|
+
export { OnlineStoreTheme } from "./generated/OnlineStoreTheme";
|
|
11
12
|
export { OrderStatus } from "./generated/OrderStatus";
|
|
12
13
|
export { PackageIdentifierType } from "./generated/PackageIdentifierType";
|
|
13
14
|
export { PaymentMethod } from "./generated/PaymentMethod";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FulfillmentMode as proto_FulfillmentMode } from "./generated/FulfillmentMode";
|
|
2
|
+
import { OnlineStoreTheme as proto_OnlineStoreTheme } from "./generated/OnlineStoreTheme";
|
|
2
3
|
import { AddressList } from "./Address";
|
|
3
4
|
import BusinessIdentifier from "./BusinessIdentifier";
|
|
4
5
|
import LatLong from "./LatLong";
|
|
@@ -22,10 +23,10 @@ export default class GeneralSettings {
|
|
|
22
23
|
private readonly _primaryStoreLocation;
|
|
23
24
|
private readonly _googleBusinessCategoryId;
|
|
24
25
|
private readonly _googleBusinessCategoryName;
|
|
25
|
-
private readonly
|
|
26
|
+
private readonly _onlineStoreTheme;
|
|
26
27
|
private readonly _onlineShoppingEnabled;
|
|
27
|
-
static fromScaledValues(paymentMethodDetails: ReadonlyArray<PaymentMethodDetail>, customerServicePhone: string | null, isWhatsAppSupported: boolean, isSmsSupported: boolean, businessAddresses: AddressList, businessIdentifiers: ReadonlyArray<BusinessIdentifier>, fulfillmentModes: ReadonlyArray<proto_FulfillmentMode>, scaledDeliveryCharge: bigint, deliveryChargeTaxes: ReadonlyArray<Tax>, scaledFreeDeliveryTotal: bigint, deliveryRadiusKilometres: number, storeTagline: string | null, workingDays: WorkingDays, primaryStoreLocation: LatLong | null, googleBusinessCategoryId: string | null, googleBusinessCategoryName: string | null,
|
|
28
|
-
constructor(_paymentMethodDetails: ReadonlyArray<PaymentMethodDetail>, _customerServicePhone: string | null, _isWhatsAppSupported: boolean, _isSmsSupported: boolean, _businessAddresses: AddressList, _businessIdentifiers: ReadonlyArray<BusinessIdentifier>, _fulfillmentModes: ReadonlyArray<proto_FulfillmentMode>, _deliveryCharge: number, _deliveryChargeTaxes: ReadonlyArray<Tax>, _freeDeliveryTotal: number, _deliveryRadiusKilometres: number, _storeTagline: string | null, _workingDays: WorkingDays, _primaryStoreLocation: LatLong | null, _googleBusinessCategoryId: string | null, _googleBusinessCategoryName: string | null,
|
|
28
|
+
static fromScaledValues(paymentMethodDetails: ReadonlyArray<PaymentMethodDetail>, customerServicePhone: string | null, isWhatsAppSupported: boolean, isSmsSupported: boolean, businessAddresses: AddressList, businessIdentifiers: ReadonlyArray<BusinessIdentifier>, fulfillmentModes: ReadonlyArray<proto_FulfillmentMode>, scaledDeliveryCharge: bigint, deliveryChargeTaxes: ReadonlyArray<Tax>, scaledFreeDeliveryTotal: bigint, deliveryRadiusKilometres: number, storeTagline: string | null, workingDays: WorkingDays, primaryStoreLocation: LatLong | null, googleBusinessCategoryId: string | null, googleBusinessCategoryName: string | null, onlineStoreTheme: proto_OnlineStoreTheme | null, onlineShoppingEnabled: boolean): GeneralSettings;
|
|
29
|
+
constructor(_paymentMethodDetails: ReadonlyArray<PaymentMethodDetail>, _customerServicePhone: string | null, _isWhatsAppSupported: boolean, _isSmsSupported: boolean, _businessAddresses: AddressList, _businessIdentifiers: ReadonlyArray<BusinessIdentifier>, _fulfillmentModes: ReadonlyArray<proto_FulfillmentMode>, _deliveryCharge: number, _deliveryChargeTaxes: ReadonlyArray<Tax>, _freeDeliveryTotal: number, _deliveryRadiusKilometres: number, _storeTagline: string | null, _workingDays: WorkingDays, _primaryStoreLocation: LatLong | null, _googleBusinessCategoryId: string | null, _googleBusinessCategoryName: string | null, _onlineStoreTheme: proto_OnlineStoreTheme | null, _onlineShoppingEnabled: boolean);
|
|
29
30
|
get paymentMethodDetails(): ReadonlyArray<PaymentMethodDetail>;
|
|
30
31
|
get customerServicePhone(): string | null;
|
|
31
32
|
get isWhatsAppSupported(): boolean;
|
|
@@ -42,7 +43,7 @@ export default class GeneralSettings {
|
|
|
42
43
|
get primaryStoreLocation(): LatLong | null;
|
|
43
44
|
get googleBusinessCategoryId(): string | null;
|
|
44
45
|
get googleBusinessCategoryName(): string | null;
|
|
45
|
-
get
|
|
46
|
+
get onlineStoreTheme(): proto_OnlineStoreTheme | null;
|
|
46
47
|
get onlineShoppingEnabled(): boolean;
|
|
47
48
|
static readonly EMPTY: GeneralSettings;
|
|
48
49
|
}
|
package/dist/GeneralSettings.js
CHANGED
|
@@ -7,10 +7,10 @@ import WorkingDays from "./WorkingDays";
|
|
|
7
7
|
// merchant-only fields are absent.
|
|
8
8
|
class GeneralSettings {
|
|
9
9
|
// For ProtoMap, which sees amounts still multiplied by Constants.AMOUNT_FACTOR.
|
|
10
|
-
static fromScaledValues(paymentMethodDetails, customerServicePhone, isWhatsAppSupported, isSmsSupported, businessAddresses, businessIdentifiers, fulfillmentModes, scaledDeliveryCharge, deliveryChargeTaxes, scaledFreeDeliveryTotal, deliveryRadiusKilometres, storeTagline, workingDays, primaryStoreLocation, googleBusinessCategoryId, googleBusinessCategoryName,
|
|
11
|
-
return new GeneralSettings(paymentMethodDetails, customerServicePhone, isWhatsAppSupported, isSmsSupported, businessAddresses, businessIdentifiers, fulfillmentModes, amountFromScaledValue(scaledDeliveryCharge), deliveryChargeTaxes, amountFromScaledValue(scaledFreeDeliveryTotal), deliveryRadiusKilometres, storeTagline, workingDays, primaryStoreLocation, googleBusinessCategoryId, googleBusinessCategoryName,
|
|
10
|
+
static fromScaledValues(paymentMethodDetails, customerServicePhone, isWhatsAppSupported, isSmsSupported, businessAddresses, businessIdentifiers, fulfillmentModes, scaledDeliveryCharge, deliveryChargeTaxes, scaledFreeDeliveryTotal, deliveryRadiusKilometres, storeTagline, workingDays, primaryStoreLocation, googleBusinessCategoryId, googleBusinessCategoryName, onlineStoreTheme, onlineShoppingEnabled) {
|
|
11
|
+
return new GeneralSettings(paymentMethodDetails, customerServicePhone, isWhatsAppSupported, isSmsSupported, businessAddresses, businessIdentifiers, fulfillmentModes, amountFromScaledValue(scaledDeliveryCharge), deliveryChargeTaxes, amountFromScaledValue(scaledFreeDeliveryTotal), deliveryRadiusKilometres, storeTagline, workingDays, primaryStoreLocation, googleBusinessCategoryId, googleBusinessCategoryName, onlineStoreTheme, onlineShoppingEnabled);
|
|
12
12
|
}
|
|
13
|
-
constructor(_paymentMethodDetails, _customerServicePhone, _isWhatsAppSupported, _isSmsSupported, _businessAddresses, _businessIdentifiers, _fulfillmentModes, _deliveryCharge, _deliveryChargeTaxes, _freeDeliveryTotal, _deliveryRadiusKilometres, _storeTagline, _workingDays, _primaryStoreLocation, _googleBusinessCategoryId, _googleBusinessCategoryName,
|
|
13
|
+
constructor(_paymentMethodDetails, _customerServicePhone, _isWhatsAppSupported, _isSmsSupported, _businessAddresses, _businessIdentifiers, _fulfillmentModes, _deliveryCharge, _deliveryChargeTaxes, _freeDeliveryTotal, _deliveryRadiusKilometres, _storeTagline, _workingDays, _primaryStoreLocation, _googleBusinessCategoryId, _googleBusinessCategoryName, _onlineStoreTheme, _onlineShoppingEnabled) {
|
|
14
14
|
this._paymentMethodDetails = _paymentMethodDetails;
|
|
15
15
|
this._customerServicePhone = _customerServicePhone;
|
|
16
16
|
this._isWhatsAppSupported = _isWhatsAppSupported;
|
|
@@ -27,7 +27,7 @@ class GeneralSettings {
|
|
|
27
27
|
this._primaryStoreLocation = _primaryStoreLocation;
|
|
28
28
|
this._googleBusinessCategoryId = _googleBusinessCategoryId;
|
|
29
29
|
this._googleBusinessCategoryName = _googleBusinessCategoryName;
|
|
30
|
-
this.
|
|
30
|
+
this._onlineStoreTheme = _onlineStoreTheme;
|
|
31
31
|
this._onlineShoppingEnabled = _onlineShoppingEnabled;
|
|
32
32
|
}
|
|
33
33
|
get paymentMethodDetails() {
|
|
@@ -93,10 +93,11 @@ class GeneralSettings {
|
|
|
93
93
|
get googleBusinessCategoryName() {
|
|
94
94
|
return this._googleBusinessCategoryName;
|
|
95
95
|
}
|
|
96
|
-
// Which of the storefront's
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
// Which of the storefront's themes this business picked. Null when none was picked. A theme that a
|
|
97
|
+
// newer app added, which this version of the library has no entry for, is returned as it came: a
|
|
98
|
+
// number that is not a member of the enum. A caller that maps themes must have a fallback.
|
|
99
|
+
get onlineStoreTheme() {
|
|
100
|
+
return this._onlineStoreTheme;
|
|
100
101
|
}
|
|
101
102
|
// Whether the business has turned online shopping on. The server sends the business either way.
|
|
102
103
|
// Model throws a NotFoundException, after reading everything it was sent, when the settings it
|
package/dist/Item.js
CHANGED
|
@@ -17,7 +17,8 @@ export default class Item extends Entity {
|
|
|
17
17
|
get description() {
|
|
18
18
|
return this._description;
|
|
19
19
|
}
|
|
20
|
-
// Constants.ENTITY_ID_NULL when this item has no parent (e.g. an uncategorized product, or a price
|
|
20
|
+
// Constants.ENTITY_ID_NULL when this item has no parent (e.g. an uncategorized product, or a price
|
|
21
|
+
// list with no parent list).
|
|
21
22
|
get parentItemId() {
|
|
22
23
|
return this._parentItemId;
|
|
23
24
|
}
|
package/dist/Package.d.ts
CHANGED
|
@@ -11,8 +11,7 @@ export default class Package extends Item {
|
|
|
11
11
|
private readonly _dimensions;
|
|
12
12
|
private readonly _weight;
|
|
13
13
|
private readonly _photos;
|
|
14
|
-
|
|
15
|
-
constructor(header: EntityHeader, name: string, description: string | null, productId: bigint, isDisabled: boolean, _isSoldLoose: boolean, _itemCode: bigint, _identifiers: ReadonlyArray<PackageIdentifier>, _dimensions: Dimensions | null, _weight: Weight | null, _photos: ReadonlyArray<Photo>, _price: Price | null);
|
|
14
|
+
constructor(header: EntityHeader, name: string, description: string | null, productId: bigint, isDisabled: boolean, _isSoldLoose: boolean, _itemCode: bigint, _identifiers: ReadonlyArray<PackageIdentifier>, _dimensions: Dimensions | null, _weight: Weight | null, _photos: ReadonlyArray<Photo>);
|
|
16
15
|
get productId(): bigint;
|
|
17
16
|
get isSoldLoose(): boolean;
|
|
18
17
|
get itemCode(): bigint;
|
|
@@ -21,5 +20,10 @@ export default class Package extends Item {
|
|
|
21
20
|
get weight(): Weight | null;
|
|
22
21
|
get photos(): ReadonlyArray<Photo>;
|
|
23
22
|
get price(): Price | null;
|
|
23
|
+
private set price(value);
|
|
24
24
|
get isBuyable(): boolean;
|
|
25
|
+
private _price;
|
|
26
|
+
}
|
|
27
|
+
export interface UpdatablePackage {
|
|
28
|
+
set price(value: Price | null);
|
|
25
29
|
}
|
package/dist/Package.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import Item from "./Item";
|
|
2
2
|
// A package, or variant, of a product (a 500 gram bottle of mango pickle, say) and the thing a
|
|
3
|
-
// customer buys. Built
|
|
3
|
+
// customer buys. Built with its photos. Catalog sets the price, once the price list to sell from is
|
|
4
|
+
// known.
|
|
4
5
|
export default class Package extends Item {
|
|
5
|
-
constructor(header, name, description, productId, isDisabled, _isSoldLoose, _itemCode, _identifiers, _dimensions, _weight, _photos
|
|
6
|
+
constructor(header, name, description, productId, isDisabled, _isSoldLoose, _itemCode, _identifiers, _dimensions, _weight, _photos) {
|
|
6
7
|
super(header, name, description, productId, isDisabled);
|
|
7
8
|
this._isSoldLoose = _isSoldLoose;
|
|
8
9
|
this._itemCode = _itemCode;
|
|
@@ -10,7 +11,7 @@ export default class Package extends Item {
|
|
|
10
11
|
this._dimensions = _dimensions;
|
|
11
12
|
this._weight = _weight;
|
|
12
13
|
this._photos = _photos;
|
|
13
|
-
this._price =
|
|
14
|
+
this._price = null;
|
|
14
15
|
}
|
|
15
16
|
// The product this package is a variant of, which is the parent id every item has
|
|
16
17
|
get productId() {
|
|
@@ -37,11 +38,16 @@ export default class Package extends Item {
|
|
|
37
38
|
get photos() {
|
|
38
39
|
return this._photos;
|
|
39
40
|
}
|
|
40
|
-
// What this package costs, with the taxes of its product included (Product.taxes).
|
|
41
|
-
//
|
|
41
|
+
// What this package costs, with the taxes of its product included (Product.taxes). It is the
|
|
42
|
+
// price in the catalog's sale price list, which can follow that list's parent (see
|
|
43
|
+
// PriceList.getPrice). It is disabled when the package is not in the list. Null when the list gives
|
|
44
|
+
// the package no price, so the package cannot be bought.
|
|
42
45
|
get price() {
|
|
43
46
|
return this._price;
|
|
44
47
|
}
|
|
48
|
+
set price(value) {
|
|
49
|
+
this._price = value;
|
|
50
|
+
}
|
|
45
51
|
// True when this package is enabled and has an enabled price. Checked here because a
|
|
46
52
|
// product-level filter does not guarantee that every package, or every price, of an otherwise
|
|
47
53
|
// visible product is enabled.
|
package/dist/Price.d.ts
CHANGED
|
@@ -4,10 +4,13 @@ export default class Price extends Item {
|
|
|
4
4
|
private readonly _packageId;
|
|
5
5
|
private readonly _regularPrice;
|
|
6
6
|
private readonly _offerPrice;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
private readonly _isPlaceholder;
|
|
8
|
+
static fromScaledValues(header: EntityHeader, name: string, description: string | null, priceListId: bigint, isDisabled: boolean, packageId: bigint, scaledRegularPrice: bigint, scaledOfferPrice: bigint, isPlaceholder?: boolean): Price;
|
|
9
|
+
constructor(header: EntityHeader, name: string, description: string | null, priceListId: bigint, isDisabled: boolean, _packageId: bigint, _regularPrice: number, _offerPrice: number, _isPlaceholder?: boolean);
|
|
9
10
|
get packageId(): bigint;
|
|
10
11
|
get priceListId(): bigint;
|
|
12
|
+
get isPlaceholder(): boolean;
|
|
13
|
+
withIsDisabled(isDisabled: boolean): Price;
|
|
11
14
|
get regularPrice(): number;
|
|
12
15
|
get offerPrice(): number;
|
|
13
16
|
get finalPrice(): number;
|
package/dist/Price.js
CHANGED
|
@@ -9,14 +9,15 @@ import Item from "./Item";
|
|
|
9
9
|
// stores a price without taxes, so a cart takes them out (CartEditor).
|
|
10
10
|
export default class Price extends Item {
|
|
11
11
|
// For ProtoMap, which sees prices still multiplied by Constants.AMOUNT_FACTOR.
|
|
12
|
-
static fromScaledValues(header, name, description, priceListId, isDisabled, packageId, scaledRegularPrice, scaledOfferPrice) {
|
|
13
|
-
return new Price(header, name, description, priceListId, isDisabled, packageId, amountFromScaledValue(scaledRegularPrice), amountFromScaledValue(scaledOfferPrice));
|
|
12
|
+
static fromScaledValues(header, name, description, priceListId, isDisabled, packageId, scaledRegularPrice, scaledOfferPrice, isPlaceholder = false) {
|
|
13
|
+
return new Price(header, name, description, priceListId, isDisabled, packageId, amountFromScaledValue(scaledRegularPrice), amountFromScaledValue(scaledOfferPrice), isPlaceholder);
|
|
14
14
|
}
|
|
15
|
-
constructor(header, name, description, priceListId, isDisabled, _packageId, _regularPrice, _offerPrice) {
|
|
15
|
+
constructor(header, name, description, priceListId, isDisabled, _packageId, _regularPrice, _offerPrice, _isPlaceholder = false) {
|
|
16
16
|
super(header, name, description, priceListId, isDisabled);
|
|
17
17
|
this._packageId = _packageId;
|
|
18
18
|
this._regularPrice = _regularPrice;
|
|
19
19
|
this._offerPrice = _offerPrice;
|
|
20
|
+
this._isPlaceholder = _isPlaceholder;
|
|
20
21
|
}
|
|
21
22
|
// The package this price applies to. Nothing nests on the wire, so this is how the catalog finds
|
|
22
23
|
// the price of a package.
|
|
@@ -27,6 +28,20 @@ export default class Price extends Item {
|
|
|
27
28
|
get priceListId() {
|
|
28
29
|
return this.parentItemId;
|
|
29
30
|
}
|
|
31
|
+
// True when this price has no amounts of its own: the package has the amounts of the price the
|
|
32
|
+
// list's parent has for it. regularPrice and offerPrice are a copy of those, which can be out of
|
|
33
|
+
// date, so they are never used. isDisabled says whether the package is in this list. See
|
|
34
|
+
// PriceList.getPrice, which resolves it. A UI never sees one, because Package.price is never a
|
|
35
|
+
// placeholder.
|
|
36
|
+
get isPlaceholder() {
|
|
37
|
+
return this._isPlaceholder;
|
|
38
|
+
}
|
|
39
|
+
// This price with another enabled state: the same entity, amounts and list. For PriceList.getPrice,
|
|
40
|
+
// which returns a price that is not the one the list holds when the package's state in the list
|
|
41
|
+
// differs from the state of the price that gives its amounts.
|
|
42
|
+
withIsDisabled(isDisabled) {
|
|
43
|
+
return new Price(this.header, this.name, this.description, this.priceListId, isDisabled, this._packageId, this._regularPrice, this._offerPrice, this._isPlaceholder);
|
|
44
|
+
}
|
|
30
45
|
get regularPrice() {
|
|
31
46
|
return this._regularPrice;
|
|
32
47
|
}
|
package/dist/PriceList.d.ts
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
1
|
import Item from "./Item";
|
|
2
|
+
import Price from "./Price";
|
|
2
3
|
export default class PriceList extends Item {
|
|
4
|
+
get parentPriceListId(): bigint;
|
|
5
|
+
get parentPriceList(): PriceList | null;
|
|
6
|
+
private set parentPriceList(value);
|
|
7
|
+
get prices(): ReadonlyMap<bigint, Price>;
|
|
8
|
+
private set prices(value);
|
|
9
|
+
getPrice(packageId: bigint): Price | null;
|
|
10
|
+
private _parentPriceList;
|
|
11
|
+
private _prices;
|
|
12
|
+
}
|
|
13
|
+
export interface UpdatablePriceList {
|
|
14
|
+
set parentPriceList(value: PriceList | null);
|
|
15
|
+
set prices(value: ReadonlyMap<bigint, Price>);
|
|
3
16
|
}
|
package/dist/PriceList.js
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
import Item from "./Item";
|
|
2
|
-
// A named list of prices
|
|
3
|
-
//
|
|
2
|
+
// A named list of prices, at most one per package. A list can have a parent, named by its
|
|
3
|
+
// parentItemId, and gets the amounts of some packages from it. See getPrice for the rules. Catalog
|
|
4
|
+
// sets the prices and the parent, once every price list and price has been read.
|
|
4
5
|
export default class PriceList extends Item {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this._parentPriceList = null;
|
|
9
|
+
this._prices = new Map();
|
|
10
|
+
}
|
|
11
|
+
// The id of the list whose prices give the amounts of the packages this list takes them from it
|
|
12
|
+
// for, or Constants.ENTITY_ID_NULL when this list has no parent
|
|
13
|
+
get parentPriceListId() {
|
|
14
|
+
return this.parentItemId;
|
|
15
|
+
}
|
|
16
|
+
// Null when this list has no parent, or when the parent was not read. Not Entity.parent, which is
|
|
17
|
+
// the business.
|
|
18
|
+
get parentPriceList() {
|
|
19
|
+
return this._parentPriceList;
|
|
20
|
+
}
|
|
21
|
+
set parentPriceList(value) {
|
|
22
|
+
this._parentPriceList = value;
|
|
23
|
+
}
|
|
24
|
+
// The prices of this list itself, by package id. getPrice also looks in the parent.
|
|
25
|
+
get prices() {
|
|
26
|
+
return this._prices;
|
|
27
|
+
}
|
|
28
|
+
set prices(value) {
|
|
29
|
+
this._prices = value;
|
|
30
|
+
}
|
|
31
|
+
// The price of a package in this list, or null when the list gives it none. Only the parent is
|
|
32
|
+
// consulted, not its parent.
|
|
33
|
+
// - A list follows its parent. A package the list has no price for has the parent's price, so its
|
|
34
|
+
// amounts and whether it is enabled.
|
|
35
|
+
// - A price of this list replaces the parent's price, both amounts and enabled state.
|
|
36
|
+
// - A placeholder replaces only the enabled state. The amounts are the parent's. The placeholder
|
|
37
|
+
// holds a copy of them that can be out of date, so it is never used.
|
|
38
|
+
// - The package is in the list when the price returned is enabled.
|
|
39
|
+
// - A placeholder gives no price when the parent has none.
|
|
40
|
+
// The price returned is the one that gives the amounts when it already has the right state, and a
|
|
41
|
+
// copy of it with the right state (withIsDisabled) otherwise.
|
|
42
|
+
getPrice(packageId) {
|
|
43
|
+
const ownPrice = this._prices.get(packageId);
|
|
44
|
+
if (ownPrice !== undefined && !ownPrice.isPlaceholder)
|
|
45
|
+
return ownPrice;
|
|
46
|
+
const parentPrice = this._parentPriceList?._prices.get(packageId);
|
|
47
|
+
if (parentPrice === undefined)
|
|
48
|
+
return null;
|
|
49
|
+
if (ownPrice === undefined || ownPrice.isDisabled === parentPrice.isDisabled)
|
|
50
|
+
return parentPrice;
|
|
51
|
+
return parentPrice.withIsDisabled(ownPrice.isDisabled);
|
|
52
|
+
}
|
|
5
53
|
}
|
package/dist/Product.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export default class Product extends Item {
|
|
|
16
16
|
private readonly _features;
|
|
17
17
|
private readonly _isForOfflineSaleOnly;
|
|
18
18
|
private readonly _photos;
|
|
19
|
-
constructor(header: EntityHeader, name: string, description: string | null, productCategoryId: bigint, isDisabled: boolean, _productType: proto_ProductType, _brand: string | null, _isManufacturedByBusiness: boolean, _manufacturer: string | null, _manufacturerAddress: Address | null, _taxes: ReadonlyArray<Tax>, _features: ReadonlyArray<string>, _isForOfflineSaleOnly: boolean, _photos: ReadonlyArray<Photo
|
|
19
|
+
constructor(header: EntityHeader, name: string, description: string | null, productCategoryId: bigint, isDisabled: boolean, _productType: proto_ProductType, _brand: string | null, _isManufacturedByBusiness: boolean, _manufacturer: string | null, _manufacturerAddress: Address | null, _taxes: ReadonlyArray<Tax>, _features: ReadonlyArray<string>, _isForOfflineSaleOnly: boolean, _photos: ReadonlyArray<Photo>);
|
|
20
20
|
get productCategoryId(): bigint;
|
|
21
21
|
get productType(): proto_ProductType;
|
|
22
22
|
get brand(): string | null;
|
|
@@ -28,8 +28,12 @@ export default class Product extends Item {
|
|
|
28
28
|
get isForOfflineSaleOnly(): boolean;
|
|
29
29
|
get photos(): ReadonlyArray<Photo>;
|
|
30
30
|
get packages(): ReadonlyArray<Package>;
|
|
31
|
+
private set packages(value);
|
|
31
32
|
get lowestPrice(): Price | null;
|
|
32
33
|
get isOnOffer(): boolean;
|
|
33
34
|
get isBuyable(): boolean;
|
|
34
|
-
private
|
|
35
|
+
private _packages;
|
|
36
|
+
}
|
|
37
|
+
export interface UpdatableProduct {
|
|
38
|
+
set packages(value: ReadonlyArray<Package>);
|
|
35
39
|
}
|