@sixtyninecommerce/admin 0.8.0 → 0.10.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 (179) hide show
  1. package/README.md +2739 -17
  2. package/dist/api-tokens/index.d.ts +15 -5
  3. package/dist/api-tokens/index.js +1 -0
  4. package/dist/apps/event-subscription.d.ts +59 -0
  5. package/dist/apps/event-subscription.js +32 -0
  6. package/dist/apps/hook-secret.d.ts +22 -0
  7. package/dist/apps/hook-secret.js +36 -0
  8. package/dist/apps/index.d.ts +54 -3
  9. package/dist/apps/index.js +17 -0
  10. package/dist/audit/index.d.ts +7 -0
  11. package/dist/auth/queries.d.ts +5 -1
  12. package/dist/auth/queries.js +6 -0
  13. package/dist/bulk/index.d.ts +323 -0
  14. package/dist/bulk/index.js +162 -0
  15. package/dist/catalog/assets.d.ts +147 -0
  16. package/dist/catalog/assets.js +164 -0
  17. package/dist/catalog/collections.d.ts +109 -0
  18. package/dist/catalog/collections.js +91 -0
  19. package/dist/catalog/facets.d.ts +103 -0
  20. package/dist/catalog/facets.js +100 -0
  21. package/dist/catalog/index.d.ts +115 -0
  22. package/dist/catalog/index.js +21 -0
  23. package/dist/catalog/options.d.ts +89 -0
  24. package/dist/catalog/options.js +88 -0
  25. package/dist/catalog/products-bulk.d.ts +21 -0
  26. package/dist/catalog/products-bulk.js +58 -0
  27. package/dist/catalog/products.d.ts +650 -0
  28. package/dist/catalog/products.js +458 -0
  29. package/dist/catalog/properties.d.ts +234 -0
  30. package/dist/catalog/properties.js +158 -0
  31. package/dist/catalog/types.d.ts +174 -0
  32. package/dist/catalog/types.js +141 -0
  33. package/dist/catalog/variants.d.ts +324 -0
  34. package/dist/catalog/variants.js +288 -0
  35. package/dist/catalog/visibility.d.ts +57 -0
  36. package/dist/catalog/visibility.js +59 -0
  37. package/dist/client.d.ts +192 -3
  38. package/dist/client.js +87 -12
  39. package/dist/compliance/index.d.ts +88 -0
  40. package/dist/compliance/index.js +88 -0
  41. package/dist/customer-data-redaction.d.ts +14 -0
  42. package/dist/customer-data-redaction.js +22 -0
  43. package/dist/customers/index.d.ts +428 -17
  44. package/dist/customers/index.js +322 -15
  45. package/dist/documents/index.d.ts +513 -16
  46. package/dist/documents/index.js +229 -3
  47. package/dist/events/index.d.ts +259 -0
  48. package/dist/events/index.js +147 -0
  49. package/dist/feeds/ai.d.ts +46 -0
  50. package/dist/feeds/ai.js +43 -0
  51. package/dist/feeds/categories.d.ts +50 -0
  52. package/dist/feeds/categories.js +56 -0
  53. package/dist/feeds/configs.d.ts +54 -0
  54. package/dist/feeds/configs.js +85 -0
  55. package/dist/feeds/identifier-fields.d.ts +25 -0
  56. package/dist/feeds/identifier-fields.js +29 -0
  57. package/dist/feeds/index.d.ts +54 -0
  58. package/dist/feeds/index.js +46 -0
  59. package/dist/feeds/preserve.d.ts +38 -0
  60. package/dist/feeds/preserve.js +74 -0
  61. package/dist/feeds/rules.d.ts +42 -0
  62. package/dist/feeds/rules.js +56 -0
  63. package/dist/feeds/types.d.ts +654 -0
  64. package/dist/feeds/types.js +135 -0
  65. package/dist/fulfillments/index.d.ts +437 -0
  66. package/dist/fulfillments/index.js +534 -0
  67. package/dist/heads/index.d.ts +60 -0
  68. package/dist/heads/index.js +45 -0
  69. package/dist/hooks/assignments.d.ts +90 -0
  70. package/dist/hooks/assignments.js +53 -0
  71. package/dist/hooks/index.d.ts +97 -0
  72. package/dist/hooks/index.js +76 -0
  73. package/dist/index.d.ts +95 -9
  74. package/dist/index.js +21 -1
  75. package/dist/integrations/index.d.ts +14 -0
  76. package/dist/integrations/index.js +9 -0
  77. package/dist/integrations/pipelines.d.ts +113 -0
  78. package/dist/integrations/pipelines.js +62 -0
  79. package/dist/integrations/types.d.ts +176 -0
  80. package/dist/integrations/types.js +8 -0
  81. package/dist/jobs/bulk-action-run.d.ts +74 -0
  82. package/dist/jobs/bulk-action-run.js +69 -0
  83. package/dist/locations/index.d.ts +6 -2
  84. package/dist/meta/index.d.ts +32 -0
  85. package/dist/orders/bulk.d.ts +75 -0
  86. package/dist/orders/bulk.js +150 -0
  87. package/dist/orders/commit-edit.d.ts +123 -0
  88. package/dist/orders/commit-edit.js +142 -0
  89. package/dist/orders/deposit-policy.d.ts +103 -0
  90. package/dist/orders/deposit-policy.js +202 -0
  91. package/dist/orders/get.d.ts +722 -0
  92. package/dist/orders/get.js +530 -0
  93. package/dist/orders/index.d.ts +186 -21
  94. package/dist/orders/index.js +57 -0
  95. package/dist/orders/line-price-preview.d.ts +297 -0
  96. package/dist/orders/line-price-preview.js +50 -0
  97. package/dist/orders/manual-discounts.d.ts +141 -0
  98. package/dist/orders/manual-discounts.js +97 -0
  99. package/dist/orders/manual-pricing.d.ts +192 -0
  100. package/dist/orders/manual-pricing.js +72 -0
  101. package/dist/orders/order-entry.d.ts +566 -0
  102. package/dist/orders/order-entry.js +129 -0
  103. package/dist/orders/parcel-charge.d.ts +45 -0
  104. package/dist/orders/parcel-charge.js +55 -0
  105. package/dist/orders/plan-edit.d.ts +489 -0
  106. package/dist/orders/plan-edit.js +93 -0
  107. package/dist/orders/status.d.ts +235 -0
  108. package/dist/orders/status.js +96 -0
  109. package/dist/orders/surcharges.d.ts +75 -2
  110. package/dist/orders/surcharges.js +110 -4
  111. package/dist/payments/account-credit.d.ts +171 -0
  112. package/dist/payments/account-credit.js +107 -0
  113. package/dist/payments/index.d.ts +241 -9
  114. package/dist/payments/index.js +92 -0
  115. package/dist/payments/methods.d.ts +37 -0
  116. package/dist/payments/methods.js +33 -0
  117. package/dist/platform/catalog.d.ts +148 -0
  118. package/dist/platform/catalog.js +74 -0
  119. package/dist/platform/entitlements.d.ts +111 -0
  120. package/dist/platform/entitlements.js +86 -0
  121. package/dist/platform/legal-entities.d.ts +139 -0
  122. package/dist/platform/legal-entities.js +126 -0
  123. package/dist/platform/legal-entity-numbering.d.ts +103 -0
  124. package/dist/platform/legal-entity-numbering.js +101 -0
  125. package/dist/platform/organization-membership.d.ts +80 -0
  126. package/dist/platform/organization-membership.js +71 -0
  127. package/dist/platform/organization-settings.d.ts +33 -0
  128. package/dist/platform/organization-settings.js +42 -0
  129. package/dist/platform/organization-sharing.d.ts +172 -0
  130. package/dist/platform/organization-sharing.js +120 -0
  131. package/dist/platform/organizations.d.ts +205 -0
  132. package/dist/platform/organizations.js +180 -0
  133. package/dist/platform/provision-store.d.ts +88 -8
  134. package/dist/platform/provision-store.js +12 -0
  135. package/dist/platform/reports.d.ts +46 -0
  136. package/dist/platform/reports.js +31 -0
  137. package/dist/platform/server-metrics.d.ts +58 -0
  138. package/dist/platform/server-metrics.js +11 -0
  139. package/dist/pos/index.d.ts +567 -0
  140. package/dist/pos/index.js +205 -0
  141. package/dist/pricing/index.d.ts +408 -0
  142. package/dist/pricing/index.js +353 -0
  143. package/dist/pricing/vouchers.d.ts +103 -0
  144. package/dist/pricing/vouchers.js +69 -0
  145. package/dist/provenance/index.d.ts +93 -0
  146. package/dist/provenance/index.js +53 -0
  147. package/dist/reports/index.d.ts +199 -0
  148. package/dist/reports/index.js +154 -0
  149. package/dist/returns/index.d.ts +225 -0
  150. package/dist/returns/index.js +160 -0
  151. package/dist/search/index.d.ts +99 -0
  152. package/dist/search/index.js +62 -0
  153. package/dist/shipping/parcel-count-suggestion.d.ts +52 -0
  154. package/dist/shipping/parcel-count-suggestion.js +73 -0
  155. package/dist/shipping/parcel-rule.d.ts +48 -0
  156. package/dist/shipping/parcel-rule.js +91 -0
  157. package/dist/stock/index.d.ts +166 -0
  158. package/dist/stock/index.js +115 -0
  159. package/dist/stock/transfers.d.ts +520 -0
  160. package/dist/stock/transfers.js +437 -0
  161. package/dist/stored-value/index.d.ts +154 -0
  162. package/dist/stored-value/index.js +130 -0
  163. package/dist/tenant/capabilities.d.ts +10 -0
  164. package/dist/tenant/entitlements.d.ts +35 -0
  165. package/dist/tenant/entitlements.js +15 -0
  166. package/dist/tenant/field-groups.d.ts +64 -0
  167. package/dist/tenant/field-groups.js +34 -0
  168. package/dist/tenant/legal-entity.d.ts +32 -0
  169. package/dist/tenant/legal-entity.js +41 -0
  170. package/dist/tenant/notifications.d.ts +148 -0
  171. package/dist/tenant/notifications.js +79 -0
  172. package/dist/tenant/retention.d.ts +10 -4
  173. package/dist/tenant/settings-sources.d.ts +103 -0
  174. package/dist/tenant/settings-sources.js +92 -0
  175. package/dist/types.d.ts +86 -11
  176. package/dist/uploads/index.d.ts +11 -7
  177. package/dist/users/index.d.ts +104 -0
  178. package/dist/users/index.js +80 -0
  179. package/package.json +3 -2
@@ -1,8 +1,48 @@
1
- import type { Transport } from '@sixtyninecommerce/core';
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 OrderCommitEditModule } from './commit-edit.js';
7
+ import { type OrderDepositPolicyModule } from './deposit-policy.js';
8
+ import { type OrderGetModule } from './get.js';
9
+ import { type OrderLinePricePreviewModule } from './line-price-preview.js';
10
+ import { type ManualDiscountsModule } from './manual-discounts.js';
11
+ import { type OrderManualPricingModule } from './manual-pricing.js';
12
+ import { type OrderEntryModule } from './order-entry.js';
13
+ import { type OrderParcelChargeModule } from './parcel-charge.js';
14
+ import { type OrderPlanEditModule } from './plan-edit.js';
15
+ import { type OrderStatusModule } from './status.js';
4
16
  import { type SurchargesModule } from './surcharges.js';
5
17
  export type { PaidOrder } from '../payments/index.js';
18
+ export type { OrderBulkAction, OrderBulkCapture, OrderBulkInput, OrderBulkItem, OrderBulkRun, } from './bulk.js';
19
+ export { MAX_BULK_ORDERS, ORDER_BULK_ACTIONS, ORDER_BULK_TRANSITION_REFUSED } from './bulk.js';
20
+ export type { OrderDepositPolicy, OrderDepositPolicyModule, StorefrontDepositPolicy, } from './deposit-policy.js';
21
+ export type { DiscountPolicy, DiscountPolicyInput, DiscountPolicyModule, DiscountReason, DiscountReasonInput, DiscountReasonsModule, ManualDiscountsModule, OrderManualDiscount, } from './manual-discounts.js';
22
+ export type { ExternalLinePriceBasis, ExternalOrder, ExternalOrderAddressInput, ExternalOrderCall, ExternalOrderCatalogLine, ExternalOrderExternalLine, ExternalOrderFulfilment, ExternalOrderInput, ExternalOrderLine, ExternalOrderLineInput, ExternalOrderSurcharge, ExternalOrderSurchargeInput, ExternalOrderTargetState, ExternalOrderTaxLine, } from './order-entry.js';
23
+ /** An app provider an order is running without (`admin.orders.providerFallbacks`). */
24
+ export interface OrderProviderFallback {
25
+ /** `shipping.rates` or `tax.calculate`. */
26
+ kind: string;
27
+ installationId: string;
28
+ /**
29
+ * `timeout`, `network`, `tls`, `redirect`, `http_status`, `invalid_response`,
30
+ * `private_host`, `suspended`, `not_configured` — the app could not answer, or
31
+ * was not asked because it is switched off (`suspended`: after 20 failures, or
32
+ * the installation or app suspended) — or one the MERCHANT fixes, not the app
33
+ * vendor:
34
+ * - `tax_class` (`shipping.rates`): the app answered, but the store's tax
35
+ * classes cannot tax any rate it offered; map the class.
36
+ * - `withdrawn` (`tax.calculate`): the store's assigned tax provider no longer
37
+ * declares the hook, or its installation no longer consents to it; approve
38
+ * the app's pending consent, or unassign the provider.
39
+ *
40
+ * Treat an unknown value as "not available": reasons are added over time.
41
+ */
42
+ reason: string;
43
+ /** ISO-8601 with offset: when the order started running without it. */
44
+ since: string;
45
+ }
6
46
  /** The result of settling an order. */
7
47
  export interface OrderSettlement {
8
48
  order: PaidOrder;
@@ -21,8 +61,98 @@ export interface OrderSettlement {
21
61
  * deposit flow: hold an order while the rest of the money is arranged, read
22
62
  * what it stands at, and settle it once the money is really there.
23
63
  */
24
- export interface OrdersModule {
64
+ /**
65
+ * `OrderEntryModule`'s three methods sit DIRECTLY on `admin.orders` rather than
66
+ * under a nested namespace: composing an order and recovering it are order
67
+ * operations, not a sub-resource, and `admin.orders.byExternalRef(ref)` is the
68
+ * sentence a vertical's own code wants to write.
69
+ *
70
+ * The manual pricing doors (`setLinePrices`, `setOneTimeDiscounts`) sit there too, beside their
71
+ * read twin `previewLinePrices`, which prices the same changes without saving them.
72
+ */
73
+ export interface OrdersModule extends OrderEntryModule, OrderGetModule, OrderParcelChargeModule, OrderLinePricePreviewModule, OrderManualPricingModule, OrderPlanEditModule, OrderCommitEditModule, OrderStatusModule {
25
74
  surcharges: SurchargesModule;
75
+ /**
76
+ * Manual discounts with a reason (incentives spec §4 decision 6): read an order's records,
77
+ * and the store's reason list and policy (`reasons`, `policy`). A discount itself is given
78
+ * through the doors that move the money, each taking a reason code: `setLinePrices` and
79
+ * `setOneTimeDiscounts` on this module.
80
+ */
81
+ manualDiscounts: ManualDiscountsModule;
82
+ /**
83
+ * Move, cancel, delete or mark paid up to `MAX_BULK_ORDERS` (50) orders of the store in ONE
84
+ * call (headless spec §7 `orders.bulk`; rulings G19, G28).
85
+ *
86
+ * **The run is a job.** The call answers a receipt (`runId`) once the run is queued;
87
+ * `handle.wait()` polls it until it ends and resolves with the run, whatever the ending.
88
+ * `bulkRun(runId)` reads it again later, from any process. Each order's outcome is in
89
+ * `run.items`, in the order the ids were named.
90
+ *
91
+ * **Each order is judged as on its own page, and succeeds or fails alone.** First by its own
92
+ * status (`orders.status`): an action the order's status does not offer, or a TRANSITION target
93
+ * outside the order's own `nextStates`, answers `ORDER_ACTION_UNAVAILABLE` with `reasonCode`
94
+ * (that read's vocabulary), before anything is written. Then by its single door, under the
95
+ * door's own lock, with the door's own code: `ORDER_STATE_TRANSITION_ERROR` (and core's other
96
+ * 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.
100
+ *
101
+ * - `TRANSITION` (`toState` required): as `transitionOrderToState`. Never `Cancelled` (use
102
+ * `CANCEL`), `PaymentSettled` (use `MARK_PAID`), `Modifying` or `AddingItems`.
103
+ * - `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`.
105
+ * - `DELETE`: a draft or a cart holding no payment or stock movement, as `deleteOrder`.
106
+ * - `MARK_PAID`: **captures** each payment of the order that is `Authorized` when the run reaches
107
+ * it, read by the engine (never your list's copy), each as `settlePayment` and on its own
108
+ * (ruling G19). Each order's `captured` lists every payment acted on. **A decline is a result,
109
+ * not a retry:** the order answers `SETTLE_PAYMENT_ERROR`, the payment keeps the state the
110
+ * provider left, and the run never asks again. **An unknown provider answer must be
111
+ * reconciled, never retried blind:** `IDEMPOTENCY_OUTCOME_UNKNOWN` means the provider was asked
112
+ * and its answer was lost; check the payment with the provider. `IDEMPOTENCY_IN_PROGRESS` means
113
+ * a capture under the same request may still be running. An order with no authorized payment
114
+ * answers `NOTHING_TO_CAPTURE`: it is never marked paid without money (ruling G28).
115
+ *
116
+ * **Idempotency.** `options.idempotencyKey` (minted when omitted): the same key with the same
117
+ * input answers the SAME run, so a resubmit never captures twice; another input under the key is
118
+ * `IDEMPOTENCY_CONFLICT` (409 `ConflictError`). Each order, and each capture, is keyed within the
119
+ * run, so a run the platform processes again (a worker restart) answers what it already did from
120
+ * that record and never asks a provider twice.
121
+ *
122
+ * **No dry run.** The refusals that matter are the doors' own, made under their locks, so a
123
+ * rehearsal could answer "ok" for an order the real run refuses.
124
+ *
125
+ * Needs `UpdateOrder` (`DeleteOrder` for `DELETE`); reading the run needs `ReadOrder`. Refusals
126
+ * of the call itself (nothing is queued): `BULK_ACTION_INPUT_INVALID` (`ValidationError`, 400:
127
+ * no orders, more than 50, one named twice, an unknown action, a missing or refused `toState`,
128
+ * an option the action takes none of; refused before sending too), `BULK_ACTION_NOT_ALLOWED`
129
+ * (`PermissionDeniedError`, 403), `IDEMPOTENCY_CONFLICT`.
130
+ *
131
+ * Platform releases before this method do not have the mutation and refuse it as
132
+ * `ValidationError` `GRAPHQL_VALIDATION_FAILED` (400): deploy the engine first.
133
+ */
134
+ bulk(input: OrderBulkInput, options?: Call): Promise<JobHandle<OrderBulkRun>>;
135
+ /**
136
+ * One read of a bulk order run, by the `runId` `bulk()` answered. A run of another store, or one
137
+ * that does not exist, is `BULK_ACTION_RUN_NOT_FOUND` (`NotFoundError`, 404).
138
+ */
139
+ bulkRun(runId: string, options?: Call): Promise<OrderBulkRun>;
140
+ /**
141
+ * Delete ONE order: a draft or a cart (`AddingItems`) holding no payment and no stock movement,
142
+ * as the order page's Delete (ruling G29). Needs `DeleteOrder`. Anything else is kept:
143
+ * `ORDER_INVOICE_LOCKED` (an invoiced order, for every caller), `ORDER_HAS_RECORDS` (cancel it
144
+ * instead: `orders.bulk` with `CANCEL`), or `ORDER_NOT_DELETED` (`ConflictError`, 409, as every `*_NOT_DELETED` of this SDK) with
145
+ * the engine's own reason for an order in another state, or one this store does not have.
146
+ * Placed orders are cancelled, never deleted.
147
+ */
148
+ delete(orderId: string, options?: Call): Promise<void>;
149
+ /**
150
+ * The store's deposit policy (`orderDepositPolicy`): whether staff may take a
151
+ * deposit and {@link OrdersModule.park} an order, the minimum a deposit must be,
152
+ * and whether a shopper may pay one at checkout. `get` answers what the engine
153
+ * applies; `set` replaces it, validated against the schema's bounds first.
154
+ */
155
+ depositPolicy: OrderDepositPolicyModule;
26
156
  /**
27
157
  * Hold a placed order while the rest of its money is arranged. Needs
28
158
  * `UpdateOrder`.
@@ -32,16 +162,21 @@ export interface OrdersModule {
32
162
  * is off unless a merchant chose it. Refusals carry the order's position:
33
163
  * `DEPOSITS_NOT_ENABLED` (the store has not turned deposits on — the default,
34
164
  * so this is the first one you will meet), `DEPOSIT_REQUIRED` (nothing paid,
35
- * and the store does not allow that), `DEPOSIT_BELOW_MINIMUM`,
36
- * `ORDER_NOT_PARKABLE` (wrong state), `PARK_REASON_TOO_LONG` (500
37
- * characters).
38
- *
39
- * Parking does not RESERVE stock: the platform allocates at the payment edge,
40
- * so an order parked while arranging payment usually holds no allocations
41
- * yet. What it protects is the ORDER — the stock-allocation sweeper leaves a
42
- * parked order alone deliberately, so an expiring allocation TTL cannot
43
- * cancel an order a customer has already paid a deposit on, and allocations
44
- * it does hold stay put while it waits.
165
+ * and the store does not allow that), `DEPOSIT_BELOW_MINIMUM` (the minimum is
166
+ * set in the store's default currency and converted into the order's),
167
+ * `EXCHANGE_RATE_UNAVAILABLE` (no exchange rate to convert it into the
168
+ * order's currency),
169
+ * `ORDER_NOT_PARKABLE` (wrong state), `INSUFFICIENT_STOCK` (the goods sold
170
+ * since the order reached payment; `extensions.lines` names each short line),
171
+ * `PARK_REASON_TOO_LONG` (500 characters).
172
+ *
173
+ * Parking RESERVES the order's stock for the life of the park, without
174
+ * placing the order: no confirmation email, no `order.created`, no ERP push
175
+ * until it settles, and settling does not reserve twice. `unpark` and a
176
+ * cancellation give the stock back. A line's backorder or pre-order part is
177
+ * reserved as it would be at payment. The stock-allocation sweeper leaves a
178
+ * parked order alone, so an expiring allocation TTL cannot cancel an order a
179
+ * customer has already paid a deposit on.
45
180
  */
46
181
  park(orderId: string, options?: Call & {
47
182
  reason?: string;
@@ -55,11 +190,16 @@ export interface OrdersModule {
55
190
  * parked it. `PARK_ORIGIN_UNKNOWN` is the refusal when that history does not
56
191
  * say — move such an order on explicitly with a state transition instead.
57
192
  *
58
- * There is no storefront equivalent today: a parked order's remainder is
59
- * recorded WHERE IT STANDS with `payments.record`, and the payment that
60
- * clears it settles, places and allocates the order without ever leaving
61
- * `Parked` first. Use this when the order has to be EDITED, which is the one
62
- * thing it cannot do while held.
193
+ * A shopper can pay a parked order's remainder from the storefront
194
+ * (`commerce.payParkedOrder` / `commerce.createParkedOrderPaymentIntent`),
195
+ * and a merchant records it WHERE IT STANDS with `payments.record`; the
196
+ * payment that clears it settles and places the order, keeping the stock the
197
+ * park reserved, without ever leaving `Parked` first. Use this when the order
198
+ * has to be EDITED, which is the one thing it cannot do while held; it gives
199
+ * the park's reserved stock back. On a paid order an installed app held for
200
+ * review it does NOT accept it: the hold goes back to `ArrangingPayment` with the
201
+ * order, and nothing places it until staff accept it with {@link OrdersModule.settle}
202
+ * (or it goes back to the cart and the apps are asked again).
63
203
  *
64
204
  * It moves no money and changes no payment. Other refusals:
65
205
  * `ORDER_NOT_PARKED`, `UNPARK_TRANSITION_REFUSED` (the origin was known and
@@ -76,10 +216,27 @@ export interface OrdersModule {
76
216
  * Refuses `COVERAGE_INSUFFICIENT` while the order's SETTLED money does not
77
217
  * cover its total, with the position attached. Settled, not covered: an
78
218
  * authorization is permission to take money, not money, so an order whose
79
- * remainder is merely authorized is settled from `ArrangingPayment` after the
80
- * authorization is captured, like any other order. `ORDER_NOT_SETTLEABLE` is
81
- * the other refusal — a state a settlement cannot be reached from, which
82
- * paying more can never fix.
219
+ * remainder is merely authorized settles once that authorization is captured
220
+ * where it stands (`settlePayment` on the Admin API): the capture settles it,
221
+ * out of a park included, and a parked order never goes back to
222
+ * `ArrangingPayment` for it (that is {@link OrdersModule.unpark}, which gives
223
+ * the reserved stock back). `ORDER_NOT_SETTLEABLE` is the other refusal — a
224
+ * state a settlement cannot be reached from, which paying more can never fix.
225
+ *
226
+ * This is also how staff ACCEPT a paid order held for review — an installed
227
+ * app refused it after it was paid, or a check an ordinary checkout would have
228
+ * refused it for (it is `Parked`, or `ArrangingPayment` after an un-park or
229
+ * when it could not be parked; `admin.orders.status(orderId).hold` gives the
230
+ * refusal's code, and the app when an app refused). Nothing else settles such an order: money that lands on it meanwhile
231
+ * is recorded and the order stays where it is. A settled one settles here and
232
+ * is placed; one that still owes money is accepted WITHOUT settling — the hold
233
+ * ends and the answer's `order.state` stays where it was (for a parked order,
234
+ * an ordinary part-paid park the shopper can now pay off). One whose balance
235
+ * is covered only by an AUTHORIZED payment owes nothing and is refused
236
+ * `COVERAGE_INSUFFICIENT` with the hold kept: accept it by capturing that
237
+ * 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.
83
240
  *
84
241
  * Calling this on an order the platform ALREADY settled succeeds rather than
85
242
  * refusing. Expect that to be the common case: the engine settles an order as
@@ -98,6 +255,14 @@ export interface OrdersModule {
98
255
  settle(orderId: string, options?: Call & {
99
256
  fulfil?: boolean;
100
257
  }): Promise<OrderSettlement>;
258
+ /**
259
+ * The app providers this order is currently running WITHOUT (spec §15.19): a
260
+ * rates or tax app that could not answer, so the platform's own behaviour was
261
+ * used instead. Empty when none. Needs `ReadOrder`; `ORDER_NOT_FOUND` for an
262
+ * order this store does not have. {@link OrderStatusModule.status} answers
263
+ * the same list beside everything else about the order.
264
+ */
265
+ providerFallbacks(orderId: string, options?: Call): Promise<OrderProviderFallback[]>;
101
266
  }
102
267
  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";
103
268
  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";
@@ -1,4 +1,30 @@
1
+ import { NotFoundError } from '@sixtyninecommerce/core';
2
+ import { bulkOrders, deleteOrder, readOrderBulkRun, } from './bulk.js';
3
+ import { createOrderCommitEditModule } from './commit-edit.js';
4
+ import { createOrderDepositPolicyModule } from './deposit-policy.js';
5
+ import { createOrderGetModule } from './get.js';
6
+ import { createOrderLinePricePreviewModule, } from './line-price-preview.js';
7
+ import { createManualDiscountsModule } from './manual-discounts.js';
8
+ import { createOrderManualPricingModule } from './manual-pricing.js';
9
+ import { createOrderEntryModule } from './order-entry.js';
10
+ import { createOrderParcelChargeModule } from './parcel-charge.js';
11
+ import { createOrderPlanEditModule } from './plan-edit.js';
12
+ import { createOrderStatusModule } from './status.js';
1
13
  import { createSurchargesModule } from './surcharges.js';
14
+ export { MAX_BULK_ORDERS, ORDER_BULK_ACTIONS, ORDER_BULK_TRANSITION_REFUSED } from './bulk.js';
15
+ const ORDER_PROVIDER_FALLBACKS_QUERY = /* GraphQL */ `
16
+ query OrderProviderFallbacks($id: ID!) {
17
+ order(id: $id) {
18
+ id
19
+ providerFallbacks {
20
+ kind
21
+ installationId
22
+ reason
23
+ since
24
+ }
25
+ }
26
+ }
27
+ `;
2
28
  const SETTLEMENT_FIELDS = /* GraphQL */ `
3
29
  order {
4
30
  id
@@ -67,7 +93,26 @@ export const ORDER_POSITION_QUERY = /* GraphQL */ `
67
93
  `;
68
94
  export function createOrdersModule(transport) {
69
95
  return {
96
+ ...createOrderEntryModule(transport),
97
+ ...createOrderGetModule(transport),
98
+ ...createOrderParcelChargeModule(transport),
99
+ ...createOrderLinePricePreviewModule(transport),
100
+ ...createOrderManualPricingModule(transport),
101
+ ...createOrderPlanEditModule(transport),
102
+ ...createOrderCommitEditModule(transport),
103
+ ...createOrderStatusModule(transport),
70
104
  surcharges: createSurchargesModule(transport),
105
+ manualDiscounts: createManualDiscountsModule(transport),
106
+ depositPolicy: createOrderDepositPolicyModule(transport),
107
+ bulk(input, options) {
108
+ return bulkOrders(transport, input, options);
109
+ },
110
+ bulkRun(runId, options) {
111
+ return readOrderBulkRun(transport, runId, options);
112
+ },
113
+ delete(orderId, options) {
114
+ return deleteOrder(transport, orderId, options);
115
+ },
71
116
  async park(orderId, options) {
72
117
  const data = await transport.graphql({
73
118
  api: 'admin',
@@ -92,6 +137,18 @@ export function createOrdersModule(transport) {
92
137
  }, options);
93
138
  return data.unparkOrder;
94
139
  },
140
+ async providerFallbacks(orderId, options) {
141
+ const data = await transport.graphql({ api: 'admin', query: ORDER_PROVIDER_FALLBACKS_QUERY, variables: { id: orderId } }, options);
142
+ if (!data.order) {
143
+ throw new NotFoundError({
144
+ code: 'ORDER_NOT_FOUND',
145
+ message: `This store has no order ${orderId}.`,
146
+ status: 404,
147
+ service: 'vendure',
148
+ });
149
+ }
150
+ return data.order.providerFallbacks;
151
+ },
95
152
  async paymentPosition(orderId, options) {
96
153
  const data = await transport.graphql({ api: 'admin', query: ORDER_POSITION_QUERY, variables: { orderId } }, options);
97
154
  return data.orderPaymentPosition;
@@ -0,0 +1,297 @@
1
+ import type { Transport } from '@sixtyninecommerce/core';
2
+ import type { Call } from '../types.js';
3
+ /** The tax basis a unit price is stated in. */
4
+ export type OrderLinePriceBasis = 'NET' | 'GROSS';
5
+ /**
6
+ * One layer a line's price goes through: the catalogue price, a manual unit
7
+ * price, the customer's price list, or the order's own one-time pricing.
8
+ */
9
+ export type OrderLinePriceSource = 'RETAIL' | 'OVERRIDE' | 'PRICE_LIST' | 'ONE_TIME';
10
+ /** How a one-time discount is stated. */
11
+ export type PreviewLineDiscountType = 'PERCENTAGE' | 'FIXED_AMOUNT' | 'FIXED_PRICE';
12
+ /** A manual unit price to stage on a line. */
13
+ export interface PreviewLinePriceOverride {
14
+ /**
15
+ * Minor units, a whole number of 0 or more, stated in `basis`. Stated in the
16
+ * line's own basis (the answer's `basis`) it is taken as it is, on every
17
+ * line. Stated in the other basis it is converted only at a tax rate the
18
+ * preview evaluated: the rate the platform taxes the line at on the order as
19
+ * it is now.
20
+ */
21
+ amount: number;
22
+ /**
23
+ * The basis `amount` is stated in. The line's own `basis` is always
24
+ * accepted. The other basis is refused with `INVALID_PREVIEW_INPUT`, in a
25
+ * message that names the basis to state it in, where the preview evaluates
26
+ * no tax rate for the line: on every line, stored or new, of a store with an
27
+ * active tax provider app, and on a line of the order whose variant was
28
+ * moved to another tax category since. To learn a line's basis first,
29
+ * preview it without an `override` and read `basis`.
30
+ */
31
+ basis: OrderLinePriceBasis;
32
+ }
33
+ /**
34
+ * A one-time discount to stage: on one line's product variant, or on the whole
35
+ * order (`options.orderDiscount`).
36
+ */
37
+ export interface PreviewOneTimeDiscount {
38
+ /** A whole-order discount is `PERCENTAGE` or `FIXED_AMOUNT`, never `FIXED_PRICE`. */
39
+ discountType: PreviewLineDiscountType;
40
+ /**
41
+ * A whole number. `PERCENTAGE`: basis points, 1 to 10000. `FIXED_AMOUNT`:
42
+ * minor units off each unit, 1 or more. `FIXED_PRICE`: the unit price in
43
+ * minor units, 0 or more. The two money kinds are in the CHANNEL's tax basis,
44
+ * which is not always the line's. These are the values the Admin API's
45
+ * `setOrderPriceListDiscounts` takes.
46
+ */
47
+ discountValue: number;
48
+ }
49
+ /**
50
+ * One line to preview.
51
+ *
52
+ * `override` and `oneTimeDiscount` each have three states: leave the key out
53
+ * to keep what the order has, pass `null` to clear it, pass a value to stage
54
+ * it. The SDK sends each as given. A key set to `undefined` counts as left out.
55
+ */
56
+ export interface PreviewLinePriceLine {
57
+ /**
58
+ * The order line to preview. Leave it out, or pass `null`, for a line that is
59
+ * not on the order yet. An order line may appear once per call.
60
+ */
61
+ lineId?: string | null;
62
+ /** Required on every line. With `lineId` it must be that line's variant. */
63
+ productVariantId: string;
64
+ /**
65
+ * The quantity the line would have, a whole number of 1 or more. It selects
66
+ * the quantity tier. A removed line cannot be staged.
67
+ */
68
+ quantity: number;
69
+ /** A staged manual unit price. */
70
+ override?: PreviewLinePriceOverride | null;
71
+ /**
72
+ * A staged one-time discount. It applies to the product variant, so to every
73
+ * line of it: two lines of one variant that stage different discounts are
74
+ * refused.
75
+ */
76
+ oneTimeDiscount?: PreviewOneTimeDiscount | null;
77
+ }
78
+ /** One layer of a previewed price. */
79
+ export interface LinePriceStackingStep {
80
+ source: OrderLinePriceSource;
81
+ /** The unit price after this layer, minor units in the line's `basis`. */
82
+ amount: number;
83
+ }
84
+ /**
85
+ * Why a line has no price to charge, as a platform code. A string on the wire.
86
+ * `VARIANT_NOT_FOR_SALE_IN_CURRENCY`: the store does not sell the variant in
87
+ * the order's currency, and no price was stated for the line.
88
+ */
89
+ export type LineNotPurchasableCode = 'VARIANT_NOT_FOR_SALE_IN_CURRENCY' | (string & {});
90
+ /** What a preview says of every line, whether it has a price or not. */
91
+ export interface LinePricePreviewBase {
92
+ /** The order line previewed. `null` for a line that is not on the order yet. */
93
+ lineId: string | null;
94
+ productVariantId: string;
95
+ /**
96
+ * The basis the engine prices the line in. Send a manual unit price to the
97
+ * Admin API's `applyOrderLinePriceOverrides` in this basis: the `OVERRIDE`
98
+ * step of `stacking` is that figure.
99
+ */
100
+ basis: OrderLinePriceBasis;
101
+ /** Always `true`: the engine prices the line in the order's tax zone itself. */
102
+ basisKnown: boolean;
103
+ /**
104
+ * The CATALOGUE retail moved since the stored line was priced: a re-price
105
+ * starts from another catalogue retail than `retailBase`. For a line a price
106
+ * list priced, the line recorded that retail gross and no tax rate of its
107
+ * day, so the two are compared gross. Besides a moved catalogue price, a
108
+ * change of the rate the catalogue taxes the variant at for this order can
109
+ * therefore set it too, while the net catalogue price did not move: the rate
110
+ * of the order's tax zone changed, the order now falls in another tax zone,
111
+ * or the variant moved to another tax category.
112
+ *
113
+ * A changed price list or quantity tier, and a tax driver that changes only
114
+ * the line's own tax (a reverse charge, tax removed), can move the previewed
115
+ * figures and leave it `false`. It is always `false` for a list-priced line
116
+ * of an order outside the store's default currency. To know
117
+ * whether a re-price would move a stored line, compare BOTH figures with the
118
+ * line's own: `chargedUnitPrice` with `unitPrice`, and
119
+ * `chargedUnitPriceWithTax` with `unitPriceWithTax` (a changed tax driver
120
+ * can move one of them and not the other). The comparison does not see a
121
+ * changed tax driver on a line that keeps the tax rate it carries: every
122
+ * line of the order on a store with an active tax provider app, and a line
123
+ * whose variant was moved to another tax category since.
124
+ */
125
+ catalogueChanged: boolean;
126
+ /**
127
+ * The layers a re-price goes through, in order. It starts with a `RETAIL`
128
+ * step at TODAY's catalogue price when the line has one, which is not always
129
+ * `retailBase`. The last step is the charged unit price in `basis`. Empty for
130
+ * a line that is not purchasable.
131
+ */
132
+ stacking: LinePriceStackingStep[];
133
+ /** A manual unit price is set, and a contract (fixed) price won over it. */
134
+ overrideInert: boolean;
135
+ /**
136
+ * The net/gross split is the PLATFORM's tax where the store's tax provider
137
+ * app decides. `true` for a line that is not on the order yet, on a store
138
+ * with an active tax provider app: a preview never asks the app, which
139
+ * answers when the line is added. The figure in the line's `basis` is firm.
140
+ * The OTHER one (the gross of a `NET` line, the net of a `GROSS` line) is
141
+ * derived at the platform's rate and may differ: show it as provisional.
142
+ *
143
+ * A manual price for such a line must be stated in the line's `basis`. One
144
+ * stated in the other basis is refused with `INVALID_PREVIEW_INPUT`, because
145
+ * converting it needs the app's rate. To learn the basis first, preview the
146
+ * line without an `override` and read `basis`. This is not the only line
147
+ * with that rule: see `PreviewLinePriceOverride.basis`.
148
+ *
149
+ * `false` everywhere else, and on a line that is not purchasable, which has
150
+ * no money to qualify.
151
+ */
152
+ taxProvisional: boolean;
153
+ }
154
+ /** A line with a price. Money is minor units in the order's currency, before promotions. */
155
+ export interface PurchasableLinePricePreview extends LinePricePreviewBase {
156
+ purchasable: true;
157
+ notPurchasableCode: null;
158
+ /**
159
+ * Net unit price the line would be charged. Provisional on a `GROSS` line
160
+ * while `taxProvisional` is `true`.
161
+ */
162
+ chargedUnitPrice: number;
163
+ /**
164
+ * Gross unit price the line would be charged. Provisional on a `NET` line
165
+ * while `taxProvisional` is `true`.
166
+ */
167
+ chargedUnitPriceWithTax: number;
168
+ /**
169
+ * The retail the line was PRICED AT, in `basis`: the base a percentage is
170
+ * measured against. For a line that is not on the order yet it is today's
171
+ * catalogue price. `null` when a stored line recorded none (a manual price
172
+ * with no price list), and when the line has no catalogue price (an
173
+ * externally priced line, or a variant not for sale in the order's currency
174
+ * that a stated price makes purchasable).
175
+ */
176
+ retailBase: number | null;
177
+ }
178
+ /**
179
+ * A line with no price to charge: the store does not sell the variant in the
180
+ * order's currency and no price was stated for the line. Every money field is
181
+ * `null`, never 0 and never a rate-derived figure.
182
+ */
183
+ export interface NotPurchasableLinePricePreview extends LinePricePreviewBase {
184
+ purchasable: false;
185
+ notPurchasableCode: LineNotPurchasableCode;
186
+ chargedUnitPrice: null;
187
+ chargedUnitPriceWithTax: null;
188
+ retailBase: null;
189
+ }
190
+ /**
191
+ * What one line would cost. Check `purchasable` before reading a price: the
192
+ * money fields are numbers only on a purchasable line.
193
+ */
194
+ export type LinePricePreview = PurchasableLinePricePreview | NotPurchasableLinePricePreview;
195
+ /**
196
+ * Its own document on purpose: `previewOrderLinePrices` exists only on an
197
+ * engine with the line price preview, so on an older one this call alone fails
198
+ * validation and no other order call does.
199
+ */
200
+ export declare const PREVIEW_ORDER_LINE_PRICES_QUERY = "\n query PreviewOrderLinePrices($input: PreviewOrderLinePricesInput!) {\n previewOrderLinePrices(input: $input) {\n lineId\n productVariantId\n purchasable\n notPurchasableCode\n chargedUnitPrice\n chargedUnitPriceWithTax\n basis\n basisKnown\n retailBase\n catalogueChanged\n stacking {\n source\n amount\n }\n overrideInert\n taxProvisional\n }\n }\n";
201
+ export interface OrderLinePricePreviewModule {
202
+ /**
203
+ * What lines of an order would cost, before anything is saved: the pricing
204
+ * engine's own answer for a staged manual unit price, one-time discount and
205
+ * quantity, on stored lines and on lines that are not on the order yet. One
206
+ * result per entry of `lines`, in the order of `lines`. Needs `ReadOrder`,
207
+ * and an engine that serves `previewOrderLinePrices`.
208
+ *
209
+ * A pure read: nothing is saved, no event is published, and no payment or
210
+ * tax provider is contacted.
211
+ *
212
+ * The answer is what a re-price of the line gives now: today's catalogue
213
+ * price, price lists, tiers and tax. A stored line that a save does not
214
+ * re-price keeps its stored price, so compare `chargedUnitPrice` and
215
+ * `chargedUnitPriceWithTax` with the line's own `unitPrice` and
216
+ * `unitPriceWithTax` to see whether they differ (a changed tax driver can
217
+ * move one of the two and not the other). `catalogueChanged` reports a
218
+ * moved catalogue retail only; its own description says what counts as one.
219
+ *
220
+ * Two kinds of stored line KEEP the tax rate they carry, and their tax is
221
+ * not re-evaluated: every line of the order on a store with an active tax
222
+ * provider app (the app is not asked), and a line whose variant was moved to
223
+ * another tax category since. A tax driver that changed since (a VAT number
224
+ * validated, tax removed) does not show in such a line's figures, so the
225
+ * comparison above does not see it.
226
+ *
227
+ * The preview does not
228
+ * predict what a save refuses: a staged one-time discount that the Admin
229
+ * API's `setOrderPriceListDiscounts` would refuse is still priced, and shows
230
+ * no `ONE_TIME` step when the pricing rules skipped it.
231
+ *
232
+ * Every figure is minor units in the order's currency, before promotions. A
233
+ * placed order converts at the rate it was placed at. Each line is taxed as
234
+ * a re-price would tax it now, apart from the two kinds of stored line named
235
+ * above.
236
+ *
237
+ * A store with an active tax provider app gets a platform-taxed preview for
238
+ * new lines. There a line of the order keeps the rate it carries, but a
239
+ * line that is not on the order yet is taxed at the platform's rate: the app
240
+ * is never asked by a preview and answers when the line is added.
241
+ * `taxProvisional` marks those lines. Their figure in `basis` is firm. The
242
+ * other one (the gross of a `NET` line, the net of a `GROSS` line) may then
243
+ * differ, so show it as provisional.
244
+ *
245
+ * On such a store, state every manual price in the line's `basis`, for a
246
+ * line of the order as well as a new one: preview the line without an
247
+ * `override` first and read `basis`. One stated in the other basis is
248
+ * refused there, and on a line of the order whose variant was moved to
249
+ * another tax category, because the preview never converts a price at a
250
+ * tax rate it did not evaluate (`PreviewLinePriceOverride.basis`).
251
+ *
252
+ * Check `purchasable` before reading a price. A variant the store does not
253
+ * sell in the order's currency is answered `purchasable: false` with
254
+ * `notPurchasableCode` set and every money field `null`, never 0, unless a
255
+ * price is stated for the line (for example a manual unit price, staged or
256
+ * stored). The own lines of an order placed at a recorded exchange rate are
257
+ * not judged; a line that is not on the order yet always is.
258
+ *
259
+ * `basis` on a result is the basis a manual unit price must be sent in to
260
+ * the Admin API's `applyOrderLinePriceOverrides`, and the `OVERRIDE` step of
261
+ * `stacking` is that figure.
262
+ *
263
+ * `override` and `oneTimeDiscount` on a line, and `options.orderDiscount`
264
+ * (a whole-order one-time discount, `PERCENTAGE` or `FIXED_AMOUNT`), each
265
+ * have three states: left out keeps what the order has, `null` clears it, a
266
+ * value stages it. The SDK sends them as given.
267
+ *
268
+ * At least 1 and at most 100 lines per call. Each call prices from the saved
269
+ * order plus what that call stages: stage a whole-order discount, and every
270
+ * quantity a collection or facet tier depends on, in the same call as the
271
+ * lines they affect. A removed line cannot be staged (a quantity is 1 or
272
+ * more): the collection and facet tiers of the other lines still count it at
273
+ * its stored quantity.
274
+ *
275
+ * Refusals:
276
+ * - `PREVIEW_ORDER_NOT_FOUND`, `PREVIEW_ORDER_LINE_NOT_FOUND` and
277
+ * `PREVIEW_VARIANT_NOT_FOUND` (`NotFoundError`, 404). An id of another
278
+ * store answers like a missing one, and a cancelled line is not found. An
279
+ * id that is not a uuid is refused before that with core's
280
+ * `ENTITY_NOT_FOUND`, also a `NotFoundError`: branch on the class for
281
+ * not-found, not on one code.
282
+ * - `INVALID_PREVIEW_INPUT` (`ValidationError`, 400): no lines or more than
283
+ * 100, a quantity below 1, an order line given twice, a `lineId` that is
284
+ * not a line of that `productVariantId`, an amount or discount value out
285
+ * of range, a `FIXED_PRICE` whole-order discount, two lines of one variant
286
+ * staging different one-time discounts, `override: null` on an externally
287
+ * priced line (it has no catalogue price to fall back to), or an `override`
288
+ * stated in the other basis than the line's on a line whose tax rate the
289
+ * preview does not evaluate (`PreviewLinePriceOverride.basis`).
290
+ * - `PREVIEW_CHANNEL_NOT_ALLOWED` (`PermissionDeniedError`, 403): the call
291
+ * was made from the default channel instead of the order's own.
292
+ */
293
+ previewLinePrices(orderId: string, lines: PreviewLinePriceLine[], options?: Call & {
294
+ orderDiscount?: PreviewOneTimeDiscount | null;
295
+ }): Promise<LinePricePreview[]>;
296
+ }
297
+ export declare function createOrderLinePricePreviewModule(transport: Transport): OrderLinePricePreviewModule;