@sixtyninecommerce/admin 0.9.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 (258) hide show
  1. package/README.md +4598 -128
  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 +318 -17
  9. package/dist/catalog/products.js +182 -14
  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 +282 -25
  21. package/dist/catalog/variants.js +173 -25
  22. package/dist/catalog/visibility.d.ts +20 -5
  23. package/dist/catalog/visibility.js +19 -1
  24. package/dist/client.d.ts +116 -9
  25. package/dist/client.js +41 -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 +121 -10
  63. package/dist/fulfillments/index.js +120 -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 +129 -30
  71. package/dist/index.js +47 -9
  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 +40 -0
  87. package/dist/integrations/index.js +24 -0
  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 +114 -0
  91. package/dist/integrations/pipelines.js +46 -0
  92. package/dist/integrations/types.d.ts +322 -0
  93. package/dist/integrations/types.js +8 -0
  94. package/dist/jobs/bulk-action-run.d.ts +11 -2
  95. package/dist/jobs/bulk-action-run.js +4 -5
  96. package/dist/locations/index.d.ts +66 -0
  97. package/dist/locations/index.js +31 -0
  98. package/dist/meta/index.d.ts +162 -0
  99. package/dist/orders/bulk.d.ts +75 -0
  100. package/dist/orders/bulk.js +150 -0
  101. package/dist/orders/cancel-with-money.d.ts +227 -0
  102. package/dist/orders/cancel-with-money.js +153 -0
  103. package/dist/orders/commit-edit.d.ts +7 -1
  104. package/dist/orders/commit-edit.js +5 -1
  105. package/dist/orders/deposit-policy.d.ts +103 -0
  106. package/dist/orders/deposit-policy.js +202 -0
  107. package/dist/orders/drafts.d.ts +800 -0
  108. package/dist/orders/drafts.js +771 -0
  109. package/dist/orders/fields.d.ts +245 -0
  110. package/dist/orders/fields.js +188 -0
  111. package/dist/orders/get.d.ts +29 -19
  112. package/dist/orders/get.js +17 -8
  113. package/dist/orders/index.d.ts +125 -5
  114. package/dist/orders/index.js +35 -2
  115. package/dist/orders/lifecycle.d.ts +128 -0
  116. package/dist/orders/lifecycle.js +158 -0
  117. package/dist/orders/line-price-preview.d.ts +7 -2
  118. package/dist/orders/list.d.ts +222 -0
  119. package/dist/orders/list.js +377 -0
  120. package/dist/orders/manual-discounts.d.ts +11 -2
  121. package/dist/orders/manual-discounts.js +2 -0
  122. package/dist/orders/manual-pricing.d.ts +5 -0
  123. package/dist/orders/order-entry.d.ts +20 -7
  124. package/dist/orders/plan-edit.d.ts +1 -1
  125. package/dist/orders/plan-edit.js +4 -1
  126. package/dist/orders/settings.d.ts +201 -0
  127. package/dist/orders/settings.js +325 -0
  128. package/dist/orders/status.d.ts +159 -13
  129. package/dist/orders/status.js +21 -0
  130. package/dist/orders/surcharges.d.ts +8 -1
  131. package/dist/orders/surcharges.js +3 -2
  132. package/dist/payments/account-credit.d.ts +30 -0
  133. package/dist/payments/account-credit.js +19 -0
  134. package/dist/payments/ar.d.ts +292 -0
  135. package/dist/payments/ar.js +223 -0
  136. package/dist/payments/connected-account.d.ts +47 -0
  137. package/dist/payments/connected-account.js +61 -0
  138. package/dist/payments/credit-noted-fields.d.ts +12 -0
  139. package/dist/payments/credit-noted-fields.js +37 -0
  140. package/dist/payments/index.d.ts +263 -10
  141. package/dist/payments/index.js +133 -1
  142. package/dist/payments/methods.d.ts +332 -0
  143. package/dist/payments/methods.js +363 -0
  144. package/dist/payments/mollie-methods.d.ts +159 -0
  145. package/dist/payments/mollie-methods.js +141 -0
  146. package/dist/payments/payment-links.d.ts +180 -0
  147. package/dist/payments/payment-links.js +97 -0
  148. package/dist/payments/provider-keys.d.ts +150 -0
  149. package/dist/payments/provider-keys.js +118 -0
  150. package/dist/payments/providers.d.ts +86 -11
  151. package/dist/payments/providers.js +29 -0
  152. package/dist/payments/requests.d.ts +144 -0
  153. package/dist/payments/requests.js +92 -0
  154. package/dist/payments/store-credit-fields.d.ts +15 -0
  155. package/dist/payments/store-credit-fields.js +51 -0
  156. package/dist/pickups/index.d.ts +104 -0
  157. package/dist/pickups/index.js +105 -0
  158. package/dist/platform/channels.d.ts +132 -0
  159. package/dist/platform/channels.js +128 -0
  160. package/dist/platform/geo.d.ts +123 -0
  161. package/dist/platform/geo.js +144 -0
  162. package/dist/platform/tax.d.ts +154 -0
  163. package/dist/platform/tax.js +139 -0
  164. package/dist/pos/anomalies.d.ts +158 -0
  165. package/dist/pos/anomalies.js +64 -0
  166. package/dist/pos/assisted-selling.d.ts +79 -0
  167. package/dist/pos/assisted-selling.js +38 -0
  168. package/dist/pos/exchanges.d.ts +103 -0
  169. package/dist/pos/exchanges.js +22 -0
  170. package/dist/pos/gift-cards.d.ts +135 -0
  171. package/dist/pos/gift-cards.js +47 -0
  172. package/dist/pos/index.d.ts +2125 -32
  173. package/dist/pos/index.js +742 -4
  174. package/dist/pos/no-receipt.d.ts +94 -0
  175. package/dist/pos/no-receipt.js +25 -0
  176. package/dist/pos/offline-sales.d.ts +187 -0
  177. package/dist/pos/offline-sales.js +116 -0
  178. package/dist/pos/pay-by-link.d.ts +143 -0
  179. package/dist/pos/pay-by-link.js +57 -0
  180. package/dist/pos/quick-keys.d.ts +103 -0
  181. package/dist/pos/quick-keys.js +45 -0
  182. package/dist/pos/reports.d.ts +360 -0
  183. package/dist/pos/reports.js +62 -0
  184. package/dist/pos/returns.d.ts +217 -0
  185. package/dist/pos/returns.js +53 -0
  186. package/dist/pricing/bulk-coupons.d.ts +139 -0
  187. package/dist/pricing/bulk-coupons.js +112 -0
  188. package/dist/pricing/index.d.ts +177 -4
  189. package/dist/pricing/index.js +176 -1
  190. package/dist/pricing/price-lists.d.ts +604 -0
  191. package/dist/pricing/price-lists.js +600 -0
  192. package/dist/pricing/vouchers.d.ts +103 -0
  193. package/dist/pricing/vouchers.js +69 -0
  194. package/dist/purchasing/alerts.d.ts +89 -0
  195. package/dist/purchasing/alerts.js +62 -0
  196. package/dist/purchasing/cost.d.ts +110 -0
  197. package/dist/purchasing/cost.js +86 -0
  198. package/dist/purchasing/index.d.ts +36 -0
  199. package/dist/purchasing/index.js +16 -0
  200. package/dist/purchasing/purchase-orders.d.ts +548 -0
  201. package/dist/purchasing/purchase-orders.js +491 -0
  202. package/dist/purchasing/replenishment.d.ts +281 -0
  203. package/dist/purchasing/replenishment.js +240 -0
  204. package/dist/purchasing/settings.d.ts +152 -0
  205. package/dist/purchasing/settings.js +181 -0
  206. package/dist/purchasing/suppliers.d.ts +476 -0
  207. package/dist/purchasing/suppliers.js +438 -0
  208. package/dist/quotes/index.d.ts +501 -0
  209. package/dist/quotes/index.js +439 -0
  210. package/dist/reports/index.d.ts +71 -8
  211. package/dist/reports/index.js +74 -11
  212. package/dist/returns/index.d.ts +818 -0
  213. package/dist/returns/index.js +844 -0
  214. package/dist/search/index.d.ts +174 -0
  215. package/dist/search/index.js +125 -0
  216. package/dist/shipping/definitions.d.ts +29 -0
  217. package/dist/shipping/definitions.js +47 -0
  218. package/dist/shipping/fulfillment-profiles.d.ts +174 -0
  219. package/dist/shipping/fulfillment-profiles.js +104 -0
  220. package/dist/shipping/hendriks.d.ts +97 -0
  221. package/dist/shipping/hendriks.js +50 -0
  222. package/dist/shipping/index.d.ts +48 -0
  223. package/dist/shipping/index.js +25 -0
  224. package/dist/shipping/methods.d.ts +198 -0
  225. package/dist/shipping/methods.js +240 -0
  226. package/dist/shipping/myparcel.d.ts +254 -0
  227. package/dist/shipping/myparcel.js +178 -0
  228. package/dist/shipping/parcel-count-suggestion.d.ts +2 -0
  229. package/dist/shipping/parcel-rule.d.ts +6 -5
  230. package/dist/shipping/parcel-rule.js +21 -23
  231. package/dist/shipping/rate-tables.d.ts +179 -0
  232. package/dist/shipping/rate-tables.js +184 -0
  233. package/dist/stock/index.d.ts +10 -3
  234. package/dist/stock/index.js +3 -0
  235. package/dist/stock/locations.d.ts +144 -0
  236. package/dist/stock/locations.js +168 -0
  237. package/dist/stock/transfers.d.ts +216 -43
  238. package/dist/stock/transfers.js +140 -13
  239. package/dist/stored-value/index.d.ts +214 -4
  240. package/dist/stored-value/index.js +152 -0
  241. package/dist/subscriptions/index.d.ts +682 -0
  242. package/dist/subscriptions/index.js +815 -0
  243. package/dist/tax/index.d.ts +76 -1
  244. package/dist/tax/index.js +50 -0
  245. package/dist/tenant/email-style.d.ts +102 -0
  246. package/dist/tenant/email-style.js +72 -0
  247. package/dist/tenant/email-templates.d.ts +66 -0
  248. package/dist/tenant/email-templates.js +54 -0
  249. package/dist/tenant/notifications.d.ts +23 -17
  250. package/dist/tenant/settings-sources.d.ts +1 -1
  251. package/dist/tenant/time-zone.d.ts +17 -0
  252. package/dist/tenant/time-zone.js +11 -0
  253. package/dist/types.d.ts +51 -4
  254. package/dist/users/index.d.ts +3 -0
  255. package/dist/users/index.js +2 -0
  256. package/dist/users/warehouses.d.ts +50 -0
  257. package/dist/users/warehouses.js +51 -0
  258. package/package.json +2 -2
@@ -1,19 +1,39 @@
1
1
  import { type Transport } from '@sixtyninecommerce/core';
2
+ import type { JobHandle } from '../jobs/index.js';
2
3
  import type { OrderPaymentPosition, PaidOrder } from '../payments/index.js';
3
4
  import type { Call } from '../types.js';
5
+ import { type OrderBulkInput, type OrderBulkRun } from './bulk.js';
6
+ import { type OrderCancelWithMoneyModule } from './cancel-with-money.js';
4
7
  import { type OrderCommitEditModule } from './commit-edit.js';
8
+ import { type OrderDepositPolicyModule } from './deposit-policy.js';
9
+ import { type OrderDraftsModule } from './drafts.js';
10
+ import { type OrderFieldsModule } from './fields.js';
5
11
  import { type OrderGetModule } from './get.js';
12
+ import { type OrderLifecycleModule } from './lifecycle.js';
6
13
  import { type OrderLinePricePreviewModule } from './line-price-preview.js';
14
+ import { type OrderListModule } from './list.js';
7
15
  import { type ManualDiscountsModule } from './manual-discounts.js';
8
16
  import { type OrderManualPricingModule } from './manual-pricing.js';
9
17
  import { type OrderEntryModule } from './order-entry.js';
10
18
  import { type OrderParcelChargeModule } from './parcel-charge.js';
11
19
  import { type OrderPlanEditModule } from './plan-edit.js';
20
+ import { type OrderSettingsModule } from './settings.js';
12
21
  import { type OrderStatusModule } from './status.js';
13
22
  import { type SurchargesModule } from './surcharges.js';
14
23
  export type { PaidOrder } from '../payments/index.js';
24
+ export type { OrderBulkAction, OrderBulkCapture, OrderBulkInput, OrderBulkItem, OrderBulkRun, } from './bulk.js';
25
+ export { MAX_BULK_ORDERS, ORDER_BULK_ACTIONS, ORDER_BULK_TRANSITION_REFUSED } from './bulk.js';
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';
15
33
  export type { DiscountPolicy, DiscountPolicyInput, DiscountPolicyModule, DiscountReason, DiscountReasonInput, DiscountReasonsModule, ManualDiscountsModule, OrderManualDiscount, } from './manual-discounts.js';
16
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';
17
37
  /** An app provider an order is running without (`admin.orders.providerFallbacks`). */
18
38
  export interface OrderProviderFallback {
19
39
  /** `shipping.rates` or `tax.calculate`. */
@@ -64,8 +84,14 @@ export interface OrderSettlement {
64
84
  * The manual pricing doors (`setLinePrices`, `setOneTimeDiscounts`) sit there too, beside their
65
85
  * read twin `previewLinePrices`, which prices the same changes without saving them.
66
86
  */
67
- 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 {
68
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;
69
95
  /**
70
96
  * Manual discounts with a reason (incentives spec §4 decision 6): read an order's records,
71
97
  * and the store's reason list and policy (`reasons`, `policy`). A discount itself is given
@@ -73,6 +99,93 @@ export interface OrdersModule extends OrderEntryModule, OrderGetModule, OrderPar
73
99
  * `setOneTimeDiscounts` on this module.
74
100
  */
75
101
  manualDiscounts: ManualDiscountsModule;
102
+ /**
103
+ * Move, cancel, delete or mark paid up to `MAX_BULK_ORDERS` (50) orders of the store in ONE
104
+ * call (headless spec §7 `orders.bulk`; rulings G19, G28).
105
+ *
106
+ * **The run is a job.** The call answers a receipt (`runId`) once the run is queued;
107
+ * `handle.wait()` polls it until it ends and resolves with the run, whatever the ending.
108
+ * `bulkRun(runId)` reads it again later, from any process. Each order's outcome is in
109
+ * `run.items`, in the order the ids were named.
110
+ *
111
+ * **Each order is judged as on its own page, and succeeds or fails alone.** First by its own
112
+ * status (`orders.status`): an action the order's status does not offer, or a TRANSITION target
113
+ * outside the order's own `nextStates`, answers `ORDER_ACTION_UNAVAILABLE` with `reasonCode`
114
+ * (that read's vocabulary), before anything is written. Then by its single door, under the
115
+ * door's own lock, with the door's own code: `ORDER_STATE_TRANSITION_ERROR` (and core's other
116
+ * order codes), `ORDER_CART_NOT_CANCELLABLE`, `ORDER_UNITS_SHIPPED`,
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.
120
+ *
121
+ * - `TRANSITION` (`toState` required): as `transitionOrderToState`. Never `Cancelled` (use
122
+ * `CANCEL`), `PaymentSettled` (use `MARK_PAID`), `Modifying` or `AddingItems`.
123
+ * - `CANCEL` (`reason` optional): the whole order, shipping included, as `cancelOrder`. **It
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.
132
+ * - `DELETE`: a draft or a cart holding no payment or stock movement, as `deleteOrder`.
133
+ * - `MARK_PAID`: **captures** each payment of the order that is `Authorized` when the run reaches
134
+ * it, read by the engine (never your list's copy), each as `settlePayment` and on its own
135
+ * (ruling G19). Each order's `captured` lists every payment acted on. **A decline is a result,
136
+ * not a retry:** the order answers `SETTLE_PAYMENT_ERROR`, the payment keeps the state the
137
+ * provider left, and the run never asks again. **An unknown provider answer must be
138
+ * reconciled, never retried blind:** `IDEMPOTENCY_OUTCOME_UNKNOWN` means the provider was asked
139
+ * and its answer was lost; check the payment with the provider. `IDEMPOTENCY_IN_PROGRESS` means
140
+ * a capture under the same request may still be running. An order with no authorized payment
141
+ * answers `NOTHING_TO_CAPTURE`: it is never marked paid without money (ruling G28).
142
+ *
143
+ * **Idempotency.** `options.idempotencyKey` (minted when omitted): the same key with the same
144
+ * input answers the SAME run, so a resubmit never captures twice; another input under the key is
145
+ * `IDEMPOTENCY_CONFLICT` (409 `ConflictError`). Each order, and each capture, is keyed within the
146
+ * run, so a run the platform processes again (a worker restart) answers what it already did from
147
+ * that record and never asks a provider twice.
148
+ *
149
+ * **No dry run.** The refusals that matter are the doors' own, made under their locks, so a
150
+ * rehearsal could answer "ok" for an order the real run refuses.
151
+ *
152
+ * Needs `UpdateOrder` (`DeleteOrder` for `DELETE`); reading the run needs `ReadOrder`. Refusals
153
+ * of the call itself (nothing is queued): `BULK_ACTION_INPUT_INVALID` (`ValidationError`, 400:
154
+ * no orders, more than 50, one named twice, an unknown action, a missing or refused `toState`,
155
+ * an option the action takes none of; refused before sending too), `BULK_ACTION_NOT_ALLOWED`
156
+ * (`PermissionDeniedError`, 403), `IDEMPOTENCY_CONFLICT`.
157
+ *
158
+ * Platform releases before this method do not have the mutation and refuse it as
159
+ * `ValidationError` `GRAPHQL_VALIDATION_FAILED` (400): deploy the engine first.
160
+ */
161
+ bulk(input: OrderBulkInput, options?: Call): Promise<JobHandle<OrderBulkRun>>;
162
+ /**
163
+ * One read of a bulk order run, by the `runId` `bulk()` answered. A run of another store, or one
164
+ * that does not exist, is `BULK_ACTION_RUN_NOT_FOUND` (`NotFoundError`, 404).
165
+ */
166
+ bulkRun(runId: string, options?: Call): Promise<OrderBulkRun>;
167
+ /**
168
+ * Delete ONE order: a draft or a cart (`AddingItems`) holding no payment and no stock movement,
169
+ * as the order page's Delete (ruling G29). Needs `DeleteOrder`. Anything else is kept:
170
+ * `ORDER_INVOICE_LOCKED` (an invoiced order, for every caller), `ORDER_HAS_RECORDS` (cancel it
171
+ * instead: `orders.bulk` with `CANCEL`), or `ORDER_NOT_DELETED` (`ConflictError`, 409, as every `*_NOT_DELETED` of this SDK) with
172
+ * the engine's own reason for an order in another state, or one this store does not have.
173
+ * Placed orders are cancelled, never deleted.
174
+ */
175
+ delete(orderId: string, options?: Call): Promise<void>;
176
+ /**
177
+ * The store's deposit policy (`orderDepositPolicy`): whether staff may take a
178
+ * deposit and {@link OrdersModule.park} an order, the minimum a deposit must be,
179
+ * and whether a shopper may pay one at checkout. `get` answers what the engine
180
+ * applies; `set` replaces it, validated against the schema's bounds first.
181
+ */
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;
76
189
  /**
77
190
  * Hold a placed order while the rest of its money is arranged. Needs
78
191
  * `UpdateOrder`.
@@ -128,7 +241,12 @@ export interface OrdersModule extends OrderEntryModule, OrderGetModule, OrderPar
128
241
  * position.
129
242
  */
130
243
  unpark(orderId: string, options?: Call): Promise<PaidOrder>;
131
- /** 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
+ */
132
250
  paymentPosition(orderId: string, options?: Call): Promise<OrderPaymentPosition>;
133
251
  /**
134
252
  * Move a fully paid order to `PaymentSettled`. Needs `UpdateOrder`.
@@ -155,8 +273,10 @@ export interface OrdersModule extends OrderEntryModule, OrderGetModule, OrderPar
155
273
  * is covered only by an AUTHORIZED payment owes nothing and is refused
156
274
  * `COVERAGE_INSUFFICIENT` with the hold kept: accept it by capturing that
157
275
  * payment with `settlePayment`, which settles and places it. To turn the order
158
- * down, refund the payment, then {@link OrdersModule.unpark} and cancel it: a
159
- * 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.
160
280
  *
161
281
  * Calling this on an order the platform ALREADY settled succeeds rather than
162
282
  * refusing. Expect that to be the common case: the engine settles an order as
@@ -187,5 +307,5 @@ export interface OrdersModule extends OrderEntryModule, OrderGetModule, OrderPar
187
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";
188
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";
189
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";
190
- 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";
191
311
  export declare function createOrdersModule(transport: Transport): OrdersModule;
@@ -1,14 +1,27 @@
1
1
  import { NotFoundError } from '@sixtyninecommerce/core';
2
+ import { creditNotedAware } from '../payments/credit-noted-fields.js';
3
+ import { bulkOrders, deleteOrder, readOrderBulkRun, } from './bulk.js';
4
+ import { createOrderCancelWithMoneyModule, } from './cancel-with-money.js';
2
5
  import { createOrderCommitEditModule } from './commit-edit.js';
6
+ import { createOrderDepositPolicyModule } from './deposit-policy.js';
7
+ import { createOrderDraftsModule } from './drafts.js';
8
+ import { createOrderFieldsModule } from './fields.js';
3
9
  import { createOrderGetModule } from './get.js';
10
+ import { createOrderLifecycleModule } from './lifecycle.js';
4
11
  import { createOrderLinePricePreviewModule, } from './line-price-preview.js';
12
+ import { createOrderListModule } from './list.js';
5
13
  import { createManualDiscountsModule } from './manual-discounts.js';
6
14
  import { createOrderManualPricingModule } from './manual-pricing.js';
7
15
  import { createOrderEntryModule } from './order-entry.js';
8
16
  import { createOrderParcelChargeModule } from './parcel-charge.js';
9
17
  import { createOrderPlanEditModule } from './plan-edit.js';
18
+ import { createOrderSettingsModule } from './settings.js';
10
19
  import { createOrderStatusModule } from './status.js';
11
20
  import { createSurchargesModule } from './surcharges.js';
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';
12
25
  const ORDER_PROVIDER_FALLBACKS_QUERY = /* GraphQL */ `
13
26
  query OrderProviderFallbacks($id: ID!) {
14
27
  order(id: $id) {
@@ -82,6 +95,8 @@ export const ORDER_POSITION_QUERY = /* GraphQL */ `
82
95
  settled
83
96
  authorized
84
97
  refunded
98
+ creditNoted
99
+ owed
85
100
  outstanding
86
101
  overpaid
87
102
  availableToCharge
@@ -89,17 +104,34 @@ export const ORDER_POSITION_QUERY = /* GraphQL */ `
89
104
  }
90
105
  `;
91
106
  export function createOrdersModule(transport) {
107
+ const getModule = createOrderGetModule(transport);
92
108
  return {
93
109
  ...createOrderEntryModule(transport),
94
- ...createOrderGetModule(transport),
110
+ ...getModule,
111
+ ...createOrderListModule(transport),
95
112
  ...createOrderParcelChargeModule(transport),
96
113
  ...createOrderLinePricePreviewModule(transport),
97
114
  ...createOrderManualPricingModule(transport),
98
115
  ...createOrderPlanEditModule(transport),
99
116
  ...createOrderCommitEditModule(transport),
117
+ ...createOrderCancelWithMoneyModule(transport),
118
+ ...createOrderLifecycleModule(transport),
119
+ ...createOrderFieldsModule(transport),
100
120
  ...createOrderStatusModule(transport),
101
121
  surcharges: createSurchargesModule(transport),
122
+ drafts: createOrderDraftsModule(transport, getModule),
102
123
  manualDiscounts: createManualDiscountsModule(transport),
124
+ depositPolicy: createOrderDepositPolicyModule(transport),
125
+ settings: createOrderSettingsModule(transport),
126
+ bulk(input, options) {
127
+ return bulkOrders(transport, input, options);
128
+ },
129
+ bulkRun(runId, options) {
130
+ return readOrderBulkRun(transport, runId, options);
131
+ },
132
+ delete(orderId, options) {
133
+ return deleteOrder(transport, orderId, options);
134
+ },
103
135
  async park(orderId, options) {
104
136
  const data = await transport.graphql({
105
137
  api: 'admin',
@@ -137,7 +169,8 @@ export function createOrdersModule(transport) {
137
169
  return data.order.providerFallbacks;
138
170
  },
139
171
  async paymentPosition(orderId, options) {
140
- 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);
141
174
  return data.orderPaymentPosition;
142
175
  },
143
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;