@sixtyninecommerce/admin 0.10.0 → 0.11.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.
Files changed (247) hide show
  1. package/README.md +4347 -171
  2. package/dist/catalog/assets.d.ts +120 -8
  3. package/dist/catalog/assets.js +98 -12
  4. package/dist/catalog/collections.d.ts +279 -14
  5. package/dist/catalog/collections.js +246 -15
  6. package/dist/catalog/index.d.ts +9 -2
  7. package/dist/catalog/index.js +4 -0
  8. package/dist/catalog/products.d.ts +159 -19
  9. package/dist/catalog/products.js +88 -13
  10. package/dist/catalog/properties.d.ts +102 -14
  11. package/dist/catalog/properties.js +13 -0
  12. package/dist/catalog/recommendations.d.ts +261 -0
  13. package/dist/catalog/recommendations.js +145 -0
  14. package/dist/catalog/reviews.d.ts +368 -0
  15. package/dist/catalog/reviews.js +318 -0
  16. package/dist/catalog/types.d.ts +17 -1
  17. package/dist/catalog/types.js +10 -0
  18. package/dist/catalog/variant-find.d.ts +136 -0
  19. package/dist/catalog/variant-find.js +239 -0
  20. package/dist/catalog/variants.d.ts +233 -26
  21. package/dist/catalog/variants.js +125 -7
  22. package/dist/catalog/visibility.d.ts +20 -5
  23. package/dist/catalog/visibility.js +19 -1
  24. package/dist/client.d.ts +95 -9
  25. package/dist/client.js +35 -7
  26. package/dist/content/assets.d.ts +286 -0
  27. package/dist/content/assets.js +181 -0
  28. package/dist/content/items.d.ts +269 -0
  29. package/dist/content/items.js +170 -0
  30. package/dist/content/types.d.ts +282 -0
  31. package/dist/content/types.js +100 -0
  32. package/dist/customers/age-verification.d.ts +66 -0
  33. package/dist/customers/age-verification.js +79 -0
  34. package/dist/customers/credit.d.ts +263 -0
  35. package/dist/customers/credit.js +244 -0
  36. package/dist/customers/delivery-preferences.d.ts +120 -0
  37. package/dist/customers/delivery-preferences.js +97 -0
  38. package/dist/customers/groups.d.ts +207 -0
  39. package/dist/customers/groups.js +438 -0
  40. package/dist/customers/index.d.ts +447 -37
  41. package/dist/customers/index.js +313 -40
  42. package/dist/customers/invitation-status.d.ts +57 -0
  43. package/dist/customers/invitation-status.js +21 -0
  44. package/dist/customers/notes.d.ts +67 -0
  45. package/dist/customers/notes.js +51 -0
  46. package/dist/customers/notification-recipients.d.ts +97 -0
  47. package/dist/customers/notification-recipients.js +84 -0
  48. package/dist/customers/saved-lists.d.ts +42 -0
  49. package/dist/customers/saved-lists.js +61 -0
  50. package/dist/customers/vat.d.ts +83 -0
  51. package/dist/customers/vat.js +46 -0
  52. package/dist/customers/wire.d.ts +20 -0
  53. package/dist/customers/wire.js +35 -0
  54. package/dist/documents/ar.d.ts +307 -0
  55. package/dist/documents/ar.js +254 -0
  56. package/dist/documents/index.d.ts +731 -21
  57. package/dist/documents/index.js +436 -24
  58. package/dist/documents/pdf.d.ts +2 -0
  59. package/dist/documents/pdf.js +11 -0
  60. package/dist/fulfillments/create.d.ts +167 -0
  61. package/dist/fulfillments/create.js +216 -0
  62. package/dist/fulfillments/index.d.ts +44 -10
  63. package/dist/fulfillments/index.js +11 -2
  64. package/dist/fulfillments/payment-policy.d.ts +64 -0
  65. package/dist/fulfillments/payment-policy.js +140 -0
  66. package/dist/fulfillments/warehouse.d.ts +724 -0
  67. package/dist/fulfillments/warehouse.js +914 -0
  68. package/dist/geo/index.d.ts +119 -0
  69. package/dist/geo/index.js +107 -0
  70. package/dist/index.d.ts +123 -35
  71. package/dist/index.js +45 -12
  72. package/dist/integrations/afas-actions.d.ts +234 -0
  73. package/dist/integrations/afas-actions.js +310 -0
  74. package/dist/integrations/afas-types.d.ts +483 -0
  75. package/dist/integrations/afas-types.js +5 -0
  76. package/dist/integrations/afas.d.ts +234 -0
  77. package/dist/integrations/afas.js +290 -0
  78. package/dist/integrations/connections.d.ts +103 -0
  79. package/dist/integrations/connections.js +55 -0
  80. package/dist/integrations/esp.d.ts +313 -0
  81. package/dist/integrations/esp.js +169 -0
  82. package/dist/integrations/exact-online-types.d.ts +423 -0
  83. package/dist/integrations/exact-online-types.js +6 -0
  84. package/dist/integrations/exact-online.d.ts +248 -0
  85. package/dist/integrations/exact-online.js +376 -0
  86. package/dist/integrations/index.d.ts +29 -3
  87. package/dist/integrations/index.js +18 -3
  88. package/dist/integrations/pipeline-keys.d.ts +13 -0
  89. package/dist/integrations/pipeline-keys.js +22 -0
  90. package/dist/integrations/pipelines.d.ts +15 -14
  91. package/dist/integrations/pipelines.js +6 -22
  92. package/dist/integrations/types.d.ts +146 -0
  93. package/dist/locations/index.d.ts +66 -0
  94. package/dist/locations/index.js +31 -0
  95. package/dist/meta/index.d.ts +162 -0
  96. package/dist/orders/cancel-with-money.d.ts +227 -0
  97. package/dist/orders/cancel-with-money.js +153 -0
  98. package/dist/orders/commit-edit.d.ts +7 -1
  99. package/dist/orders/commit-edit.js +5 -1
  100. package/dist/orders/drafts.d.ts +800 -0
  101. package/dist/orders/drafts.js +771 -0
  102. package/dist/orders/fields.d.ts +245 -0
  103. package/dist/orders/fields.js +188 -0
  104. package/dist/orders/get.d.ts +29 -19
  105. package/dist/orders/get.js +17 -8
  106. package/dist/orders/index.d.ts +49 -9
  107. package/dist/orders/index.js +22 -2
  108. package/dist/orders/lifecycle.d.ts +128 -0
  109. package/dist/orders/lifecycle.js +158 -0
  110. package/dist/orders/line-price-preview.d.ts +7 -2
  111. package/dist/orders/list.d.ts +222 -0
  112. package/dist/orders/list.js +377 -0
  113. package/dist/orders/manual-pricing.d.ts +5 -0
  114. package/dist/orders/order-entry.d.ts +20 -7
  115. package/dist/orders/plan-edit.d.ts +1 -1
  116. package/dist/orders/plan-edit.js +4 -1
  117. package/dist/orders/settings.d.ts +201 -0
  118. package/dist/orders/settings.js +325 -0
  119. package/dist/orders/status.d.ts +159 -13
  120. package/dist/orders/status.js +21 -0
  121. package/dist/orders/surcharges.d.ts +8 -1
  122. package/dist/orders/surcharges.js +3 -2
  123. package/dist/payments/account-credit.d.ts +30 -0
  124. package/dist/payments/account-credit.js +19 -0
  125. package/dist/payments/ar.d.ts +292 -0
  126. package/dist/payments/ar.js +223 -0
  127. package/dist/payments/connected-account.d.ts +47 -0
  128. package/dist/payments/connected-account.js +61 -0
  129. package/dist/payments/credit-noted-fields.d.ts +12 -0
  130. package/dist/payments/credit-noted-fields.js +37 -0
  131. package/dist/payments/index.d.ts +257 -11
  132. package/dist/payments/index.js +131 -1
  133. package/dist/payments/methods.d.ts +303 -8
  134. package/dist/payments/methods.js +337 -7
  135. package/dist/payments/mollie-methods.d.ts +159 -0
  136. package/dist/payments/mollie-methods.js +141 -0
  137. package/dist/payments/payment-links.d.ts +180 -0
  138. package/dist/payments/payment-links.js +97 -0
  139. package/dist/payments/provider-keys.d.ts +150 -0
  140. package/dist/payments/provider-keys.js +118 -0
  141. package/dist/payments/providers.d.ts +86 -11
  142. package/dist/payments/providers.js +29 -0
  143. package/dist/payments/requests.d.ts +144 -0
  144. package/dist/payments/requests.js +92 -0
  145. package/dist/payments/store-credit-fields.d.ts +15 -0
  146. package/dist/payments/store-credit-fields.js +51 -0
  147. package/dist/pickups/index.d.ts +104 -0
  148. package/dist/pickups/index.js +105 -0
  149. package/dist/platform/channels.d.ts +132 -0
  150. package/dist/platform/channels.js +128 -0
  151. package/dist/platform/geo.d.ts +123 -0
  152. package/dist/platform/geo.js +144 -0
  153. package/dist/platform/tax.d.ts +154 -0
  154. package/dist/platform/tax.js +139 -0
  155. package/dist/pos/anomalies.d.ts +158 -0
  156. package/dist/pos/anomalies.js +64 -0
  157. package/dist/pos/assisted-selling.d.ts +79 -0
  158. package/dist/pos/assisted-selling.js +38 -0
  159. package/dist/pos/exchanges.d.ts +103 -0
  160. package/dist/pos/exchanges.js +22 -0
  161. package/dist/pos/gift-cards.d.ts +135 -0
  162. package/dist/pos/gift-cards.js +47 -0
  163. package/dist/pos/index.d.ts +2125 -32
  164. package/dist/pos/index.js +742 -4
  165. package/dist/pos/no-receipt.d.ts +94 -0
  166. package/dist/pos/no-receipt.js +25 -0
  167. package/dist/pos/offline-sales.d.ts +187 -0
  168. package/dist/pos/offline-sales.js +116 -0
  169. package/dist/pos/pay-by-link.d.ts +143 -0
  170. package/dist/pos/pay-by-link.js +57 -0
  171. package/dist/pos/quick-keys.d.ts +103 -0
  172. package/dist/pos/quick-keys.js +45 -0
  173. package/dist/pos/reports.d.ts +360 -0
  174. package/dist/pos/reports.js +62 -0
  175. package/dist/pos/returns.d.ts +217 -0
  176. package/dist/pos/returns.js +53 -0
  177. package/dist/pricing/bulk-coupons.d.ts +139 -0
  178. package/dist/pricing/bulk-coupons.js +112 -0
  179. package/dist/pricing/index.d.ts +174 -4
  180. package/dist/pricing/index.js +174 -1
  181. package/dist/pricing/price-lists.d.ts +604 -0
  182. package/dist/pricing/price-lists.js +600 -0
  183. package/dist/purchasing/alerts.d.ts +89 -0
  184. package/dist/purchasing/alerts.js +62 -0
  185. package/dist/purchasing/cost.d.ts +110 -0
  186. package/dist/purchasing/cost.js +86 -0
  187. package/dist/purchasing/index.d.ts +36 -0
  188. package/dist/purchasing/index.js +16 -0
  189. package/dist/purchasing/purchase-orders.d.ts +548 -0
  190. package/dist/purchasing/purchase-orders.js +491 -0
  191. package/dist/purchasing/replenishment.d.ts +281 -0
  192. package/dist/purchasing/replenishment.js +240 -0
  193. package/dist/purchasing/settings.d.ts +152 -0
  194. package/dist/purchasing/settings.js +181 -0
  195. package/dist/purchasing/suppliers.d.ts +476 -0
  196. package/dist/purchasing/suppliers.js +438 -0
  197. package/dist/quotes/index.d.ts +501 -0
  198. package/dist/quotes/index.js +439 -0
  199. package/dist/reports/index.d.ts +71 -8
  200. package/dist/reports/index.js +74 -11
  201. package/dist/returns/index.d.ts +614 -21
  202. package/dist/returns/index.js +695 -11
  203. package/dist/search/index.d.ts +76 -1
  204. package/dist/search/index.js +63 -0
  205. package/dist/shipping/definitions.d.ts +29 -0
  206. package/dist/shipping/definitions.js +47 -0
  207. package/dist/shipping/fulfillment-profiles.d.ts +174 -0
  208. package/dist/shipping/fulfillment-profiles.js +104 -0
  209. package/dist/shipping/hendriks.d.ts +97 -0
  210. package/dist/shipping/hendriks.js +50 -0
  211. package/dist/shipping/index.d.ts +48 -0
  212. package/dist/shipping/index.js +25 -0
  213. package/dist/shipping/methods.d.ts +198 -0
  214. package/dist/shipping/methods.js +240 -0
  215. package/dist/shipping/myparcel.d.ts +254 -0
  216. package/dist/shipping/myparcel.js +178 -0
  217. package/dist/shipping/parcel-count-suggestion.d.ts +2 -0
  218. package/dist/shipping/parcel-rule.d.ts +6 -5
  219. package/dist/shipping/parcel-rule.js +21 -23
  220. package/dist/shipping/rate-tables.d.ts +179 -0
  221. package/dist/shipping/rate-tables.js +184 -0
  222. package/dist/stock/index.d.ts +10 -3
  223. package/dist/stock/index.js +3 -0
  224. package/dist/stock/locations.d.ts +144 -0
  225. package/dist/stock/locations.js +168 -0
  226. package/dist/stock/transfers.d.ts +216 -43
  227. package/dist/stock/transfers.js +140 -13
  228. package/dist/stored-value/index.d.ts +214 -4
  229. package/dist/stored-value/index.js +152 -0
  230. package/dist/subscriptions/index.d.ts +682 -0
  231. package/dist/subscriptions/index.js +815 -0
  232. package/dist/tax/index.d.ts +76 -1
  233. package/dist/tax/index.js +50 -0
  234. package/dist/tenant/email-style.d.ts +102 -0
  235. package/dist/tenant/email-style.js +72 -0
  236. package/dist/tenant/email-templates.d.ts +66 -0
  237. package/dist/tenant/email-templates.js +54 -0
  238. package/dist/tenant/notifications.d.ts +23 -17
  239. package/dist/tenant/settings-sources.d.ts +1 -1
  240. package/dist/tenant/time-zone.d.ts +17 -0
  241. package/dist/tenant/time-zone.js +11 -0
  242. package/dist/types.d.ts +50 -3
  243. package/dist/users/index.d.ts +3 -0
  244. package/dist/users/index.js +2 -0
  245. package/dist/users/warehouses.d.ts +50 -0
  246. package/dist/users/warehouses.js +51 -0
  247. package/package.json +2 -2
@@ -3,23 +3,37 @@ import type { JobHandle } from '../jobs/index.js';
3
3
  import type { OrderPaymentPosition, PaidOrder } from '../payments/index.js';
4
4
  import type { Call } from '../types.js';
5
5
  import { type OrderBulkInput, type OrderBulkRun } from './bulk.js';
6
+ import { type OrderCancelWithMoneyModule } from './cancel-with-money.js';
6
7
  import { type OrderCommitEditModule } from './commit-edit.js';
7
8
  import { type OrderDepositPolicyModule } from './deposit-policy.js';
9
+ import { type OrderDraftsModule } from './drafts.js';
10
+ import { type OrderFieldsModule } from './fields.js';
8
11
  import { type OrderGetModule } from './get.js';
12
+ import { type OrderLifecycleModule } from './lifecycle.js';
9
13
  import { type OrderLinePricePreviewModule } from './line-price-preview.js';
14
+ import { type OrderListModule } from './list.js';
10
15
  import { type ManualDiscountsModule } from './manual-discounts.js';
11
16
  import { type OrderManualPricingModule } from './manual-pricing.js';
12
17
  import { type OrderEntryModule } from './order-entry.js';
13
18
  import { type OrderParcelChargeModule } from './parcel-charge.js';
14
19
  import { type OrderPlanEditModule } from './plan-edit.js';
20
+ import { type OrderSettingsModule } from './settings.js';
15
21
  import { type OrderStatusModule } from './status.js';
16
22
  import { type SurchargesModule } from './surcharges.js';
17
23
  export type { PaidOrder } from '../payments/index.js';
18
24
  export type { OrderBulkAction, OrderBulkCapture, OrderBulkInput, OrderBulkItem, OrderBulkRun, } from './bulk.js';
19
25
  export { MAX_BULK_ORDERS, ORDER_BULK_ACTIONS, ORDER_BULK_TRANSITION_REFUSED } from './bulk.js';
20
26
  export type { OrderDepositPolicy, OrderDepositPolicyModule, StorefrontDepositPolicy, } from './deposit-policy.js';
27
+ export type { ClonedDraft, DraftAddLineInput, DraftAddressDefault, DraftAddressDefaults, DraftAddressFields, DraftAddressInput, DraftAddressSide, DraftAdjustLineInput, DraftCloneSkipReason, DraftCouponsModule, DraftLinePriceInput, DraftMinimumModule, DraftMinimumStatus, DraftOrder, DraftOrderFields, DraftOrderLine, DraftPaymentInput, DraftRepriceOutcome, DraftShippingQuote, KeyedDraftCall, OrderDraftsModule, PlaceDraftInput, PlacedDraftOrder, PlacedDraftPayment, SaveDraftAddressesInput, SavedDraftAddresses, } from './drafts.js';
28
+ export { DraftInsufficientStockError } from './drafts.js';
29
+ export type { FulfillmentQuantityCorrection, FulfillmentQuantityCorrectionInput, FulfillmentQuantityCorrectionLine, FulfillmentUnitDisposition, OrderCustomerAssignment, OrderFieldsModule, OrderGoodwillRounding, OrderNote, OrderNoteInput, OrderNotesModule, OrderPurchaseOrderNumber, } from './fields.js';
30
+ export type { FulfillmentHoldInput, OrderLifecycleModule, OrderLifecycleRecord, } from './lifecycle.js';
31
+ export type { OrderListFilter, OrderListModule, OrderListOptions, OrderListSort, OrderListSortField, OrderSummary, RecentOrder, RecentOrderLine, RecentOrdersOptions, } from './list.js';
32
+ export { MAX_ORDER_LIST_TAKE, MAX_RECENT_ORDERS, ORDER_LIST_SORT_FIELDS } from './list.js';
21
33
  export type { DiscountPolicy, DiscountPolicyInput, DiscountPolicyModule, DiscountReason, DiscountReasonInput, DiscountReasonsModule, ManualDiscountsModule, OrderManualDiscount, } from './manual-discounts.js';
22
34
  export type { ExternalLinePriceBasis, ExternalOrder, ExternalOrderAddressInput, ExternalOrderCall, ExternalOrderCatalogLine, ExternalOrderExternalLine, ExternalOrderFulfilment, ExternalOrderInput, ExternalOrderLine, ExternalOrderLineInput, ExternalOrderSurcharge, ExternalOrderSurchargeInput, ExternalOrderTargetState, ExternalOrderTaxLine, } from './order-entry.js';
35
+ export type { MinimumAgeSource, OrderSettings, OrderSettingsModule, OrderStatusRule, OrderStatusRuleConditionType, OrderStatusRuleTargetState, UpdateOrderSettingsInput, } from './settings.js';
36
+ export { MINIMUM_AGE_MAX, MINIMUM_AGE_MIN, ORDER_CODE_DIGITS_MAX, ORDER_CODE_DIGITS_MIN, ORDER_CODE_PREFIX_MAX_LENGTH, ORDER_SETTINGS_AMOUNT_MAX, ORDER_STATUS_RULE_CONDITION_TYPES, ORDER_STATUS_RULE_TARGET_STATES, } from './settings.js';
23
37
  /** An app provider an order is running without (`admin.orders.providerFallbacks`). */
24
38
  export interface OrderProviderFallback {
25
39
  /** `shipping.rates` or `tax.calculate`. */
@@ -70,8 +84,14 @@ export interface OrderSettlement {
70
84
  * The manual pricing doors (`setLinePrices`, `setOneTimeDiscounts`) sit there too, beside their
71
85
  * read twin `previewLinePrices`, which prices the same changes without saving them.
72
86
  */
73
- export interface OrdersModule extends OrderEntryModule, OrderGetModule, OrderParcelChargeModule, OrderLinePricePreviewModule, OrderManualPricingModule, OrderPlanEditModule, OrderCommitEditModule, OrderStatusModule {
87
+ export interface OrdersModule extends OrderEntryModule, OrderGetModule, OrderListModule, OrderParcelChargeModule, OrderLinePricePreviewModule, OrderManualPricingModule, OrderPlanEditModule, OrderCommitEditModule, OrderCancelWithMoneyModule, OrderLifecycleModule, OrderFieldsModule, OrderStatusModule {
74
88
  surcharges: SurchargesModule;
89
+ /**
90
+ * The draft-order builder: staff create a draft, set its customer, lines (with manual prices
91
+ * and reasons), fields, shipping and order-minimum override, and re-price it, one step at a
92
+ * time (headless W10-21). See {@link OrderDraftsModule}.
93
+ */
94
+ drafts: OrderDraftsModule;
75
95
  /**
76
96
  * Manual discounts with a reason (incentives spec §4 decision 6): read an order's records,
77
97
  * and the store's reason list and policy (`reasons`, `policy`). A discount itself is given
@@ -94,14 +114,21 @@ export interface OrdersModule extends OrderEntryModule, OrderGetModule, OrderPar
94
114
  * (that read's vocabulary), before anything is written. Then by its single door, under the
95
115
  * door's own lock, with the door's own code: `ORDER_STATE_TRANSITION_ERROR` (and core's other
96
116
  * order codes), `ORDER_CART_NOT_CANCELLABLE`, `ORDER_UNITS_SHIPPED`,
97
- * `ORDER_HAS_ACTIVE_FULFILLMENT`, `ORDER_INVOICE_LOCKED`, `ORDER_HAS_RECORDS`,
98
- * `ORDER_NOT_DELETED`. Another store's order answers `ENTITY_NOT_FOUND` on its item. A
99
- * `SUCCEEDED` run can hold `FAILED` items: read them.
117
+ * `ORDER_HAS_ACTIVE_FULFILLMENT`, `ORDER_CANCEL_CREDIT_NOTE_CONFLICT`, `ORDER_HOLDS_MONEY`,
118
+ * `ORDER_INVOICE_LOCKED`, `ORDER_HAS_RECORDS`, `ORDER_NOT_DELETED`. Another store's order
119
+ * answers `ENTITY_NOT_FOUND` on its item. A `SUCCEEDED` run can hold `FAILED` items: read them.
100
120
  *
101
121
  * - `TRANSITION` (`toState` required): as `transitionOrderToState`. Never `Cancelled` (use
102
122
  * `CANCEL`), `PaymentSettled` (use `MARK_PAID`), `Modifying` or `AddingItems`.
103
123
  * - `CANCEL` (`reason` optional): the whole order, shipping included, as `cancelOrder`. **It
104
- * moves no money:** a paid order keeps its payment, to be refunded through `payments.refund`.
124
+ * moves no money:** an order that has been placed or parked and still holds money (settled
125
+ * money, a card hold) answers `ORDER_HOLDS_MONEY` and is not cancelled; cancel it on its own
126
+ * with `orders.cancelWithMoney`, which decides what happens to the money. An INVOICED order,
127
+ * paid or not, is not cancelled by either (reason `CREDIT_NOTE_REQUIRED`): do what
128
+ * `orders.status`'s `cancelCreditNote.remedy` says first (correct the invoice, or refund the
129
+ * payment whose AR credit note corrects it, never both), then cancel it. A credential
130
+ * restricted to stock locations (`locationIds`) cancels only an order whose stock is reserved
131
+ * at its own locations; any other item answers `LOCATION_OUT_OF_SCOPE`, as `cancelOrder` does.
105
132
  * - `DELETE`: a draft or a cart holding no payment or stock movement, as `deleteOrder`.
106
133
  * - `MARK_PAID`: **captures** each payment of the order that is `Authorized` when the run reaches
107
134
  * it, read by the engine (never your list's copy), each as `settlePayment` and on its own
@@ -153,6 +180,12 @@ export interface OrdersModule extends OrderEntryModule, OrderGetModule, OrderPar
153
180
  * applies; `set` replaces it, validated against the schema's bounds first.
154
181
  */
155
182
  depositPolicy: OrderDepositPolicyModule;
183
+ /**
184
+ * The store's order settings (Settings → Orders): the order minimum and its exemptions, order
185
+ * numbering, the minimum purchase age, the status rules and the outstanding-balance tiers.
186
+ * `get` answers them as the engine applies them; `set` changes the keys a patch names.
187
+ */
188
+ settings: OrderSettingsModule;
156
189
  /**
157
190
  * Hold a placed order while the rest of its money is arranged. Needs
158
191
  * `UpdateOrder`.
@@ -208,7 +241,12 @@ export interface OrdersModule extends OrderEntryModule, OrderGetModule, OrderPar
208
241
  * position.
209
242
  */
210
243
  unpark(orderId: string, options?: Call): Promise<PaidOrder>;
211
- /** What the order has actually been paid. Needs `ReadOrder`. */
244
+ /**
245
+ * What the order has actually been paid, what its credit notes took off and what it still owes
246
+ * (`payments.position`'s answer). Needs `ReadOrder`.
247
+ *
248
+ * @effect read
249
+ */
212
250
  paymentPosition(orderId: string, options?: Call): Promise<OrderPaymentPosition>;
213
251
  /**
214
252
  * Move a fully paid order to `PaymentSettled`. Needs `UpdateOrder`.
@@ -235,8 +273,10 @@ export interface OrdersModule extends OrderEntryModule, OrderGetModule, OrderPar
235
273
  * is covered only by an AUTHORIZED payment owes nothing and is refused
236
274
  * `COVERAGE_INSUFFICIENT` with the hold kept: accept it by capturing that
237
275
  * payment with `settlePayment`, which settles and places it. To turn the order
238
- * down, refund the payment, then {@link OrdersModule.unpark} and cancel it: a
239
- * refund alone leaves it parked, held and holding its stock.
276
+ * down, cancel it with {@link OrdersModule.cancelWithMoney}: one call, straight
277
+ * out of the park, that refunds its money, credits it to the customer's account
278
+ * or keeps it (with a reason), and gives the reserved stock back. A refund alone
279
+ * leaves it parked, held and holding its stock.
240
280
  *
241
281
  * Calling this on an order the platform ALREADY settled succeeds rather than
242
282
  * refusing. Expect that to be the common case: the engine settles an order as
@@ -267,5 +307,5 @@ export interface OrdersModule extends OrderEntryModule, OrderGetModule, OrderPar
267
307
  export declare const PARK_ORDER_MUTATION = "\n mutation ParkOrder($orderId: ID!, $reason: String, $idempotencyKey: String) {\n parkOrder(orderId: $orderId, reason: $reason, idempotencyKey: $idempotencyKey) {\n id\n code\n state\n currencyCode\n total\n totalWithTax\n }\n }\n";
268
308
  export declare const UNPARK_ORDER_MUTATION = "\n mutation UnparkOrder($orderId: ID!, $idempotencyKey: String) {\n unparkOrder(orderId: $orderId, idempotencyKey: $idempotencyKey) {\n id\n code\n state\n currencyCode\n total\n totalWithTax\n }\n }\n";
269
309
  export declare const SETTLE_ORDER_MUTATION = "\n mutation SettleOrder($orderId: ID!, $fulfil: Boolean!, $idempotencyKey: String) {\n settleOrder(orderId: $orderId, fulfil: $fulfil, idempotencyKey: $idempotencyKey) {\n \n order {\n id\n code\n state\n currencyCode\n total\n totalWithTax\n }\n position {\n total\n covered\n settled\n authorized\n refunded\n outstanding\n overpaid\n availableToCharge\n }\n fulfilRequested\n\n }\n }\n";
270
- export declare const ORDER_POSITION_QUERY = "\n query OrderPosition($orderId: ID!) {\n orderPaymentPosition(orderId: $orderId) {\n total\n covered\n settled\n authorized\n refunded\n outstanding\n overpaid\n availableToCharge\n }\n }\n";
310
+ export declare const ORDER_POSITION_QUERY = "\n query OrderPosition($orderId: ID!) {\n orderPaymentPosition(orderId: $orderId) {\n total\n covered\n settled\n authorized\n refunded\n creditNoted\n owed\n outstanding\n overpaid\n availableToCharge\n }\n }\n";
271
311
  export declare function createOrdersModule(transport: Transport): OrdersModule;
@@ -1,17 +1,27 @@
1
1
  import { NotFoundError } from '@sixtyninecommerce/core';
2
+ import { creditNotedAware } from '../payments/credit-noted-fields.js';
2
3
  import { bulkOrders, deleteOrder, readOrderBulkRun, } from './bulk.js';
4
+ import { createOrderCancelWithMoneyModule, } from './cancel-with-money.js';
3
5
  import { createOrderCommitEditModule } from './commit-edit.js';
4
6
  import { createOrderDepositPolicyModule } from './deposit-policy.js';
7
+ import { createOrderDraftsModule } from './drafts.js';
8
+ import { createOrderFieldsModule } from './fields.js';
5
9
  import { createOrderGetModule } from './get.js';
10
+ import { createOrderLifecycleModule } from './lifecycle.js';
6
11
  import { createOrderLinePricePreviewModule, } from './line-price-preview.js';
12
+ import { createOrderListModule } from './list.js';
7
13
  import { createManualDiscountsModule } from './manual-discounts.js';
8
14
  import { createOrderManualPricingModule } from './manual-pricing.js';
9
15
  import { createOrderEntryModule } from './order-entry.js';
10
16
  import { createOrderParcelChargeModule } from './parcel-charge.js';
11
17
  import { createOrderPlanEditModule } from './plan-edit.js';
18
+ import { createOrderSettingsModule } from './settings.js';
12
19
  import { createOrderStatusModule } from './status.js';
13
20
  import { createSurchargesModule } from './surcharges.js';
14
21
  export { MAX_BULK_ORDERS, ORDER_BULK_ACTIONS, ORDER_BULK_TRANSITION_REFUSED } from './bulk.js';
22
+ export { DraftInsufficientStockError } from './drafts.js';
23
+ export { MAX_ORDER_LIST_TAKE, MAX_RECENT_ORDERS, ORDER_LIST_SORT_FIELDS } from './list.js';
24
+ export { MINIMUM_AGE_MAX, MINIMUM_AGE_MIN, ORDER_CODE_DIGITS_MAX, ORDER_CODE_DIGITS_MIN, ORDER_CODE_PREFIX_MAX_LENGTH, ORDER_SETTINGS_AMOUNT_MAX, ORDER_STATUS_RULE_CONDITION_TYPES, ORDER_STATUS_RULE_TARGET_STATES, } from './settings.js';
15
25
  const ORDER_PROVIDER_FALLBACKS_QUERY = /* GraphQL */ `
16
26
  query OrderProviderFallbacks($id: ID!) {
17
27
  order(id: $id) {
@@ -85,6 +95,8 @@ export const ORDER_POSITION_QUERY = /* GraphQL */ `
85
95
  settled
86
96
  authorized
87
97
  refunded
98
+ creditNoted
99
+ owed
88
100
  outstanding
89
101
  overpaid
90
102
  availableToCharge
@@ -92,18 +104,25 @@ export const ORDER_POSITION_QUERY = /* GraphQL */ `
92
104
  }
93
105
  `;
94
106
  export function createOrdersModule(transport) {
107
+ const getModule = createOrderGetModule(transport);
95
108
  return {
96
109
  ...createOrderEntryModule(transport),
97
- ...createOrderGetModule(transport),
110
+ ...getModule,
111
+ ...createOrderListModule(transport),
98
112
  ...createOrderParcelChargeModule(transport),
99
113
  ...createOrderLinePricePreviewModule(transport),
100
114
  ...createOrderManualPricingModule(transport),
101
115
  ...createOrderPlanEditModule(transport),
102
116
  ...createOrderCommitEditModule(transport),
117
+ ...createOrderCancelWithMoneyModule(transport),
118
+ ...createOrderLifecycleModule(transport),
119
+ ...createOrderFieldsModule(transport),
103
120
  ...createOrderStatusModule(transport),
104
121
  surcharges: createSurchargesModule(transport),
122
+ drafts: createOrderDraftsModule(transport, getModule),
105
123
  manualDiscounts: createManualDiscountsModule(transport),
106
124
  depositPolicy: createOrderDepositPolicyModule(transport),
125
+ settings: createOrderSettingsModule(transport),
107
126
  bulk(input, options) {
108
127
  return bulkOrders(transport, input, options);
109
128
  },
@@ -150,7 +169,8 @@ export function createOrdersModule(transport) {
150
169
  return data.order.providerFallbacks;
151
170
  },
152
171
  async paymentPosition(orderId, options) {
153
- const data = await transport.graphql({ api: 'admin', query: ORDER_POSITION_QUERY, variables: { orderId } }, options);
172
+ // The credit fields fall away on an engine before them: the position itself still reads.
173
+ const data = await creditNotedAware(transport).graphql({ api: 'admin', query: ORDER_POSITION_QUERY, variables: { orderId } }, options);
154
174
  return data.orderPaymentPosition;
155
175
  },
156
176
  async settle(orderId, options) {
@@ -0,0 +1,128 @@
1
+ /**
2
+ * The single-order lifecycle writes (headless spec §9.2 `orders`, "holds, cancel/reopen/complete";
3
+ * W10-25): complete, reopen, waive the payment, hold the fulfilment, move the order to another
4
+ * state, and cancel it whole.
5
+ *
6
+ * Which of them an order allows now, and why not, is `orders.status(orderId).actions`
7
+ * (`MARK_COMPLETED`, `REOPEN`, `SET_PAYMENT_NOT_REQUIRED`, `SET_FULFILLMENT_HOLD`, `TRANSITION`
8
+ * with `nextStates`, `CANCEL`): ask it before offering one. Every refusal below is a coded
9
+ * `PlatformError`; core's own transition refusals carry the gate's reason as their message, never
10
+ * Vendure's "Cannot transition Order from X to Y" template.
11
+ */
12
+ import { type Transport } from '@sixtyninecommerce/core';
13
+ import type { Call } from '../types.js';
14
+ import type { OrderFulfillmentHoldReason } from './get.js';
15
+ /** The order as a lifecycle write leaves it. */
16
+ export interface OrderLifecycleRecord {
17
+ id: string;
18
+ code: string;
19
+ /** The engine state. */
20
+ state: string;
21
+ /**
22
+ * The four projected dimensions (`orders.status` reads the same). Each is null on an order that
23
+ * predates them, and for a moment after a change: the engine writes them after the change.
24
+ */
25
+ lifecycle: {
26
+ status: string | null;
27
+ payment: string | null;
28
+ fulfillment: string | null;
29
+ return: string | null;
30
+ };
31
+ }
32
+ /** Putting a hold on (`hold: true`, with a reason) or releasing it (`hold: false`, nothing else). */
33
+ export type FulfillmentHoldInput = {
34
+ hold: true;
35
+ reason: OrderFulfillmentHoldReason;
36
+ /** At most 500 characters. Required for `other`. */
37
+ note?: string | null;
38
+ } | {
39
+ hold: false;
40
+ };
41
+ export interface OrderLifecycleModule {
42
+ /**
43
+ * Mark the order completed. Needs `UpdateOrder`.
44
+ *
45
+ * Refused `ORDER_ALREADY_COMPLETED` on a completed order and `ORDER_COMPLETE_CANCELLED` on a
46
+ * cancelled one (`BusinessRuleError`, 422); nothing changes. Against an engine older than these
47
+ * codes the same call succeeded without changing anything.
48
+ *
49
+ * @effect write
50
+ */
51
+ markCompleted(orderId: string, options?: Call): Promise<OrderLifecycleRecord>;
52
+ /**
53
+ * Reopen a completed order. Needs `UpdateOrder`. Does nothing to an order that is not
54
+ * completed. Refused `ORDER_REOPEN_LOCKED` (422) while an invoice locks the order: an invoiced
55
+ * order is corrected by void & reissue, not reopened.
56
+ *
57
+ * @effect write
58
+ */
59
+ reopen(orderId: string, options?: Call): Promise<OrderLifecycleRecord>;
60
+ /**
61
+ * Waive the payment the order expects (`notRequired: true`: a comp, a sample) or lift the
62
+ * waiver (`false`). The payment dimension reads `not_required` while waived. Needs
63
+ * `UpdateOrder`.
64
+ *
65
+ * Refused `ORDER_PAYMENT_WAIVER_REFUSED` (422) on a cancelled order either way, and when
66
+ * waiving an order an invoice still bills: correct the invoice first (`orders.status` answers
67
+ * `CREDIT_NOTE_REQUIRED`). Lifting a waiver is otherwise never refused.
68
+ *
69
+ * @effect money
70
+ */
71
+ setPaymentNotRequired(orderId: string, notRequired: boolean, options?: Call): Promise<OrderLifecycleRecord>;
72
+ /**
73
+ * Put the order's fulfilment on hold with a reason, or release it. Re-holding replaces the
74
+ * reason and note. Both directions write a private (staff-only) history entry. Needs
75
+ * `UpdateOrder`.
76
+ *
77
+ * Refused `ORDER_FULFILLMENT_HOLD_INVALID` (`ValidationError`, 400) for an unknown reason, a
78
+ * note over 500 characters, or `other` without a note. `orders.status` offers a NEW hold on an
79
+ * open order only (`SET_FULFILLMENT_HOLD`), and a release on any order holding one.
80
+ *
81
+ * @effect write
82
+ */
83
+ setFulfillmentHold(orderId: string, input: FulfillmentHoldInput, options?: Call): Promise<OrderLifecycleRecord>;
84
+ /**
85
+ * Move the order to one of `orders.status(orderId).nextStates`. Needs `UpdateOrder`.
86
+ *
87
+ * A move into `PaymentSettled`, or into `PaymentAuthorized` from the unpaid side, is refused
88
+ * `COVERAGE_INSUFFICIENT` (422) while the order's money does not cover it (settled money for
89
+ * `PaymentSettled`; a net-terms order is judged when it was authorized): it never settles an
90
+ * order without its money (`nextStates` already leaves such a move out). A move into
91
+ * `Cancelled` is a cancel, and refused as {@link OrderLifecycleModule.cancel} is. Any other
92
+ * refusal is core's `ORDER_STATE_TRANSITION_ERROR` with the gate's reason as its message (an
93
+ * order minimum, unconfirmed terms, a stock shortage).
94
+ *
95
+ * @effect money
96
+ */
97
+ transition(orderId: string, state: string, options?: Call): Promise<OrderLifecycleRecord>;
98
+ /**
99
+ * Cancel the WHOLE order, shipping included. An order cannot be un-cancelled. Needs
100
+ * `UpdateOrder`. Lines alone are cancelled through `orders.commitEdit`.
101
+ *
102
+ * It moves no money. Refused:
103
+ * - `ORDER_HOLDS_MONEY` (422) while the order has been placed or parked and still holds money:
104
+ * use `orders.cancelWithMoney`, which decides what happens to it;
105
+ * - `ORDER_CANCEL_CREDIT_NOTE_CONFLICT` (409) while an invoice still bills the order, paid or
106
+ * not: do what `orders.status(orderId).cancelCreditNote.remedy` says first;
107
+ * - `ORDER_UNITS_SHIPPED` / `ORDER_HAS_ACTIVE_FULFILLMENT` (422) while a fulfilment holds a
108
+ * line; `ORDER_CART_NOT_CANCELLABLE` (422) for a live cart the store may not end;
109
+ * - `LOCATION_OUT_OF_SCOPE` (422), for a credential restricted to stock locations (an API
110
+ * token or app installation with `locationIds`) only: the order's stock is reserved at a
111
+ * location outside its restriction, and a cancel releases it there
112
+ * (`orders.status(orderId)` answers `CANCEL` with `PERMISSION`);
113
+ * - core's own refusals (`ORDER_STATE_TRANSITION_ERROR`, `CANCEL_ACTIVE_ORDER_ERROR`,
114
+ * `EMPTY_ORDER_LINE_SELECTION_ERROR`) with their reason.
115
+ *
116
+ * @effect irreversible
117
+ */
118
+ cancel(orderId: string, options?: Call & {
119
+ reason?: string;
120
+ }): Promise<OrderLifecycleRecord>;
121
+ }
122
+ export declare const MARK_ORDER_COMPLETED_MUTATION = "\n mutation MarkOrderCompleted($orderId: ID!) {\n markOrderCompleted(orderId: $orderId) {\n \n id\n code\n state\n customFields {\n lifecycleStatus\n paymentStatus\n fulfillmentStatus\n returnStatus\n }\n\n }\n }\n";
123
+ export declare const REOPEN_ORDER_MUTATION = "\n mutation ReopenOrder($orderId: ID!) {\n reopenOrder(orderId: $orderId) {\n \n id\n code\n state\n customFields {\n lifecycleStatus\n paymentStatus\n fulfillmentStatus\n returnStatus\n }\n\n }\n }\n";
124
+ export declare const MARK_ORDER_PAYMENT_NOT_REQUIRED_MUTATION = "\n mutation MarkOrderPaymentNotRequired($orderId: ID!, $notRequired: Boolean!) {\n markOrderPaymentNotRequired(orderId: $orderId, notRequired: $notRequired) {\n \n id\n code\n state\n customFields {\n lifecycleStatus\n paymentStatus\n fulfillmentStatus\n returnStatus\n }\n\n }\n }\n";
125
+ export declare const SET_ORDER_FULFILLMENT_HOLD_MUTATION = "\n mutation SetOrderFulfillmentHold(\n $orderId: ID!\n $onHold: Boolean!\n $reason: FulfillmentHoldReason\n $note: String\n ) {\n setOrderFulfillmentHold(orderId: $orderId, onHold: $onHold, reason: $reason, note: $note) {\n \n id\n code\n state\n customFields {\n lifecycleStatus\n paymentStatus\n fulfillmentStatus\n returnStatus\n }\n\n }\n }\n";
126
+ export declare const TRANSITION_ORDER_MUTATION = "\n mutation TransitionOrderToState($id: ID!, $state: String!) {\n transitionOrderToState(id: $id, state: $state) {\n __typename\n ... on Order {\n \n id\n code\n state\n customFields {\n lifecycleStatus\n paymentStatus\n fulfillmentStatus\n returnStatus\n }\n\n }\n ... on OrderStateTransitionError {\n transitionError\n }\n ... on ErrorResult {\n errorCode\n message\n }\n }\n }\n";
127
+ export declare const CANCEL_ORDER_MUTATION = "\n mutation CancelOrder($input: CancelOrderInput!) {\n cancelOrder(input: $input) {\n __typename\n ... on Order {\n \n id\n code\n state\n customFields {\n lifecycleStatus\n paymentStatus\n fulfillmentStatus\n returnStatus\n }\n\n }\n ... on OrderStateTransitionError {\n transitionError\n }\n ... on ErrorResult {\n errorCode\n message\n }\n }\n }\n";
128
+ export declare function createOrderLifecycleModule(transport: Transport): OrderLifecycleModule;
@@ -0,0 +1,158 @@
1
+ /**
2
+ * The single-order lifecycle writes (headless spec §9.2 `orders`, "holds, cancel/reopen/complete";
3
+ * W10-25): complete, reopen, waive the payment, hold the fulfilment, move the order to another
4
+ * state, and cancel it whole.
5
+ *
6
+ * Which of them an order allows now, and why not, is `orders.status(orderId).actions`
7
+ * (`MARK_COMPLETED`, `REOPEN`, `SET_PAYMENT_NOT_REQUIRED`, `SET_FULFILLMENT_HOLD`, `TRANSITION`
8
+ * with `nextStates`, `CANCEL`): ask it before offering one. Every refusal below is a coded
9
+ * `PlatformError`; core's own transition refusals carry the gate's reason as their message, never
10
+ * Vendure's "Cannot transition Order from X to Y" template.
11
+ */
12
+ import { errorFromErrorResult, isErrorResult } from '@sixtyninecommerce/core';
13
+ const ORDER_FIELDS = /* GraphQL */ `
14
+ id
15
+ code
16
+ state
17
+ customFields {
18
+ lifecycleStatus
19
+ paymentStatus
20
+ fulfillmentStatus
21
+ returnStatus
22
+ }
23
+ `;
24
+ export const MARK_ORDER_COMPLETED_MUTATION = /* GraphQL */ `
25
+ mutation MarkOrderCompleted($orderId: ID!) {
26
+ markOrderCompleted(orderId: $orderId) {
27
+ ${ORDER_FIELDS}
28
+ }
29
+ }
30
+ `;
31
+ export const REOPEN_ORDER_MUTATION = /* GraphQL */ `
32
+ mutation ReopenOrder($orderId: ID!) {
33
+ reopenOrder(orderId: $orderId) {
34
+ ${ORDER_FIELDS}
35
+ }
36
+ }
37
+ `;
38
+ export const MARK_ORDER_PAYMENT_NOT_REQUIRED_MUTATION = /* GraphQL */ `
39
+ mutation MarkOrderPaymentNotRequired($orderId: ID!, $notRequired: Boolean!) {
40
+ markOrderPaymentNotRequired(orderId: $orderId, notRequired: $notRequired) {
41
+ ${ORDER_FIELDS}
42
+ }
43
+ }
44
+ `;
45
+ export const SET_ORDER_FULFILLMENT_HOLD_MUTATION = /* GraphQL */ `
46
+ mutation SetOrderFulfillmentHold(
47
+ $orderId: ID!
48
+ $onHold: Boolean!
49
+ $reason: FulfillmentHoldReason
50
+ $note: String
51
+ ) {
52
+ setOrderFulfillmentHold(orderId: $orderId, onHold: $onHold, reason: $reason, note: $note) {
53
+ ${ORDER_FIELDS}
54
+ }
55
+ }
56
+ `;
57
+ // The concrete members are selected for their sentences: `ErrorResult.message` is a per-code
58
+ // template, and the refusing gate's reason lives on the concrete type alone.
59
+ export const TRANSITION_ORDER_MUTATION = /* GraphQL */ `
60
+ mutation TransitionOrderToState($id: ID!, $state: String!) {
61
+ transitionOrderToState(id: $id, state: $state) {
62
+ __typename
63
+ ... on Order {
64
+ ${ORDER_FIELDS}
65
+ }
66
+ ... on OrderStateTransitionError {
67
+ transitionError
68
+ }
69
+ ... on ErrorResult {
70
+ errorCode
71
+ message
72
+ }
73
+ }
74
+ }
75
+ `;
76
+ export const CANCEL_ORDER_MUTATION = /* GraphQL */ `
77
+ mutation CancelOrder($input: CancelOrderInput!) {
78
+ cancelOrder(input: $input) {
79
+ __typename
80
+ ... on Order {
81
+ ${ORDER_FIELDS}
82
+ }
83
+ ... on OrderStateTransitionError {
84
+ transitionError
85
+ }
86
+ ... on ErrorResult {
87
+ errorCode
88
+ message
89
+ }
90
+ }
91
+ }
92
+ `;
93
+ function recordOf(order) {
94
+ const fields = order.customFields ?? {};
95
+ return {
96
+ id: order.id,
97
+ code: order.code,
98
+ state: order.state,
99
+ lifecycle: {
100
+ status: fields.lifecycleStatus ?? null,
101
+ payment: fields.paymentStatus ?? null,
102
+ fulfillment: fields.fulfillmentStatus ?? null,
103
+ return: fields.returnStatus ?? null,
104
+ },
105
+ };
106
+ }
107
+ /** The order, or the union member thrown as a coded error carrying the gate's own reason. */
108
+ function orderOrThrow(result) {
109
+ if (!isErrorResult(result))
110
+ return recordOf(result);
111
+ const reason = result.transitionError;
112
+ const message = typeof reason === 'string' && reason.trim() !== '' ? reason : result.message;
113
+ throw errorFromErrorResult({ errorCode: result.errorCode, message });
114
+ }
115
+ export function createOrderLifecycleModule(transport) {
116
+ const write = async (field, query, variables, options) => {
117
+ const data = await transport.graphql({ api: 'admin', query, variables }, options);
118
+ return recordOf(data[field]);
119
+ };
120
+ return {
121
+ markCompleted(orderId, options) {
122
+ return write('markOrderCompleted', MARK_ORDER_COMPLETED_MUTATION, { orderId }, options);
123
+ },
124
+ reopen(orderId, options) {
125
+ return write('reopenOrder', REOPEN_ORDER_MUTATION, { orderId }, options);
126
+ },
127
+ setPaymentNotRequired(orderId, notRequired, options) {
128
+ return write('markOrderPaymentNotRequired', MARK_ORDER_PAYMENT_NOT_REQUIRED_MUTATION, { orderId, notRequired }, options);
129
+ },
130
+ setFulfillmentHold(orderId, input, options) {
131
+ // A release sends neither a reason nor a note: the engine refuses them there.
132
+ const variables = input.hold
133
+ ? { orderId, onHold: true, reason: input.reason, note: input.note ?? null }
134
+ : { orderId, onHold: false };
135
+ return write('setOrderFulfillmentHold', SET_ORDER_FULFILLMENT_HOLD_MUTATION, variables, options);
136
+ },
137
+ async transition(orderId, state, options) {
138
+ const data = await transport.graphql({ api: 'admin', query: TRANSITION_ORDER_MUTATION, variables: { id: orderId, state } }, options);
139
+ const result = data.transitionOrderToState;
140
+ if (!result) {
141
+ throw errorFromErrorResult({
142
+ errorCode: 'ORDER_NOT_FOUND',
143
+ message: `This store has no order ${orderId}.`,
144
+ });
145
+ }
146
+ return orderOrThrow(result);
147
+ },
148
+ async cancel(orderId, options) {
149
+ const data = await transport.graphql({
150
+ api: 'admin',
151
+ query: CANCEL_ORDER_MUTATION,
152
+ // `undefined`, never an explicit null: an omitted reason stays off the wire.
153
+ variables: { input: { orderId, reason: options?.reason, cancelShipping: true } },
154
+ }, options);
155
+ return orderOrThrow(data.cancelOrder);
156
+ },
157
+ };
158
+ }
@@ -224,8 +224,8 @@ export interface OrderLinePricePreviewModule {
224
224
  * validated, tax removed) does not show in such a line's figures, so the
225
225
  * comparison above does not see it.
226
226
  *
227
- * The preview does not
228
- * predict what a save refuses: a staged one-time discount that the Admin
227
+ * Apart from the clears listed under the refusals below, the preview does
228
+ * not predict what a save refuses: a staged one-time discount that the Admin
229
229
  * API's `setOrderPriceListDiscounts` would refuse is still priced, and shows
230
230
  * no `ONE_TIME` step when the pricing rules skipped it.
231
231
  *
@@ -289,6 +289,11 @@ export interface OrderLinePricePreviewModule {
289
289
  * preview does not evaluate (`PreviewLinePriceOverride.basis`).
290
290
  * - `PREVIEW_CHANNEL_NOT_ALLOWED` (`PermissionDeniedError`, 403): the call
291
291
  * was made from the default channel instead of the order's own.
292
+ * - `ORDER_LINE_VARIANT_UNPRICED` (`BusinessRuleError`, 422; absent from an
293
+ * engine released before 2026-10-10): `override: null` on a line that
294
+ * states a manual price while its variant has no price in the store, as
295
+ * the save refuses it; stage the price you want, or set a price for the
296
+ * variant in the store first.
292
297
  */
293
298
  previewLinePrices(orderId: string, lines: PreviewLinePriceLine[], options?: Call & {
294
299
  orderDiscount?: PreviewOneTimeDiscount | null;