@sixtyninecommerce/admin 0.10.0 → 0.12.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/README.md +5772 -118
- package/dist/auth/index.d.ts +7 -1
- package/dist/auth/index.js +8 -1
- package/dist/catalog/assets.d.ts +120 -8
- package/dist/catalog/assets.js +98 -12
- package/dist/catalog/collections.d.ts +279 -14
- package/dist/catalog/collections.js +246 -15
- package/dist/catalog/documents.d.ts +142 -0
- package/dist/catalog/documents.js +114 -0
- package/dist/catalog/index.d.ts +54 -6
- package/dist/catalog/index.js +10 -1
- package/dist/catalog/metadata.d.ts +244 -0
- package/dist/catalog/metadata.js +220 -0
- package/dist/catalog/products.d.ts +159 -19
- package/dist/catalog/products.js +88 -13
- package/dist/catalog/properties.d.ts +140 -14
- package/dist/catalog/properties.js +65 -1
- package/dist/catalog/recommendations.d.ts +288 -0
- package/dist/catalog/recommendations.js +237 -0
- package/dist/catalog/reviews.d.ts +381 -0
- package/dist/catalog/reviews.js +325 -0
- package/dist/catalog/types.d.ts +17 -1
- package/dist/catalog/types.js +10 -0
- package/dist/catalog/variant-find.d.ts +136 -0
- package/dist/catalog/variant-find.js +239 -0
- package/dist/catalog/variants.d.ts +293 -26
- package/dist/catalog/variants.js +164 -7
- package/dist/catalog/visibility.d.ts +38 -7
- package/dist/catalog/visibility.js +19 -1
- package/dist/client.d.ts +121 -9
- package/dist/client.js +53 -14
- package/dist/content/assets.d.ts +285 -0
- package/dist/content/assets.js +181 -0
- package/dist/content/forms.d.ts +332 -1
- package/dist/content/forms.js +140 -4
- package/dist/content/items.d.ts +292 -0
- package/dist/content/items.js +170 -0
- package/dist/content/menus.d.ts +254 -0
- package/dist/content/menus.js +70 -0
- package/dist/content/strings.d.ts +137 -0
- package/dist/content/strings.js +82 -0
- package/dist/content/types.d.ts +282 -0
- package/dist/content/types.js +100 -0
- package/dist/customers/age-verification.d.ts +66 -0
- package/dist/customers/age-verification.js +79 -0
- package/dist/customers/credit.d.ts +263 -0
- package/dist/customers/credit.js +244 -0
- package/dist/customers/delivery-preferences.d.ts +120 -0
- package/dist/customers/delivery-preferences.js +97 -0
- package/dist/customers/delivery-terms.d.ts +44 -0
- package/dist/customers/delivery-terms.js +32 -0
- package/dist/customers/groups.d.ts +207 -0
- package/dist/customers/groups.js +438 -0
- package/dist/customers/index.d.ts +462 -37
- package/dist/customers/index.js +317 -40
- package/dist/customers/invitation-status.d.ts +57 -0
- package/dist/customers/invitation-status.js +21 -0
- package/dist/customers/notes.d.ts +67 -0
- package/dist/customers/notes.js +51 -0
- package/dist/customers/notification-recipients.d.ts +97 -0
- package/dist/customers/notification-recipients.js +84 -0
- package/dist/customers/saved-lists.d.ts +42 -0
- package/dist/customers/saved-lists.js +61 -0
- package/dist/customers/vat.d.ts +83 -0
- package/dist/customers/vat.js +46 -0
- package/dist/customers/wire.d.ts +20 -0
- package/dist/customers/wire.js +35 -0
- package/dist/documents/ar.d.ts +307 -0
- package/dist/documents/ar.js +254 -0
- package/dist/documents/emails.d.ts +150 -0
- package/dist/documents/emails.js +220 -0
- package/dist/documents/index.d.ts +744 -21
- package/dist/documents/index.js +438 -24
- package/dist/documents/pdf.d.ts +2 -0
- package/dist/documents/pdf.js +11 -0
- package/dist/fulfillments/create.d.ts +167 -0
- package/dist/fulfillments/create.js +216 -0
- package/dist/fulfillments/index.d.ts +163 -11
- package/dist/fulfillments/index.js +135 -6
- package/dist/fulfillments/payment-policy.d.ts +64 -0
- package/dist/fulfillments/payment-policy.js +140 -0
- package/dist/fulfillments/warehouse.d.ts +724 -0
- package/dist/fulfillments/warehouse.js +914 -0
- package/dist/geo/index.d.ts +119 -0
- package/dist/geo/index.js +107 -0
- package/dist/index.d.ts +147 -39
- package/dist/index.js +51 -12
- package/dist/integrations/afas-actions.d.ts +234 -0
- package/dist/integrations/afas-actions.js +310 -0
- package/dist/integrations/afas-types.d.ts +483 -0
- package/dist/integrations/afas-types.js +5 -0
- package/dist/integrations/afas.d.ts +234 -0
- package/dist/integrations/afas.js +290 -0
- package/dist/integrations/connections.d.ts +103 -0
- package/dist/integrations/connections.js +55 -0
- package/dist/integrations/esp.d.ts +313 -0
- package/dist/integrations/esp.js +169 -0
- package/dist/integrations/exact-online-types.d.ts +965 -0
- package/dist/integrations/exact-online-types.js +6 -0
- package/dist/integrations/exact-online.d.ts +784 -0
- package/dist/integrations/exact-online.js +1089 -0
- package/dist/integrations/index.d.ts +44 -3
- package/dist/integrations/index.js +23 -3
- package/dist/integrations/pipeline-discoveries.d.ts +65 -0
- package/dist/integrations/pipeline-discoveries.js +65 -0
- package/dist/integrations/pipeline-keys.d.ts +13 -0
- package/dist/integrations/pipeline-keys.js +22 -0
- package/dist/integrations/pipeline-runs.d.ts +119 -0
- package/dist/integrations/pipeline-runs.js +87 -0
- package/dist/integrations/pipelines.d.ts +87 -15
- package/dist/integrations/pipelines.js +41 -22
- package/dist/integrations/price-import.d.ts +223 -0
- package/dist/integrations/price-import.js +124 -0
- package/dist/integrations/types.d.ts +367 -3
- package/dist/integrations/types.js +4 -3
- package/dist/locations/index.d.ts +66 -0
- package/dist/locations/index.js +31 -0
- package/dist/meta/index.d.ts +172 -0
- package/dist/metafields/index.d.ts +8 -1
- package/dist/metafields/index.js +10 -0
- package/dist/orders/cancel-with-money.d.ts +237 -0
- package/dist/orders/cancel-with-money.js +155 -0
- package/dist/orders/commit-edit.d.ts +23 -1
- package/dist/orders/commit-edit.js +19 -2
- package/dist/orders/deposit-policy.d.ts +3 -1
- package/dist/orders/drafts.d.ts +800 -0
- package/dist/orders/drafts.js +771 -0
- package/dist/orders/fields.d.ts +245 -0
- package/dist/orders/fields.js +188 -0
- package/dist/orders/get.d.ts +29 -19
- package/dist/orders/get.js +17 -8
- package/dist/orders/index.d.ts +66 -15
- package/dist/orders/index.js +25 -2
- package/dist/orders/lifecycle.d.ts +128 -0
- package/dist/orders/lifecycle.js +158 -0
- package/dist/orders/line-price-preview.d.ts +7 -2
- package/dist/orders/list.d.ts +243 -0
- package/dist/orders/list.js +487 -0
- package/dist/orders/manual-discounts.d.ts +13 -5
- package/dist/orders/manual-pricing.d.ts +5 -0
- package/dist/orders/money-view.d.ts +149 -0
- package/dist/orders/money-view.js +99 -0
- package/dist/orders/order-entry.d.ts +20 -7
- package/dist/orders/plan-edit.d.ts +34 -2
- package/dist/orders/plan-edit.js +112 -11
- package/dist/orders/settings.d.ts +201 -0
- package/dist/orders/settings.js +325 -0
- package/dist/orders/status.d.ts +159 -13
- package/dist/orders/status.js +21 -0
- package/dist/orders/surcharges.d.ts +20 -1
- package/dist/orders/surcharges.js +37 -11
- package/dist/payments/account-credit.d.ts +46 -0
- package/dist/payments/account-credit.js +42 -0
- package/dist/payments/ar.d.ts +292 -0
- package/dist/payments/ar.js +223 -0
- package/dist/payments/connected-account.d.ts +47 -0
- package/dist/payments/connected-account.js +61 -0
- package/dist/payments/credit-noted-fields.d.ts +19 -0
- package/dist/payments/credit-noted-fields.js +69 -0
- package/dist/payments/customer-consent.d.ts +30 -0
- package/dist/payments/customer-consent.js +49 -0
- package/dist/payments/index.d.ts +340 -19
- package/dist/payments/index.js +151 -1
- package/dist/payments/methods.d.ts +303 -8
- package/dist/payments/methods.js +337 -7
- package/dist/payments/mollie-methods.d.ts +159 -0
- package/dist/payments/mollie-methods.js +141 -0
- package/dist/payments/payment-links.d.ts +180 -0
- package/dist/payments/payment-links.js +97 -0
- package/dist/payments/provider-keys.d.ts +150 -0
- package/dist/payments/provider-keys.js +118 -0
- package/dist/payments/providers.d.ts +86 -11
- package/dist/payments/providers.js +29 -0
- package/dist/payments/requests.d.ts +147 -0
- package/dist/payments/requests.js +93 -0
- package/dist/payments/store-credit-fields.d.ts +15 -0
- package/dist/payments/store-credit-fields.js +51 -0
- package/dist/pickups/index.d.ts +106 -0
- package/dist/pickups/index.js +108 -0
- package/dist/platform/channels.d.ts +132 -0
- package/dist/platform/channels.js +128 -0
- package/dist/platform/email-gateways.d.ts +165 -0
- package/dist/platform/email-gateways.js +78 -0
- package/dist/platform/geo.d.ts +123 -0
- package/dist/platform/geo.js +144 -0
- package/dist/platform/tax.d.ts +162 -0
- package/dist/platform/tax.js +169 -0
- package/dist/pos/anomalies.d.ts +158 -0
- package/dist/pos/anomalies.js +64 -0
- package/dist/pos/assisted-selling.d.ts +79 -0
- package/dist/pos/assisted-selling.js +38 -0
- package/dist/pos/exchanges.d.ts +108 -0
- package/dist/pos/exchanges.js +22 -0
- package/dist/pos/gift-cards.d.ts +135 -0
- package/dist/pos/gift-cards.js +47 -0
- package/dist/pos/index.d.ts +2370 -58
- package/dist/pos/index.js +854 -7
- package/dist/pos/no-receipt.d.ts +94 -0
- package/dist/pos/no-receipt.js +25 -0
- package/dist/pos/offline-sales.d.ts +228 -0
- package/dist/pos/offline-sales.js +170 -0
- package/dist/pos/pay-by-link.d.ts +143 -0
- package/dist/pos/pay-by-link.js +57 -0
- package/dist/pos/quick-keys.d.ts +103 -0
- package/dist/pos/quick-keys.js +45 -0
- package/dist/pos/reports.d.ts +360 -0
- package/dist/pos/reports.js +62 -0
- package/dist/pos/returns.d.ts +244 -0
- package/dist/pos/returns.js +83 -0
- package/dist/pricing/bulk-coupons.d.ts +139 -0
- package/dist/pricing/bulk-coupons.js +112 -0
- package/dist/pricing/index.d.ts +174 -4
- package/dist/pricing/index.js +174 -1
- package/dist/pricing/price-lists.d.ts +606 -0
- package/dist/pricing/price-lists.js +600 -0
- package/dist/purchasing/alerts.d.ts +104 -0
- package/dist/purchasing/alerts.js +88 -0
- package/dist/purchasing/backorders.d.ts +61 -0
- package/dist/purchasing/backorders.js +92 -0
- package/dist/purchasing/cost.d.ts +110 -0
- package/dist/purchasing/cost.js +86 -0
- package/dist/purchasing/index.d.ts +54 -0
- package/dist/purchasing/index.js +24 -0
- package/dist/purchasing/links.d.ts +263 -0
- package/dist/purchasing/links.js +192 -0
- package/dist/purchasing/purchase-orders.d.ts +551 -0
- package/dist/purchasing/purchase-orders.js +491 -0
- package/dist/purchasing/receipts.d.ts +396 -0
- package/dist/purchasing/receipts.js +287 -0
- package/dist/purchasing/replenishment.d.ts +281 -0
- package/dist/purchasing/replenishment.js +240 -0
- package/dist/purchasing/returns.d.ts +273 -0
- package/dist/purchasing/returns.js +229 -0
- package/dist/purchasing/settings.d.ts +152 -0
- package/dist/purchasing/settings.js +181 -0
- package/dist/purchasing/suppliers.d.ts +476 -0
- package/dist/purchasing/suppliers.js +438 -0
- package/dist/quotes/index.d.ts +518 -0
- package/dist/quotes/index.js +439 -0
- package/dist/reports/index.d.ts +71 -8
- package/dist/reports/index.js +74 -11
- package/dist/returns/index.d.ts +675 -21
- package/dist/returns/index.js +756 -11
- package/dist/search/index.d.ts +76 -1
- package/dist/search/index.js +63 -0
- package/dist/seo/config.d.ts +128 -0
- package/dist/seo/config.js +95 -0
- package/dist/seo/redirects.d.ts +125 -0
- package/dist/seo/redirects.js +60 -1
- package/dist/seo/settings.d.ts +147 -0
- package/dist/seo/settings.js +209 -0
- package/dist/shipping/definitions.d.ts +29 -0
- package/dist/shipping/definitions.js +47 -0
- package/dist/shipping/fulfillment-profiles.d.ts +174 -0
- package/dist/shipping/fulfillment-profiles.js +104 -0
- package/dist/shipping/hendriks.d.ts +97 -0
- package/dist/shipping/hendriks.js +50 -0
- package/dist/shipping/index.d.ts +54 -0
- package/dist/shipping/index.js +27 -0
- package/dist/shipping/methods.d.ts +205 -0
- package/dist/shipping/methods.js +240 -0
- package/dist/shipping/myparcel.d.ts +668 -0
- package/dist/shipping/myparcel.js +466 -0
- package/dist/shipping/parcel-count-suggestion.d.ts +2 -0
- package/dist/shipping/parcel-rule.d.ts +6 -5
- package/dist/shipping/parcel-rule.js +21 -23
- package/dist/shipping/rate-tables.d.ts +324 -0
- package/dist/shipping/rate-tables.js +390 -0
- package/dist/shipping/ship-to-countries.d.ts +75 -0
- package/dist/shipping/ship-to-countries.js +47 -0
- package/dist/stock/by-location.d.ts +86 -0
- package/dist/stock/by-location.js +94 -0
- package/dist/stock/index.d.ts +18 -4
- package/dist/stock/index.js +7 -0
- package/dist/stock/locations.d.ts +144 -0
- package/dist/stock/locations.js +168 -0
- package/dist/stock/settings.d.ts +106 -0
- package/dist/stock/settings.js +103 -0
- package/dist/stock/transfers.d.ts +386 -52
- package/dist/stock/transfers.js +222 -17
- package/dist/stored-value/index.d.ts +312 -11
- package/dist/stored-value/index.js +223 -4
- package/dist/subscriptions/index.d.ts +682 -0
- package/dist/subscriptions/index.js +815 -0
- package/dist/tax/display-policy.d.ts +105 -0
- package/dist/tax/display-policy.js +84 -0
- package/dist/tax/index.d.ts +79 -1
- package/dist/tax/index.js +52 -0
- package/dist/tenant/email-style.d.ts +102 -0
- package/dist/tenant/email-style.js +72 -0
- package/dist/tenant/email-templates.d.ts +287 -0
- package/dist/tenant/email-templates.js +271 -0
- package/dist/tenant/notifications.d.ts +23 -17
- package/dist/tenant/settings-sources.d.ts +1 -1
- package/dist/tenant/time-zone.d.ts +17 -0
- package/dist/tenant/time-zone.js +11 -0
- package/dist/types.d.ts +50 -3
- package/dist/users/index.d.ts +3 -0
- package/dist/users/index.js +2 -0
- package/dist/users/warehouses.d.ts +50 -0
- package/dist/users/warehouses.js +51 -0
- package/package.json +2 -2
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { pageFromVendureList, readOffsetCursor, } from '@sixtyninecommerce/core';
|
|
2
|
+
export const STOCK_LEVELS_AT_LOCATION_QUERY = /* GraphQL */ `
|
|
3
|
+
query StockLevelsAtLocation($locationId: ID!, $options: StockLevelListOptions) {
|
|
4
|
+
stockLevelsByLocation(locationId: $locationId, options: $options) {
|
|
5
|
+
items {
|
|
6
|
+
id
|
|
7
|
+
stockOnHand
|
|
8
|
+
stockAllocated
|
|
9
|
+
updatedAt
|
|
10
|
+
productVariant {
|
|
11
|
+
id
|
|
12
|
+
name
|
|
13
|
+
sku
|
|
14
|
+
product { id name featuredAsset { id preview } }
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
totalItems
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
`;
|
|
21
|
+
export const STOCK_MOVEMENTS_AT_LOCATION_QUERY = /* GraphQL */ `
|
|
22
|
+
query StockMovementsAtLocation($locationId: ID!, $options: StockMovementListOptions) {
|
|
23
|
+
stockMovementsByLocation(locationId: $locationId, options: $options) {
|
|
24
|
+
items {
|
|
25
|
+
id
|
|
26
|
+
createdAt
|
|
27
|
+
type
|
|
28
|
+
quantity
|
|
29
|
+
productVariant { id name sku }
|
|
30
|
+
orderLine { order { id code } }
|
|
31
|
+
}
|
|
32
|
+
totalItems
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
const toLevel = ({ productVariant, ...level }) => ({
|
|
37
|
+
id: level.id,
|
|
38
|
+
variantId: productVariant.id,
|
|
39
|
+
sku: productVariant.sku,
|
|
40
|
+
variantName: productVariant.name,
|
|
41
|
+
product: {
|
|
42
|
+
id: productVariant.product.id,
|
|
43
|
+
name: productVariant.product.name,
|
|
44
|
+
featuredAsset: productVariant.product.featuredAsset ?? null,
|
|
45
|
+
},
|
|
46
|
+
onHand: level.stockOnHand,
|
|
47
|
+
allocated: level.stockAllocated,
|
|
48
|
+
updatedAt: level.updatedAt,
|
|
49
|
+
});
|
|
50
|
+
const toMovement = ({ productVariant, orderLine, ...movement }) => ({
|
|
51
|
+
...movement,
|
|
52
|
+
variantId: productVariant.id,
|
|
53
|
+
sku: productVariant.sku,
|
|
54
|
+
variantName: productVariant.name,
|
|
55
|
+
order: orderLine?.order ?? null,
|
|
56
|
+
});
|
|
57
|
+
const DEFAULT_PAGE_SIZE = 25;
|
|
58
|
+
const firstSkip = (filter) => filter?.after === undefined ? 0 : readOffsetCursor(filter.after);
|
|
59
|
+
export function createStockByLocationReads(transport) {
|
|
60
|
+
const levelsPage = async (locationId, skip, take, filter) => {
|
|
61
|
+
const search = filter?.search?.trim();
|
|
62
|
+
const data = await transport.graphql({
|
|
63
|
+
api: 'admin',
|
|
64
|
+
query: STOCK_LEVELS_AT_LOCATION_QUERY,
|
|
65
|
+
variables: {
|
|
66
|
+
locationId,
|
|
67
|
+
options: { skip, take, sort: filter?.sort ?? 'DESC', ...(search ? { search } : {}) },
|
|
68
|
+
},
|
|
69
|
+
}, filter);
|
|
70
|
+
return pageFromVendureList({
|
|
71
|
+
items: data.stockLevelsByLocation.items.map(toLevel),
|
|
72
|
+
totalItems: data.stockLevelsByLocation.totalItems,
|
|
73
|
+
}, skip, take, (cursor) => levelsPage(locationId, readOffsetCursor(cursor), take, filter));
|
|
74
|
+
};
|
|
75
|
+
const movementsPage = async (locationId, skip, take, filter) => {
|
|
76
|
+
const data = await transport.graphql({
|
|
77
|
+
api: 'admin',
|
|
78
|
+
query: STOCK_MOVEMENTS_AT_LOCATION_QUERY,
|
|
79
|
+
variables: { locationId, options: { skip, take } },
|
|
80
|
+
}, filter);
|
|
81
|
+
return pageFromVendureList({
|
|
82
|
+
items: data.stockMovementsByLocation.items.map(toMovement),
|
|
83
|
+
totalItems: data.stockMovementsByLocation.totalItems,
|
|
84
|
+
}, skip, take, (cursor) => movementsPage(locationId, readOffsetCursor(cursor), take, filter));
|
|
85
|
+
};
|
|
86
|
+
return {
|
|
87
|
+
levelsAt(locationId, filter) {
|
|
88
|
+
return levelsPage(locationId, firstSkip(filter), filter?.limit ?? DEFAULT_PAGE_SIZE, filter);
|
|
89
|
+
},
|
|
90
|
+
movementsAt(locationId, filter) {
|
|
91
|
+
return movementsPage(locationId, firstSkip(filter), filter?.limit ?? DEFAULT_PAGE_SIZE, filter);
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
package/dist/stock/index.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { type Page, type Transport } from '@sixtyninecommerce/core';
|
|
2
2
|
import type { Call, ListOptions } from '../types.js';
|
|
3
|
+
import { type StockByLocationReads } from './by-location.js';
|
|
4
|
+
import { type StockLocationsModule } from './locations.js';
|
|
5
|
+
import { type StockSettingsModule } from './settings.js';
|
|
3
6
|
import { type StockTransfersModule } from './transfers.js';
|
|
4
7
|
/**
|
|
5
8
|
* One variant's stock at one location, in integer units.
|
|
@@ -14,7 +17,10 @@ import { type StockTransfersModule } from './transfers.js';
|
|
|
14
17
|
* allocates past on-hand, and that shortfall shows as a negative figure. A
|
|
15
18
|
* negative threshold (an oversell allowance) raises it above
|
|
16
19
|
* `onHand − allocated`.
|
|
17
|
-
* - `incoming` — open units expected at this location (purchase orders)
|
|
20
|
+
* - `incoming` — open units expected at this location (purchase orders), customer-facing: a
|
|
21
|
+
* purchase order counts only what its supplier confirmed.
|
|
22
|
+
* - `onOrder` — units ordered from suppliers and still to come at this location, confirmed or
|
|
23
|
+
* not: the remainders of sent purchase orders plus the open lines an ERP mirrors. Internal.
|
|
18
24
|
* - `trackInventory: false` — the variant does not track stock, so none of
|
|
19
25
|
* these figures gates a sale.
|
|
20
26
|
*/
|
|
@@ -25,6 +31,7 @@ export interface StockPosition {
|
|
|
25
31
|
allocated: number;
|
|
26
32
|
available: number;
|
|
27
33
|
incoming: number;
|
|
34
|
+
onOrder: number;
|
|
28
35
|
reserved: number;
|
|
29
36
|
trackInventory: boolean;
|
|
30
37
|
}
|
|
@@ -128,7 +135,7 @@ export interface StockAllocationsModule {
|
|
|
128
135
|
* narrowed to that list instead); `STOCK_LOCATION_REQUIRED` and
|
|
129
136
|
* `STOCK_WOULD_GO_NEGATIVE` (→ `BusinessRuleError`).
|
|
130
137
|
*/
|
|
131
|
-
export interface StockModule {
|
|
138
|
+
export interface StockModule extends StockByLocationReads {
|
|
132
139
|
/** The variant's stock at every location of this store (or one). A location that never held it has no entry. */
|
|
133
140
|
position(variantId: string, options?: StockPositionOptions): Promise<StockPosition[]>;
|
|
134
141
|
/** The variant's ledger at this store's locations, with each movement's reason. */
|
|
@@ -158,9 +165,16 @@ export interface StockModule {
|
|
|
158
165
|
/** Stock transfers between this store's locations, and consumptions at one. */
|
|
159
166
|
transfers: StockTransfersModule;
|
|
160
167
|
allocations: StockAllocationsModule;
|
|
168
|
+
/** The store's stock locations themselves: list, read, create, change, delete. */
|
|
169
|
+
locations: StockLocationsModule;
|
|
170
|
+
/**
|
|
171
|
+
* The store's stock settings as the engine reads them, saved or previewed: tracking, the
|
|
172
|
+
* threshold, exposure to the storefront, the storefront warehouses and the backorder default.
|
|
173
|
+
*/
|
|
174
|
+
settings: StockSettingsModule;
|
|
161
175
|
}
|
|
162
|
-
export declare const STOCK_POSITION_QUERY = "\n query StockPosition($variantId: ID!, $locationId: ID) {\n stockPosition(variantId: $variantId, locationId: $locationId) { \n locationId\n locationName\n onHand\n allocated\n available\n incoming\n reserved\n trackInventory\n }\n }\n";
|
|
176
|
+
export declare const STOCK_POSITION_QUERY = "\n query StockPosition($variantId: ID!, $locationId: ID) {\n stockPosition(variantId: $variantId, locationId: $locationId) { \n locationId\n locationName\n onHand\n allocated\n available\n incoming\n onOrder\n reserved\n trackInventory\n }\n }\n";
|
|
163
177
|
export declare const STOCK_MOVEMENTS_QUERY: string;
|
|
164
|
-
export declare const ADJUST_STOCK_MUTATION = "\n mutation AdjustStock($input: AdjustStockInput!, $idempotencyKey: String) {\n adjustStock(input: $input, idempotencyKey: $idempotencyKey) { \n locationId\n locationName\n onHand\n allocated\n available\n incoming\n reserved\n trackInventory\n }\n }\n";
|
|
178
|
+
export declare const ADJUST_STOCK_MUTATION = "\n mutation AdjustStock($input: AdjustStockInput!, $idempotencyKey: String) {\n adjustStock(input: $input, idempotencyKey: $idempotencyKey) { \n locationId\n locationName\n onHand\n allocated\n available\n incoming\n onOrder\n reserved\n trackInventory\n }\n }\n";
|
|
165
179
|
export declare const RELEASE_ORDER_ALLOCATION_MUTATION = "\n mutation ReleaseOrderAllocation($orderId: ID!) {\n releaseOrderAllocation(orderId: $orderId) {\n __typename\n ... on ReleaseOrderAllocationSuccess { orderId releasedQuantity }\n ... on ErrorResult { errorCode message }\n }\n }\n";
|
|
166
180
|
export declare function createStockModule(transport: Transport): StockModule;
|
package/dist/stock/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { errorFromErrorResult, isErrorResult, pageFromVendureList, readOffsetCursor, } from '@sixtyninecommerce/core';
|
|
2
|
+
import { createStockByLocationReads } from './by-location.js';
|
|
3
|
+
import { createStockLocationsModule } from './locations.js';
|
|
4
|
+
import { createStockSettingsModule } from './settings.js';
|
|
2
5
|
import { createStockTransfersModule } from './transfers.js';
|
|
3
6
|
const POSITION_FIELDS = /* GraphQL */ `
|
|
4
7
|
locationId
|
|
@@ -7,6 +10,7 @@ const POSITION_FIELDS = /* GraphQL */ `
|
|
|
7
10
|
allocated
|
|
8
11
|
available
|
|
9
12
|
incoming
|
|
13
|
+
onOrder
|
|
10
14
|
reserved
|
|
11
15
|
trackInventory
|
|
12
16
|
`;
|
|
@@ -101,6 +105,9 @@ export function createStockModule(transport) {
|
|
|
101
105
|
return data.adjustStock;
|
|
102
106
|
},
|
|
103
107
|
transfers: createStockTransfersModule(transport),
|
|
108
|
+
locations: createStockLocationsModule(transport),
|
|
109
|
+
settings: createStockSettingsModule(transport),
|
|
110
|
+
...createStockByLocationReads(transport),
|
|
104
111
|
allocations: {
|
|
105
112
|
async release(orderId, options) {
|
|
106
113
|
const data = await transport.graphql({ api: 'admin', query: RELEASE_ORDER_ALLOCATION_MUTATION, variables: { orderId } }, options);
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { type Page, type Transport } from '@sixtyninecommerce/core';
|
|
2
|
+
import type { Call, ListOptions } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* One stock location (warehouse, shop, back room) of the store the client is on.
|
|
5
|
+
*
|
|
6
|
+
* The parcel sender (`address`, the default sender) is not here: it has its own door
|
|
7
|
+
* (`locations.upsert` for the address, MyParcel's sender card for the default), with rules
|
|
8
|
+
* these methods cannot apply.
|
|
9
|
+
*/
|
|
10
|
+
export interface StockLocation {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
/** Empty when none was given. */
|
|
14
|
+
description: string;
|
|
15
|
+
/** ISO 8601, UTC. */
|
|
16
|
+
createdAt: string;
|
|
17
|
+
/** ISO 8601, UTC. */
|
|
18
|
+
updatedAt: string;
|
|
19
|
+
/**
|
|
20
|
+
* Whether shoppers see this location's stock (the Shop API's per-variant availability). True
|
|
21
|
+
* unless set off, for a back room or a staging area.
|
|
22
|
+
*/
|
|
23
|
+
isPublic: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* This location's own out-of-stock threshold, in units: non-zero replaces the variant's (or the
|
|
26
|
+
* store's) threshold for stock held here. Negative lets it sell that many below zero, positive
|
|
27
|
+
* holds a buffer back from sale; 0 uses the variant's or the store's.
|
|
28
|
+
*/
|
|
29
|
+
outOfStockThreshold: number;
|
|
30
|
+
}
|
|
31
|
+
/** The fields a list can be sorted by. */
|
|
32
|
+
export declare const STOCK_LOCATION_SORT_FIELDS: readonly ["name", "createdAt", "updatedAt"];
|
|
33
|
+
export type StockLocationSortField = (typeof STOCK_LOCATION_SORT_FIELDS)[number];
|
|
34
|
+
export interface StockLocationListOptions extends ListOptions {
|
|
35
|
+
/**
|
|
36
|
+
* Locations whose name OR description contains this, ignoring case (the engine's list filter;
|
|
37
|
+
* the search index is not used). Blank or omitted: every location.
|
|
38
|
+
*/
|
|
39
|
+
term?: string;
|
|
40
|
+
/** One key. Omitted: the engine's own order. */
|
|
41
|
+
sort?: {
|
|
42
|
+
field: StockLocationSortField;
|
|
43
|
+
direction: 'ASC' | 'DESC';
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export interface CreateStockLocationInput {
|
|
47
|
+
name: string;
|
|
48
|
+
description?: string;
|
|
49
|
+
/** On (shoppers see its stock) when omitted. */
|
|
50
|
+
isPublic?: boolean;
|
|
51
|
+
/** 0 (use the variant's or the store's threshold) when omitted. */
|
|
52
|
+
outOfStockThreshold?: number;
|
|
53
|
+
}
|
|
54
|
+
/** A PATCH: an absent field keeps what the location has. */
|
|
55
|
+
export interface UpdateStockLocationInput {
|
|
56
|
+
name?: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
isPublic?: boolean;
|
|
59
|
+
outOfStockThreshold?: number;
|
|
60
|
+
}
|
|
61
|
+
export interface DeleteStockLocationOptions extends Call {
|
|
62
|
+
/**
|
|
63
|
+
* Another location of this store that takes over the deleted location's stock levels. Omitted:
|
|
64
|
+
* the levels go with the location.
|
|
65
|
+
*/
|
|
66
|
+
transferToLocationId?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* `admin.stock.locations`: the store's stock locations themselves (spec §9.2 `stock`, §8.7). A
|
|
70
|
+
* location's profile (code, time zone, opening hours, address) is `admin.locations`; its pickup
|
|
71
|
+
* settings are `admin.locations.pickup`.
|
|
72
|
+
*
|
|
73
|
+
* Scoped to the store the client is on: another store's location is not listed, `get` answers
|
|
74
|
+
* `null` for it, and `update`/`delete` refuse it `ENTITY_NOT_FOUND` (`NotFoundError`), the same
|
|
75
|
+
* answer as for an id that does not exist. A location SHARED with another store is changed or
|
|
76
|
+
* deleted only by a caller who may do so in every store holding it (`ENTITY_NOT_FOUND` too
|
|
77
|
+
* otherwise).
|
|
78
|
+
*
|
|
79
|
+
* A hub-owned location (multi-region phase 5) will be refused `MANAGED_BY_ORGANIZATION`
|
|
80
|
+
* (`BusinessRuleError`) by `update` and `delete` from a member store; no location is hub-owned
|
|
81
|
+
* yet. A member store's Stock owner (an app or API token owning the Stock field group) never
|
|
82
|
+
* locks the hub's warehouse (ruling U8).
|
|
83
|
+
*/
|
|
84
|
+
export interface StockLocationsModule {
|
|
85
|
+
/**
|
|
86
|
+
* The store's locations, a page at a time (`options.limit`, default 100, at most 1,000; and
|
|
87
|
+
* `options.after` from a previous page); `for await (const location of page)` walks them all.
|
|
88
|
+
* An API token or app restricted with `locationIds` still lists every location of the store.
|
|
89
|
+
*
|
|
90
|
+
* @effect read
|
|
91
|
+
* @permission ReadStockLocation
|
|
92
|
+
*/
|
|
93
|
+
list(options?: StockLocationListOptions): Promise<Page<StockLocation>>;
|
|
94
|
+
/**
|
|
95
|
+
* One location by id, or `null` when the store has no such location (one only another store
|
|
96
|
+
* holds reads the same).
|
|
97
|
+
*
|
|
98
|
+
* @effect read
|
|
99
|
+
* @permission ReadStockLocation
|
|
100
|
+
*/
|
|
101
|
+
get(id: string, options?: Call): Promise<StockLocation | null>;
|
|
102
|
+
/**
|
|
103
|
+
* Create a location in this store. `name` must not be blank (`STOCK_LOCATION_INPUT_INVALID`,
|
|
104
|
+
* `ValidationError`, before anything is sent).
|
|
105
|
+
*
|
|
106
|
+
* @effect write
|
|
107
|
+
* @permission CreateStockLocation
|
|
108
|
+
*/
|
|
109
|
+
create(input: CreateStockLocationInput, options?: Call): Promise<StockLocation>;
|
|
110
|
+
/**
|
|
111
|
+
* Change a location's name, description, `isPublic` or threshold. Moves no stock, so a
|
|
112
|
+
* credential restricted with `locationIds` may change any location of the store. A blank
|
|
113
|
+
* `name` is `STOCK_LOCATION_INPUT_INVALID` (`ValidationError`, nothing sent). The engine also
|
|
114
|
+
* refuses `STOCK_LOCATION_SENDER_READ_ONLY` (`BusinessRuleError`) a change to the parcel sender,
|
|
115
|
+
* which this method never sends.
|
|
116
|
+
*
|
|
117
|
+
* @effect write
|
|
118
|
+
* @permission UpdateStockLocation
|
|
119
|
+
*/
|
|
120
|
+
update(id: string, input: UpdateStockLocationInput, options?: Call): Promise<StockLocation>;
|
|
121
|
+
/**
|
|
122
|
+
* Delete a location. Its stock levels move to `options.transferToLocationId`, or are deleted
|
|
123
|
+
* with it: there is no undo.
|
|
124
|
+
*
|
|
125
|
+
* Refused:
|
|
126
|
+
* - `STOCK_LOCATION_NOT_DELETED` (`BusinessRuleError`), in the engine's words, when the engine
|
|
127
|
+
* keeps it (the store's last location, for one);
|
|
128
|
+
* - `LOCATION_NOT_ALLOWED` (`PermissionDeniedError`) to a credential restricted with
|
|
129
|
+
* `locationIds` that does not hold the location and the transfer target;
|
|
130
|
+
* - `FIELD_GROUP_LOCKED` (`BusinessRuleError`) while an app or API token owns the store's Stock
|
|
131
|
+
* and the location holds stock;
|
|
132
|
+
* - `ENTITY_NOT_FOUND` (`NotFoundError`) for another store's location or the transfer target.
|
|
133
|
+
*
|
|
134
|
+
* @effect destructive
|
|
135
|
+
* @permission DeleteStockLocation
|
|
136
|
+
*/
|
|
137
|
+
delete(id: string, options?: DeleteStockLocationOptions): Promise<void>;
|
|
138
|
+
}
|
|
139
|
+
export declare const STOCK_LOCATIONS_QUERY = "\n query StockLocations($options: StockLocationListOptions) {\n stockLocations(options: $options) {\n items { \n id\n name\n description\n createdAt\n updatedAt\n customFields {\n isPublic\n outOfStockThreshold\n }\n }\n totalItems\n }\n }\n";
|
|
140
|
+
export declare const STOCK_LOCATION_QUERY = "\n query StockLocation($id: ID!) {\n stockLocation(id: $id) { \n id\n name\n description\n createdAt\n updatedAt\n customFields {\n isPublic\n outOfStockThreshold\n }\n }\n }\n";
|
|
141
|
+
export declare const CREATE_STOCK_LOCATION_MUTATION = "\n mutation CreateStockLocation($input: CreateStockLocationInput!) {\n createStockLocation(input: $input) { \n id\n name\n description\n createdAt\n updatedAt\n customFields {\n isPublic\n outOfStockThreshold\n }\n }\n }\n";
|
|
142
|
+
export declare const UPDATE_STOCK_LOCATION_MUTATION = "\n mutation UpdateStockLocation($input: UpdateStockLocationInput!) {\n updateStockLocation(input: $input) { \n id\n name\n description\n createdAt\n updatedAt\n customFields {\n isPublic\n outOfStockThreshold\n }\n }\n }\n";
|
|
143
|
+
export declare const DELETE_STOCK_LOCATION_MUTATION = "\n mutation DeleteStockLocation($input: DeleteStockLocationInput!) {\n deleteStockLocation(input: $input) {\n result\n message\n }\n }\n";
|
|
144
|
+
export declare function createStockLocationsModule(transport: Transport): StockLocationsModule;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { BusinessRuleError, pageFromVendureList, readOffsetCursor, ValidationError, } from '@sixtyninecommerce/core';
|
|
2
|
+
import { fieldOf } from '../catalog/types.js';
|
|
3
|
+
/** The fields a list can be sorted by. */
|
|
4
|
+
export const STOCK_LOCATION_SORT_FIELDS = ['name', 'createdAt', 'updatedAt'];
|
|
5
|
+
const LOCATION_FIELDS = /* GraphQL */ `
|
|
6
|
+
id
|
|
7
|
+
name
|
|
8
|
+
description
|
|
9
|
+
createdAt
|
|
10
|
+
updatedAt
|
|
11
|
+
customFields {
|
|
12
|
+
isPublic
|
|
13
|
+
outOfStockThreshold
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
export const STOCK_LOCATIONS_QUERY = /* GraphQL */ `
|
|
17
|
+
query StockLocations($options: StockLocationListOptions) {
|
|
18
|
+
stockLocations(options: $options) {
|
|
19
|
+
items { ${LOCATION_FIELDS} }
|
|
20
|
+
totalItems
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
`;
|
|
24
|
+
export const STOCK_LOCATION_QUERY = /* GraphQL */ `
|
|
25
|
+
query StockLocation($id: ID!) {
|
|
26
|
+
stockLocation(id: $id) { ${LOCATION_FIELDS} }
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
export const CREATE_STOCK_LOCATION_MUTATION = /* GraphQL */ `
|
|
30
|
+
mutation CreateStockLocation($input: CreateStockLocationInput!) {
|
|
31
|
+
createStockLocation(input: $input) { ${LOCATION_FIELDS} }
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
34
|
+
export const UPDATE_STOCK_LOCATION_MUTATION = /* GraphQL */ `
|
|
35
|
+
mutation UpdateStockLocation($input: UpdateStockLocationInput!) {
|
|
36
|
+
updateStockLocation(input: $input) { ${LOCATION_FIELDS} }
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
39
|
+
export const DELETE_STOCK_LOCATION_MUTATION = /* GraphQL */ `
|
|
40
|
+
mutation DeleteStockLocation($input: DeleteStockLocationInput!) {
|
|
41
|
+
deleteStockLocation(input: $input) {
|
|
42
|
+
result
|
|
43
|
+
message
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
`;
|
|
47
|
+
const DEFAULT_PAGE_SIZE = 100;
|
|
48
|
+
function toLocation(wire) {
|
|
49
|
+
return {
|
|
50
|
+
id: wire.id,
|
|
51
|
+
name: wire.name,
|
|
52
|
+
description: wire.description ?? '',
|
|
53
|
+
createdAt: wire.createdAt,
|
|
54
|
+
updatedAt: wire.updatedAt,
|
|
55
|
+
// The column defaults: a row written before the field existed reads null.
|
|
56
|
+
isPublic: wire.customFields?.isPublic ?? true,
|
|
57
|
+
outOfStockThreshold: wire.customFields?.outOfStockThreshold ?? 0,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const invalidInput = (message) => new ValidationError({
|
|
61
|
+
code: 'STOCK_LOCATION_INPUT_INVALID',
|
|
62
|
+
message,
|
|
63
|
+
status: 400,
|
|
64
|
+
service: 'vendure',
|
|
65
|
+
});
|
|
66
|
+
function assertId(id, what = 'id') {
|
|
67
|
+
if (typeof id !== 'string' || id.trim() === '') {
|
|
68
|
+
throw invalidInput(`${what} must be a stock location id.`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function assertName(name) {
|
|
72
|
+
if (typeof name !== 'string' || name.trim() === '') {
|
|
73
|
+
throw invalidInput('A stock location needs a name.');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** The location's own custom fields, only the keys the caller set: never the sender fields. */
|
|
77
|
+
function customFieldsOf(input) {
|
|
78
|
+
const fields = {};
|
|
79
|
+
if (input.isPublic !== undefined)
|
|
80
|
+
fields.isPublic = input.isPublic;
|
|
81
|
+
if (input.outOfStockThreshold !== undefined)
|
|
82
|
+
fields.outOfStockThreshold = input.outOfStockThreshold;
|
|
83
|
+
return Object.keys(fields).length > 0 ? fields : undefined;
|
|
84
|
+
}
|
|
85
|
+
function listOptionsOf(skip, take, options) {
|
|
86
|
+
const term = options?.term?.trim() ?? '';
|
|
87
|
+
return {
|
|
88
|
+
skip,
|
|
89
|
+
take,
|
|
90
|
+
...(term === ''
|
|
91
|
+
? {}
|
|
92
|
+
: {
|
|
93
|
+
filter: { name: { contains: term }, description: { contains: term } },
|
|
94
|
+
filterOperator: 'OR',
|
|
95
|
+
}),
|
|
96
|
+
...(options?.sort ? { sort: { [options.sort.field]: options.sort.direction } } : {}),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
export function createStockLocationsModule(transport) {
|
|
100
|
+
const listPage = async (skip, take, options) => {
|
|
101
|
+
const list = await fieldOf(transport, STOCK_LOCATIONS_QUERY, 'stockLocations', { options: listOptionsOf(skip, take, options) }, options);
|
|
102
|
+
return pageFromVendureList({ items: list.items.map(toLocation), totalItems: list.totalItems }, skip, take, (cursor) => listPage(readOffsetCursor(cursor), take, options));
|
|
103
|
+
};
|
|
104
|
+
return {
|
|
105
|
+
list(options) {
|
|
106
|
+
if (options?.sort && !STOCK_LOCATION_SORT_FIELDS.includes(options.sort.field)) {
|
|
107
|
+
return Promise.reject(invalidInput(`sort.field must be one of ${STOCK_LOCATION_SORT_FIELDS.join(', ')}.`));
|
|
108
|
+
}
|
|
109
|
+
const take = options?.limit ?? DEFAULT_PAGE_SIZE;
|
|
110
|
+
const skip = options?.after === undefined ? 0 : readOffsetCursor(options.after);
|
|
111
|
+
return listPage(skip, take, options);
|
|
112
|
+
},
|
|
113
|
+
async get(id, options) {
|
|
114
|
+
assertId(id);
|
|
115
|
+
const wire = await fieldOf(transport, STOCK_LOCATION_QUERY, 'stockLocation', { id }, options);
|
|
116
|
+
return wire === null ? null : toLocation(wire);
|
|
117
|
+
},
|
|
118
|
+
async create(input, options) {
|
|
119
|
+
assertName(input?.name);
|
|
120
|
+
const customFields = customFieldsOf(input);
|
|
121
|
+
return toLocation(await fieldOf(transport, CREATE_STOCK_LOCATION_MUTATION, 'createStockLocation', {
|
|
122
|
+
input: {
|
|
123
|
+
name: input.name,
|
|
124
|
+
description: input.description ?? '',
|
|
125
|
+
...(customFields ? { customFields } : {}),
|
|
126
|
+
},
|
|
127
|
+
}, options));
|
|
128
|
+
},
|
|
129
|
+
async update(id, input, options) {
|
|
130
|
+
assertId(id);
|
|
131
|
+
if (input?.name !== undefined)
|
|
132
|
+
assertName(input.name);
|
|
133
|
+
const customFields = customFieldsOf(input ?? {});
|
|
134
|
+
return toLocation(await fieldOf(transport, UPDATE_STOCK_LOCATION_MUTATION, 'updateStockLocation', {
|
|
135
|
+
input: {
|
|
136
|
+
id,
|
|
137
|
+
...(input?.name !== undefined ? { name: input.name } : {}),
|
|
138
|
+
...(input?.description !== undefined ? { description: input.description } : {}),
|
|
139
|
+
// Core applies customFields key by key: the sender fields are never named here.
|
|
140
|
+
...(customFields ? { customFields } : {}),
|
|
141
|
+
},
|
|
142
|
+
}, options));
|
|
143
|
+
},
|
|
144
|
+
async delete(id, options) {
|
|
145
|
+
assertId(id);
|
|
146
|
+
if (options?.transferToLocationId !== undefined) {
|
|
147
|
+
assertId(options.transferToLocationId, 'transferToLocationId');
|
|
148
|
+
}
|
|
149
|
+
const response = await fieldOf(transport, DELETE_STOCK_LOCATION_MUTATION, 'deleteStockLocation', {
|
|
150
|
+
input: {
|
|
151
|
+
id,
|
|
152
|
+
...(options?.transferToLocationId
|
|
153
|
+
? { transferToLocationId: options.transferToLocationId }
|
|
154
|
+
: {}),
|
|
155
|
+
},
|
|
156
|
+
}, options);
|
|
157
|
+
if (response?.result === 'DELETED')
|
|
158
|
+
return;
|
|
159
|
+
// Answered at HTTP 200, so the transport never throws for it.
|
|
160
|
+
throw new BusinessRuleError({
|
|
161
|
+
code: 'STOCK_LOCATION_NOT_DELETED',
|
|
162
|
+
message: response?.message?.trim() || 'The stock location was not deleted.',
|
|
163
|
+
status: 422,
|
|
164
|
+
service: 'vendure',
|
|
165
|
+
});
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { type Transport } from '@sixtyninecommerce/core';
|
|
2
|
+
import type { Call } from '../types.js';
|
|
3
|
+
/** The store's default for ordering beyond saleable stock: never, up to stock on order, any quantity. */
|
|
4
|
+
export type StockBackorderPolicy = 'deny' | 'incoming' | 'unlimited';
|
|
5
|
+
/**
|
|
6
|
+
* How the storefront warehouse selection reads: `ALL` (no selection, every warehouse), `SUBSET`
|
|
7
|
+
* (only the listed ones), or `MALFORMED` (the stored value cannot be read; the engine sells from
|
|
8
|
+
* every warehouse and logs it, and saving a selection replaces it).
|
|
9
|
+
*/
|
|
10
|
+
export type StorefrontStockLocationSelectionMode = 'ALL' | 'SUBSET' | 'MALFORMED';
|
|
11
|
+
export interface StorefrontStockLocations {
|
|
12
|
+
mode: StorefrontStockLocationSelectionMode;
|
|
13
|
+
/** The selected stock location ids, trimmed and de-duplicated (`SUBSET` only); else empty. */
|
|
14
|
+
locationIds: string[];
|
|
15
|
+
/** Why the stored value cannot be read (`MALFORMED` only); else null. */
|
|
16
|
+
reason: string | null;
|
|
17
|
+
}
|
|
18
|
+
/** A store's stock settings as the engine reads them. */
|
|
19
|
+
export interface StockSettings {
|
|
20
|
+
/** The channel the settings are stored on. */
|
|
21
|
+
channelId: string;
|
|
22
|
+
/**
|
|
23
|
+
* The store's own "track inventory" value; `null` = the store inherits
|
|
24
|
+
* {@link defaultTrackInventory}. It decides availability for this store's customers: a variant
|
|
25
|
+
* set to inherit tracks by it (a variant's own `TRUE`/`FALSE` wins), and an untracked variant
|
|
26
|
+
* is always available (saleable stock, add to cart, checkout, the storefront `stockLevel`,
|
|
27
|
+
* search, the till, feeds).
|
|
28
|
+
*/
|
|
29
|
+
trackInventory: boolean | null;
|
|
30
|
+
/**
|
|
31
|
+
* The store's own out-of-stock threshold; `null` = the store inherits
|
|
32
|
+
* {@link defaultOutOfStockThreshold}. A variant on the global threshold (its own threshold
|
|
33
|
+
* wins otherwise, and a warehouse's own threshold wins at that warehouse) is unavailable once
|
|
34
|
+
* its stock on hand less allocations falls to it.
|
|
35
|
+
*/
|
|
36
|
+
outOfStockThreshold: number | null;
|
|
37
|
+
/** The platform default a store that inherits tracks by. */
|
|
38
|
+
defaultTrackInventory: boolean;
|
|
39
|
+
/** The platform default threshold a store that inherits uses. */
|
|
40
|
+
defaultOutOfStockThreshold: number;
|
|
41
|
+
/** Whether the Shop API exposes operational stock numbers (on hand, allocated, saleable). */
|
|
42
|
+
exposeStockToStorefront: boolean;
|
|
43
|
+
/** Which warehouses back the storefront's saleable stock and its orders' reservations. */
|
|
44
|
+
storefrontStockLocations: StorefrontStockLocations;
|
|
45
|
+
/** The store's backorder default; a variant may override it. Unreadable reads `deny`. */
|
|
46
|
+
backorderPolicy: StockBackorderPolicy;
|
|
47
|
+
}
|
|
48
|
+
/** A change to the stock settings. An omitted field keeps the stored value. */
|
|
49
|
+
export interface StockSettingsPatch {
|
|
50
|
+
/**
|
|
51
|
+
* `null` = inherit the platform default. Changes which of this store's variants are available
|
|
52
|
+
* (see {@link StockSettings.trackInventory}).
|
|
53
|
+
*/
|
|
54
|
+
trackInventory?: boolean | null;
|
|
55
|
+
/** `null` = inherit the platform default (see {@link StockSettings.outOfStockThreshold}). */
|
|
56
|
+
outOfStockThreshold?: number | null;
|
|
57
|
+
exposeStockToStorefront?: boolean;
|
|
58
|
+
/** Stock location ids of the store; `[]` clears the selection (every warehouse). */
|
|
59
|
+
storefrontStockLocationIds?: string[];
|
|
60
|
+
backorderPolicy?: StockBackorderPolicy;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The ACTIVE store's stock settings (`admin.stock.settings`). Reading needs any administrator
|
|
64
|
+
* permission on the store; writing needs `UpdateChannel` (the settings are stored on the channel
|
|
65
|
+
* and written through core `updateChannel`).
|
|
66
|
+
*
|
|
67
|
+
* The engine owns every rule: how a stored value reads is never worked out in the client. Ask
|
|
68
|
+
* {@link preview} for a change that is not saved.
|
|
69
|
+
*/
|
|
70
|
+
export interface StockSettingsModule {
|
|
71
|
+
/**
|
|
72
|
+
* The settings as the engine reads them. An unreadable warehouse selection is `MALFORMED`, an
|
|
73
|
+
* unreadable backorder policy is `deny`, an unreadable exposure flag is off.
|
|
74
|
+
*
|
|
75
|
+
* @effect read
|
|
76
|
+
*/
|
|
77
|
+
get(options?: Call): Promise<StockSettings>;
|
|
78
|
+
/**
|
|
79
|
+
* How the settings WOULD read with `patch` applied, without saving anything.
|
|
80
|
+
*
|
|
81
|
+
* Refused `CHANNEL_SETTINGS_INVALID` (`ValidationError`, one `details[]` entry per field, named
|
|
82
|
+
* like `customFields.backorderPolicy`) for a change the save would refuse: a `null` track
|
|
83
|
+
* inventory, threshold, exposure flag or policy, a policy that is not exactly one of the values,
|
|
84
|
+
* a blank warehouse id, or more than 500 warehouses. A malformed warehouse id is refused
|
|
85
|
+
* `ENTITY_NOT_FOUND` (`NotFoundError`).
|
|
86
|
+
*
|
|
87
|
+
* @effect read
|
|
88
|
+
*/
|
|
89
|
+
preview(patch: StockSettingsPatch, options?: Call): Promise<StockSettings>;
|
|
90
|
+
/**
|
|
91
|
+
* Save `patch`, and answer the settings as the engine now reads them. Only the fields named are
|
|
92
|
+
* written; the warehouse list is stored as the engine reads it (trimmed, de-duplicated, `[]` as
|
|
93
|
+
* no selection).
|
|
94
|
+
*
|
|
95
|
+
* Refused, before anything is written, as {@link preview} refuses. Refused by the save itself:
|
|
96
|
+
* `FORBIDDEN` without `UpdateChannel`. A warehouse id that is not a stock location of the store
|
|
97
|
+
* is stored and ignored by the engine (it never widens the store's warehouses).
|
|
98
|
+
*
|
|
99
|
+
* @effect write
|
|
100
|
+
*/
|
|
101
|
+
set(patch: StockSettingsPatch, options?: Call): Promise<StockSettings>;
|
|
102
|
+
}
|
|
103
|
+
export declare const STOCK_SETTINGS_QUERY = "\n query StockSettings {\n stockSettings { \n channelId\n trackInventory\n outOfStockThreshold\n defaultTrackInventory\n defaultOutOfStockThreshold\n exposeStockToStorefront\n storefrontStockLocations {\n mode\n locationIds\n reason\n }\n backorderPolicy\n }\n }\n";
|
|
104
|
+
export declare const PREVIEW_STOCK_SETTINGS_QUERY = "\n query PreviewStockSettings($input: StockSettingsInput!) {\n previewStockSettings(input: $input) { \n channelId\n trackInventory\n outOfStockThreshold\n defaultTrackInventory\n defaultOutOfStockThreshold\n exposeStockToStorefront\n storefrontStockLocations {\n mode\n locationIds\n reason\n }\n backorderPolicy\n }\n }\n";
|
|
105
|
+
export declare const SET_STOCK_SETTINGS_MUTATION = "\n mutation SetStockSettings($input: UpdateChannelInput!) {\n updateChannel(input: $input) {\n ... on Channel { id }\n ... on ErrorResult { errorCode message }\n }\n }\n";
|
|
106
|
+
export declare function createStockSettingsModule(transport: Transport): StockSettingsModule;
|