@sixtyninecommerce/admin 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/README.md +4347 -171
  2. package/dist/catalog/assets.d.ts +120 -8
  3. package/dist/catalog/assets.js +98 -12
  4. package/dist/catalog/collections.d.ts +279 -14
  5. package/dist/catalog/collections.js +246 -15
  6. package/dist/catalog/index.d.ts +9 -2
  7. package/dist/catalog/index.js +4 -0
  8. package/dist/catalog/products.d.ts +159 -19
  9. package/dist/catalog/products.js +88 -13
  10. package/dist/catalog/properties.d.ts +102 -14
  11. package/dist/catalog/properties.js +13 -0
  12. package/dist/catalog/recommendations.d.ts +261 -0
  13. package/dist/catalog/recommendations.js +145 -0
  14. package/dist/catalog/reviews.d.ts +368 -0
  15. package/dist/catalog/reviews.js +318 -0
  16. package/dist/catalog/types.d.ts +17 -1
  17. package/dist/catalog/types.js +10 -0
  18. package/dist/catalog/variant-find.d.ts +136 -0
  19. package/dist/catalog/variant-find.js +239 -0
  20. package/dist/catalog/variants.d.ts +233 -26
  21. package/dist/catalog/variants.js +125 -7
  22. package/dist/catalog/visibility.d.ts +20 -5
  23. package/dist/catalog/visibility.js +19 -1
  24. package/dist/client.d.ts +95 -9
  25. package/dist/client.js +35 -7
  26. package/dist/content/assets.d.ts +286 -0
  27. package/dist/content/assets.js +181 -0
  28. package/dist/content/items.d.ts +269 -0
  29. package/dist/content/items.js +170 -0
  30. package/dist/content/types.d.ts +282 -0
  31. package/dist/content/types.js +100 -0
  32. package/dist/customers/age-verification.d.ts +66 -0
  33. package/dist/customers/age-verification.js +79 -0
  34. package/dist/customers/credit.d.ts +263 -0
  35. package/dist/customers/credit.js +244 -0
  36. package/dist/customers/delivery-preferences.d.ts +120 -0
  37. package/dist/customers/delivery-preferences.js +97 -0
  38. package/dist/customers/groups.d.ts +207 -0
  39. package/dist/customers/groups.js +438 -0
  40. package/dist/customers/index.d.ts +447 -37
  41. package/dist/customers/index.js +313 -40
  42. package/dist/customers/invitation-status.d.ts +57 -0
  43. package/dist/customers/invitation-status.js +21 -0
  44. package/dist/customers/notes.d.ts +67 -0
  45. package/dist/customers/notes.js +51 -0
  46. package/dist/customers/notification-recipients.d.ts +97 -0
  47. package/dist/customers/notification-recipients.js +84 -0
  48. package/dist/customers/saved-lists.d.ts +42 -0
  49. package/dist/customers/saved-lists.js +61 -0
  50. package/dist/customers/vat.d.ts +83 -0
  51. package/dist/customers/vat.js +46 -0
  52. package/dist/customers/wire.d.ts +20 -0
  53. package/dist/customers/wire.js +35 -0
  54. package/dist/documents/ar.d.ts +307 -0
  55. package/dist/documents/ar.js +254 -0
  56. package/dist/documents/index.d.ts +731 -21
  57. package/dist/documents/index.js +436 -24
  58. package/dist/documents/pdf.d.ts +2 -0
  59. package/dist/documents/pdf.js +11 -0
  60. package/dist/fulfillments/create.d.ts +167 -0
  61. package/dist/fulfillments/create.js +216 -0
  62. package/dist/fulfillments/index.d.ts +44 -10
  63. package/dist/fulfillments/index.js +11 -2
  64. package/dist/fulfillments/payment-policy.d.ts +64 -0
  65. package/dist/fulfillments/payment-policy.js +140 -0
  66. package/dist/fulfillments/warehouse.d.ts +724 -0
  67. package/dist/fulfillments/warehouse.js +914 -0
  68. package/dist/geo/index.d.ts +119 -0
  69. package/dist/geo/index.js +107 -0
  70. package/dist/index.d.ts +123 -35
  71. package/dist/index.js +45 -12
  72. package/dist/integrations/afas-actions.d.ts +234 -0
  73. package/dist/integrations/afas-actions.js +310 -0
  74. package/dist/integrations/afas-types.d.ts +483 -0
  75. package/dist/integrations/afas-types.js +5 -0
  76. package/dist/integrations/afas.d.ts +234 -0
  77. package/dist/integrations/afas.js +290 -0
  78. package/dist/integrations/connections.d.ts +103 -0
  79. package/dist/integrations/connections.js +55 -0
  80. package/dist/integrations/esp.d.ts +313 -0
  81. package/dist/integrations/esp.js +169 -0
  82. package/dist/integrations/exact-online-types.d.ts +423 -0
  83. package/dist/integrations/exact-online-types.js +6 -0
  84. package/dist/integrations/exact-online.d.ts +248 -0
  85. package/dist/integrations/exact-online.js +376 -0
  86. package/dist/integrations/index.d.ts +29 -3
  87. package/dist/integrations/index.js +18 -3
  88. package/dist/integrations/pipeline-keys.d.ts +13 -0
  89. package/dist/integrations/pipeline-keys.js +22 -0
  90. package/dist/integrations/pipelines.d.ts +15 -14
  91. package/dist/integrations/pipelines.js +6 -22
  92. package/dist/integrations/types.d.ts +146 -0
  93. package/dist/locations/index.d.ts +66 -0
  94. package/dist/locations/index.js +31 -0
  95. package/dist/meta/index.d.ts +162 -0
  96. package/dist/orders/cancel-with-money.d.ts +227 -0
  97. package/dist/orders/cancel-with-money.js +153 -0
  98. package/dist/orders/commit-edit.d.ts +7 -1
  99. package/dist/orders/commit-edit.js +5 -1
  100. package/dist/orders/drafts.d.ts +800 -0
  101. package/dist/orders/drafts.js +771 -0
  102. package/dist/orders/fields.d.ts +245 -0
  103. package/dist/orders/fields.js +188 -0
  104. package/dist/orders/get.d.ts +29 -19
  105. package/dist/orders/get.js +17 -8
  106. package/dist/orders/index.d.ts +49 -9
  107. package/dist/orders/index.js +22 -2
  108. package/dist/orders/lifecycle.d.ts +128 -0
  109. package/dist/orders/lifecycle.js +158 -0
  110. package/dist/orders/line-price-preview.d.ts +7 -2
  111. package/dist/orders/list.d.ts +222 -0
  112. package/dist/orders/list.js +377 -0
  113. package/dist/orders/manual-pricing.d.ts +5 -0
  114. package/dist/orders/order-entry.d.ts +20 -7
  115. package/dist/orders/plan-edit.d.ts +1 -1
  116. package/dist/orders/plan-edit.js +4 -1
  117. package/dist/orders/settings.d.ts +201 -0
  118. package/dist/orders/settings.js +325 -0
  119. package/dist/orders/status.d.ts +159 -13
  120. package/dist/orders/status.js +21 -0
  121. package/dist/orders/surcharges.d.ts +8 -1
  122. package/dist/orders/surcharges.js +3 -2
  123. package/dist/payments/account-credit.d.ts +30 -0
  124. package/dist/payments/account-credit.js +19 -0
  125. package/dist/payments/ar.d.ts +292 -0
  126. package/dist/payments/ar.js +223 -0
  127. package/dist/payments/connected-account.d.ts +47 -0
  128. package/dist/payments/connected-account.js +61 -0
  129. package/dist/payments/credit-noted-fields.d.ts +12 -0
  130. package/dist/payments/credit-noted-fields.js +37 -0
  131. package/dist/payments/index.d.ts +257 -11
  132. package/dist/payments/index.js +131 -1
  133. package/dist/payments/methods.d.ts +303 -8
  134. package/dist/payments/methods.js +337 -7
  135. package/dist/payments/mollie-methods.d.ts +159 -0
  136. package/dist/payments/mollie-methods.js +141 -0
  137. package/dist/payments/payment-links.d.ts +180 -0
  138. package/dist/payments/payment-links.js +97 -0
  139. package/dist/payments/provider-keys.d.ts +150 -0
  140. package/dist/payments/provider-keys.js +118 -0
  141. package/dist/payments/providers.d.ts +86 -11
  142. package/dist/payments/providers.js +29 -0
  143. package/dist/payments/requests.d.ts +144 -0
  144. package/dist/payments/requests.js +92 -0
  145. package/dist/payments/store-credit-fields.d.ts +15 -0
  146. package/dist/payments/store-credit-fields.js +51 -0
  147. package/dist/pickups/index.d.ts +104 -0
  148. package/dist/pickups/index.js +105 -0
  149. package/dist/platform/channels.d.ts +132 -0
  150. package/dist/platform/channels.js +128 -0
  151. package/dist/platform/geo.d.ts +123 -0
  152. package/dist/platform/geo.js +144 -0
  153. package/dist/platform/tax.d.ts +154 -0
  154. package/dist/platform/tax.js +139 -0
  155. package/dist/pos/anomalies.d.ts +158 -0
  156. package/dist/pos/anomalies.js +64 -0
  157. package/dist/pos/assisted-selling.d.ts +79 -0
  158. package/dist/pos/assisted-selling.js +38 -0
  159. package/dist/pos/exchanges.d.ts +103 -0
  160. package/dist/pos/exchanges.js +22 -0
  161. package/dist/pos/gift-cards.d.ts +135 -0
  162. package/dist/pos/gift-cards.js +47 -0
  163. package/dist/pos/index.d.ts +2125 -32
  164. package/dist/pos/index.js +742 -4
  165. package/dist/pos/no-receipt.d.ts +94 -0
  166. package/dist/pos/no-receipt.js +25 -0
  167. package/dist/pos/offline-sales.d.ts +187 -0
  168. package/dist/pos/offline-sales.js +116 -0
  169. package/dist/pos/pay-by-link.d.ts +143 -0
  170. package/dist/pos/pay-by-link.js +57 -0
  171. package/dist/pos/quick-keys.d.ts +103 -0
  172. package/dist/pos/quick-keys.js +45 -0
  173. package/dist/pos/reports.d.ts +360 -0
  174. package/dist/pos/reports.js +62 -0
  175. package/dist/pos/returns.d.ts +217 -0
  176. package/dist/pos/returns.js +53 -0
  177. package/dist/pricing/bulk-coupons.d.ts +139 -0
  178. package/dist/pricing/bulk-coupons.js +112 -0
  179. package/dist/pricing/index.d.ts +174 -4
  180. package/dist/pricing/index.js +174 -1
  181. package/dist/pricing/price-lists.d.ts +604 -0
  182. package/dist/pricing/price-lists.js +600 -0
  183. package/dist/purchasing/alerts.d.ts +89 -0
  184. package/dist/purchasing/alerts.js +62 -0
  185. package/dist/purchasing/cost.d.ts +110 -0
  186. package/dist/purchasing/cost.js +86 -0
  187. package/dist/purchasing/index.d.ts +36 -0
  188. package/dist/purchasing/index.js +16 -0
  189. package/dist/purchasing/purchase-orders.d.ts +548 -0
  190. package/dist/purchasing/purchase-orders.js +491 -0
  191. package/dist/purchasing/replenishment.d.ts +281 -0
  192. package/dist/purchasing/replenishment.js +240 -0
  193. package/dist/purchasing/settings.d.ts +152 -0
  194. package/dist/purchasing/settings.js +181 -0
  195. package/dist/purchasing/suppliers.d.ts +476 -0
  196. package/dist/purchasing/suppliers.js +438 -0
  197. package/dist/quotes/index.d.ts +501 -0
  198. package/dist/quotes/index.js +439 -0
  199. package/dist/reports/index.d.ts +71 -8
  200. package/dist/reports/index.js +74 -11
  201. package/dist/returns/index.d.ts +614 -21
  202. package/dist/returns/index.js +695 -11
  203. package/dist/search/index.d.ts +76 -1
  204. package/dist/search/index.js +63 -0
  205. package/dist/shipping/definitions.d.ts +29 -0
  206. package/dist/shipping/definitions.js +47 -0
  207. package/dist/shipping/fulfillment-profiles.d.ts +174 -0
  208. package/dist/shipping/fulfillment-profiles.js +104 -0
  209. package/dist/shipping/hendriks.d.ts +97 -0
  210. package/dist/shipping/hendriks.js +50 -0
  211. package/dist/shipping/index.d.ts +48 -0
  212. package/dist/shipping/index.js +25 -0
  213. package/dist/shipping/methods.d.ts +198 -0
  214. package/dist/shipping/methods.js +240 -0
  215. package/dist/shipping/myparcel.d.ts +254 -0
  216. package/dist/shipping/myparcel.js +178 -0
  217. package/dist/shipping/parcel-count-suggestion.d.ts +2 -0
  218. package/dist/shipping/parcel-rule.d.ts +6 -5
  219. package/dist/shipping/parcel-rule.js +21 -23
  220. package/dist/shipping/rate-tables.d.ts +179 -0
  221. package/dist/shipping/rate-tables.js +184 -0
  222. package/dist/stock/index.d.ts +10 -3
  223. package/dist/stock/index.js +3 -0
  224. package/dist/stock/locations.d.ts +144 -0
  225. package/dist/stock/locations.js +168 -0
  226. package/dist/stock/transfers.d.ts +216 -43
  227. package/dist/stock/transfers.js +140 -13
  228. package/dist/stored-value/index.d.ts +214 -4
  229. package/dist/stored-value/index.js +152 -0
  230. package/dist/subscriptions/index.d.ts +682 -0
  231. package/dist/subscriptions/index.js +815 -0
  232. package/dist/tax/index.d.ts +76 -1
  233. package/dist/tax/index.js +50 -0
  234. package/dist/tenant/email-style.d.ts +102 -0
  235. package/dist/tenant/email-style.js +72 -0
  236. package/dist/tenant/email-templates.d.ts +66 -0
  237. package/dist/tenant/email-templates.js +54 -0
  238. package/dist/tenant/notifications.d.ts +23 -17
  239. package/dist/tenant/settings-sources.d.ts +1 -1
  240. package/dist/tenant/time-zone.d.ts +17 -0
  241. package/dist/tenant/time-zone.js +11 -0
  242. package/dist/types.d.ts +50 -3
  243. package/dist/users/index.d.ts +3 -0
  244. package/dist/users/index.js +2 -0
  245. package/dist/users/warehouses.d.ts +50 -0
  246. package/dist/users/warehouses.js +51 -0
  247. package/package.json +2 -2
@@ -0,0 +1,167 @@
1
+ /**
2
+ * `admin.fulfillments.create` and `admin.fulfillments.profileChargePreview`: the shared create
3
+ * flow's write and its office-only delivery-charge preview (headless W10-38; spec
4
+ * `decoupling-fulfillments` §13, §15.4).
5
+ *
6
+ * The create answers the warehouse API's union: a refusal of the WHOLE call is thrown through
7
+ * `warehouseRefusalError`, so a code reaches a caller as the same class from `create` as from
8
+ * `fulfillments.warehouse.append` and the warehouse reads (`INVALID_INPUT` a `ValidationError`
9
+ * 400, never a 422). Each group's own refusal is data in `results[].error`.
10
+ */
11
+ import { type Transport } from '@sixtyninecommerce/core';
12
+ import type { Call } from '../types.js';
13
+ import { type KeyedWarehouseCall, type WarehouseFulfillment, type WarehouseFulfillmentLineInput, type WarehouseHandlerArg, type WarehouseRefusal } from './warehouse.js';
14
+ /** One fulfilment to create: the lines it ships and its carrier. */
15
+ export interface CreateFulfillmentGroupInput {
16
+ /** 1–500 lines, each a whole quantity of 1 or more, at most what is left to ship. */
17
+ lines: WarehouseFulfillmentLineInput[];
18
+ /** The carrier (fulfilment handler) code; `fulfillments.warehouse.handlers()` lists them. */
19
+ handlerCode: string;
20
+ /**
21
+ * The carrier's own arguments, as text. Send every name in the carrier's
22
+ * `argsRequiredForCreate`; the warehouse, profile and pick override are set by the engine.
23
+ */
24
+ handlerArgs?: WarehouseHandlerArg[];
25
+ /** Office staff only (`OFFICE_ONLY` otherwise): the profile whose minimum and delivery charge apply. */
26
+ fulfillmentProfileId?: string;
27
+ }
28
+ /** What `create` sends: one fulfilment per group, all shipping from one warehouse. */
29
+ export interface CreateFulfillmentsInput {
30
+ /** The warehouse every group ships from; it must be in the caller's scope. */
31
+ stockLocationId: string;
32
+ /** 1–50 groups. */
33
+ groups: CreateFulfillmentGroupInput[];
34
+ /**
35
+ * Claim each created in-house fulfilment for the caller (`Picking`). Only on a store with the
36
+ * warehouse workspace (`WAREHOUSE_NOT_ENABLED` otherwise).
37
+ */
38
+ startPicking?: boolean;
39
+ /**
40
+ * Office staff with no location restriction only: ship lines whose order picked another
41
+ * warehouse from this one (`OFFICE_ONLY` / `LOCATION_OUT_OF_SCOPE` otherwise).
42
+ */
43
+ overridePreferredLocation?: boolean;
44
+ }
45
+ /** What became of one group, by its position in the input. */
46
+ export interface CreateFulfillmentGroupResult {
47
+ index: number;
48
+ /** The fulfilment as it now is; null when the group was refused. */
49
+ fulfillment: WarehouseFulfillment | null;
50
+ /** Why the group was refused; nothing of it was written. */
51
+ error: WarehouseRefusal | null;
52
+ /** Set when the fulfilment WAS created but `startPicking` could not claim it. */
53
+ claimError: WarehouseRefusal | null;
54
+ }
55
+ /** Every group of a `create`, each on its own. */
56
+ export interface CreateFulfillmentsResult {
57
+ results: CreateFulfillmentGroupResult[];
58
+ created: number;
59
+ failed: number;
60
+ }
61
+ /** What `profileChargePreview` prices: a profile and the lines one fulfilment would ship. */
62
+ export interface FulfillmentProfileChargePreviewInput {
63
+ fulfillmentProfileId: string;
64
+ /** 1–500 lines, each a whole quantity of 1 or more. */
65
+ lines: Array<{
66
+ orderLineId: string;
67
+ quantity: number;
68
+ }>;
69
+ }
70
+ /**
71
+ * A fulfilment profile's minimum and delivery charge for a selection. Nothing was written. Money
72
+ * is integer MINOR UNITS of `currencyCode`.
73
+ */
74
+ export interface FulfillmentProfileChargePreview {
75
+ profileName: string;
76
+ currencyCode: string;
77
+ /** The profile's minimum order value, NET. */
78
+ minOrder: number;
79
+ /**
80
+ * The net value the minimum is judged on: the selected lines' combined net, or, for a whole
81
+ * order that met the minimum when it was placed, its lines that count toward minimums.
82
+ */
83
+ selectedNet: number;
84
+ /** How far the selection is below the minimum; 0 when it is met. */
85
+ shortfall: number;
86
+ /** What the profile's shipping method charges for these lines; null when none would be added. */
87
+ deliveryCharge: number | null;
88
+ /** Whether `deliveryCharge` includes tax; null with no charge. */
89
+ deliveryChargeIncludesTax: boolean | null;
90
+ /**
91
+ * Every order the delivery is for already paid delivery at checkout, so no charge is added.
92
+ * When nothing is delivered (`handedOver`), whether every order is fully paid.
93
+ */
94
+ settled: boolean;
95
+ /**
96
+ * Nothing in the selection is delivered (collected, sold at a till, nothing to ship): the
97
+ * minimum and the delivery charge do not apply (`minOrder` and `shortfall` 0, no charge); the
98
+ * profile still picks the warehouse.
99
+ */
100
+ handedOver: boolean;
101
+ }
102
+ export interface FulfillmentCreateMethods {
103
+ /**
104
+ * Create fulfilments at one warehouse: one per group, each in its own transaction, through the
105
+ * same create path as the order page. A group that is refused is reported in its
106
+ * `results[].error` and the rest go on, so the answer can mix created and refused groups.
107
+ * Needs `UpdateFulfillment` (warehouse staff, on a store with the warehouse workspace, at a
108
+ * warehouse assigned to them) or `UpdateOrder` (office staff, on any store, at any of its
109
+ * warehouses).
110
+ *
111
+ * MONEY and outside effects, per created fulfilment: a fulfilment profile (office only) can
112
+ * add a delivery charge to its orders, shared across a consolidation; on a store without the
113
+ * warehouse workspace the carrier is booked at create (a label bought, or a 3PL handed the
114
+ * order; with the workspace it is booked later, at Packed); the customer gets the
115
+ * `fulfillment_created` e-mail.
116
+ *
117
+ * A line nobody picked a warehouse for, whose stock is reserved at another warehouse, has its
118
+ * reservation moved here: released there and taken from this warehouse, as it is for
119
+ * warehouse staff assigned here (a line whose order picked another warehouse is refused
120
+ * `LINE_PREFERS_OTHER_LOCATION`, unless the office sets `overridePreferredLocation`).
121
+ *
122
+ * One key per attempt (`options.idempotencyKey`): a repeat under the same key answers the
123
+ * first call's result (each fulfilment as it is now) and creates nothing, however few of a
124
+ * line's units it asked for. Another request under that key is `IDEMPOTENCY_CONFLICT`
125
+ * (`ConflictError`, 409). The groups commit one by one, so the engine spends the key before the
126
+ * first: a repeat while the first is still running, or after it stopped without answering, is
127
+ * `IDEMPOTENCY_OUTCOME_UNKNOWN` (`outcomeUnknown`): read the orders' fulfilments, never create
128
+ * again under a new key blind; once the first has answered, the key replays its answer. A
129
+ * refusal of the whole call does not spend the key. Left out, a key is made up (a UUIDv7) and
130
+ * returned as `idempotencyKey` on the result, and on a thrown error as an untyped own property
131
+ * of the error.
132
+ *
133
+ * Refusals. Of the whole call, THROWN, with the classes of every warehouse refusal:
134
+ * `INVALID_INPUT` (a `ValidationError`, 400; also before any request for a missing warehouse,
135
+ * no groups, a group without a carrier or a line without an id or a whole quantity),
136
+ * `LOCATION_OUT_OF_SCOPE`, `OFFICE_ONLY`, `WAREHOUSE_NOT_ENABLED` (`BusinessRuleError`, 422).
137
+ * Of one group, as DATA: `COMBINE_RULE_VIOLATED` (the part of the rule that broke in
138
+ * `field`), `LINE_OVER_FULFILLED`, `INSUFFICIENT_STOCK_AT_LOCATION`, `ORDER_NOT_COVERED`,
139
+ * `PROFILE_MINIMUM_NOT_MET` (a consolidation short of the profile minimum; one order short of it
140
+ * is `INVALID_INPUT`, its sentence naming the minimum), `SOURCE_FULFILLED_BLOCKED`, a carrier's
141
+ * own refusal, … A missing
142
+ * permission is `FORBIDDEN` and a carrier of a plugin the store does not have
143
+ * `PLUGIN_ACCESS_DENIED` (both `PermissionDeniedError`, 403).
144
+ *
145
+ * @effect money
146
+ */
147
+ create(input: CreateFulfillmentsInput, options?: KeyedWarehouseCall): Promise<CreateFulfillmentsResult & {
148
+ idempotencyKey: string;
149
+ }>;
150
+ /**
151
+ * What a fulfilment profile would ask of a selection before it is created: its minimum, how
152
+ * far the selection is below it, and the delivery charge it would add. Office staff only
153
+ * (`UpdateOrder`). Who pays which share of a consolidated charge is decided at create. Money in
154
+ * integer minor units.
155
+ *
156
+ * A malformed or unknown profile or line, no lines or more than 500, a bad quantity, or orders
157
+ * in different currencies are `FULFILLMENT_PROFILE_PREVIEW_INVALID` (a `ValidationError`,
158
+ * 400); a selection the create would refuse answers that code (`LOCATION_OUT_OF_SCOPE`,
159
+ * `COMBINE_RULE_VIOLATED`, `PROFILE_CURRENCY_MISMATCH`, `BusinessRuleError`).
160
+ *
161
+ * @effect read
162
+ */
163
+ profileChargePreview(input: FulfillmentProfileChargePreviewInput, options?: Call): Promise<FulfillmentProfileChargePreview>;
164
+ }
165
+ export declare const CREATE_WAREHOUSE_FULFILLMENTS_MUTATION = "\n mutation CreateWarehouseFulfillments(\n $input: CreateWarehouseFulfillmentsInput!\n $idempotencyKey: String\n ) {\n createWarehouseFulfillments(input: $input, idempotencyKey: $idempotencyKey) {\n __typename\n ... on WarehouseCreateResult {\n created\n failed\n results {\n index\n fulfillment {\n \n id\n state\n handlerCode\n method\n mode\n trackingCode\n stockLocationId\n stockLocationName\n createdAt\n stateChangedAt\n overdue\n claimedBy {\n id\n name\n }\n claimedAt\n packedAt\n bookingStatus\n bookingError\n parcels {\n weightGrams\n lengthMm\n widthMm\n heightMm\n }\n orders {\n id\n code\n poNumber\n orderNotes\n requestedDeliveryDate\n deliveryDue\n paymentBadge\n hold {\n reason\n note\n }\n }\n customer {\n id\n name\n phone\n }\n shippingAddress {\n \n fullName\n company\n streetLine1\n streetLine2\n city\n province\n postalCode\n countryCode\n\n }\n lineCount\n unitCount\n\n }\n error {\n code\n message\n field\n }\n claimError {\n code\n message\n field\n }\n }\n }\n ... on WarehouseError {\n errorCode\n code\n message\n field\n }\n }\n }\n";
166
+ export declare const FULFILLMENT_PROFILE_CHARGE_PREVIEW_QUERY = "\n query FulfillmentProfileChargePreview($input: FulfillmentProfileChargePreviewInput!) {\n fulfillmentProfileChargePreview(input: $input) {\n profileName\n currencyCode\n minOrder\n selectedNet\n shortfall\n deliveryCharge\n deliveryChargeIncludesTax\n settled\n handedOver\n }\n }\n";
167
+ export declare function createFulfillmentCreateMethods(transport: Transport): FulfillmentCreateMethods;
@@ -0,0 +1,216 @@
1
+ /**
2
+ * `admin.fulfillments.create` and `admin.fulfillments.profileChargePreview`: the shared create
3
+ * flow's write and its office-only delivery-charge preview (headless W10-38; spec
4
+ * `decoupling-fulfillments` §13, §15.4).
5
+ *
6
+ * The create answers the warehouse API's union: a refusal of the WHOLE call is thrown through
7
+ * `warehouseRefusalError`, so a code reaches a caller as the same class from `create` as from
8
+ * `fulfillments.warehouse.append` and the warehouse reads (`INVALID_INPUT` a `ValidationError`
9
+ * 400, never a 422). Each group's own refusal is data in `results[].error`.
10
+ */
11
+ import { idempotencyKey as mintIdempotencyKey, ValidationError, } from '@sixtyninecommerce/core';
12
+ import { assertId, FULFILLMENT_FIELDS, invalid, isWarehouseErrorMember, toFulfillment, toRefusal, warehouseRefusalError, withAttemptKey, } from './warehouse.js';
13
+ export const CREATE_WAREHOUSE_FULFILLMENTS_MUTATION = /* GraphQL */ `
14
+ mutation CreateWarehouseFulfillments(
15
+ $input: CreateWarehouseFulfillmentsInput!
16
+ $idempotencyKey: String
17
+ ) {
18
+ createWarehouseFulfillments(input: $input, idempotencyKey: $idempotencyKey) {
19
+ __typename
20
+ ... on WarehouseCreateResult {
21
+ created
22
+ failed
23
+ results {
24
+ index
25
+ fulfillment {
26
+ ${FULFILLMENT_FIELDS}
27
+ }
28
+ error {
29
+ code
30
+ message
31
+ field
32
+ }
33
+ claimError {
34
+ code
35
+ message
36
+ field
37
+ }
38
+ }
39
+ }
40
+ ... on WarehouseError {
41
+ errorCode
42
+ code
43
+ message
44
+ field
45
+ }
46
+ }
47
+ }
48
+ `;
49
+ export const FULFILLMENT_PROFILE_CHARGE_PREVIEW_QUERY = /* GraphQL */ `
50
+ query FulfillmentProfileChargePreview($input: FulfillmentProfileChargePreviewInput!) {
51
+ fulfillmentProfileChargePreview(input: $input) {
52
+ profileName
53
+ currencyCode
54
+ minOrder
55
+ selectedNet
56
+ shortfall
57
+ deliveryCharge
58
+ deliveryChargeIncludesTax
59
+ settled
60
+ handedOver
61
+ }
62
+ }
63
+ `;
64
+ const isObject = (value) => typeof value === 'object' && value !== null;
65
+ /**
66
+ * Refused before any request: each of these would otherwise fail GraphQL validation with no code.
67
+ * Bounds the engine checks (group and line counts, quantities, ids that are not uuids) are left
68
+ * to it.
69
+ */
70
+ function assertCreateInput(input) {
71
+ if (!isObject(input))
72
+ throw invalid('input', 'Name the warehouse and the groups to create.');
73
+ assertId(input.stockLocationId, 'stockLocationId');
74
+ const groups = input.groups;
75
+ if (!Array.isArray(groups) || groups.length === 0) {
76
+ throw invalid('groups', 'Add at least one group of lines to fulfill.');
77
+ }
78
+ for (const [index, group] of groups.entries()) {
79
+ const at = `groups[${String(index)}]`;
80
+ if (!isObject(group))
81
+ throw invalid(at, `Group ${String(index + 1)} is not a group of lines.`);
82
+ if (typeof group.handlerCode !== 'string' || group.handlerCode.trim() === '') {
83
+ throw invalid(`${at}.handlerCode`, `Group ${String(index + 1)}: choose a carrier (fulfillment handler).`);
84
+ }
85
+ if (!Array.isArray(group.lines)) {
86
+ throw invalid(`${at}.lines`, `Group ${String(index + 1)}: list the lines it ships.`);
87
+ }
88
+ for (const [lineIndex, line] of group.lines.entries()) {
89
+ const lineAt = `${at}.lines[${String(lineIndex)}]`;
90
+ assertId(isObject(line) ? line.orderLineId : undefined, `${lineAt}.orderLineId`);
91
+ if (!Number.isInteger(line.quantity)) {
92
+ throw invalid(`${lineAt}.quantity`, 'A quantity is a whole number.');
93
+ }
94
+ }
95
+ if (group.handlerArgs !== undefined && !Array.isArray(group.handlerArgs)) {
96
+ throw invalid(`${at}.handlerArgs`, 'The carrier arguments are a list of names and values.');
97
+ }
98
+ for (const [argIndex, arg] of (group.handlerArgs ?? []).entries()) {
99
+ if (!isObject(arg) || typeof arg.name !== 'string' || typeof arg.value !== 'string') {
100
+ throw invalid(`${at}.handlerArgs[${String(argIndex)}]`, 'Each carrier argument has a name and a value, both text.');
101
+ }
102
+ }
103
+ }
104
+ }
105
+ function invalidPreview(field, message) {
106
+ return new ValidationError({
107
+ code: 'FULFILLMENT_PROFILE_PREVIEW_INVALID',
108
+ message,
109
+ status: 400,
110
+ service: 'vendure',
111
+ details: [{ field, code: 'FULFILLMENT_PROFILE_PREVIEW_INVALID', message }],
112
+ });
113
+ }
114
+ /** Refused before any request, with the engine's own code: each would fail GraphQL validation. */
115
+ function assertPreviewInput(input) {
116
+ if (!isObject(input))
117
+ throw invalidPreview('input', 'Name a profile and the lines to preview.');
118
+ const profileId = input.fulfillmentProfileId;
119
+ if (typeof profileId !== 'string' || profileId.trim() === '') {
120
+ throw invalidPreview('fulfillmentProfileId', 'A fulfillment profile id is required.');
121
+ }
122
+ if (!Array.isArray(input.lines)) {
123
+ throw invalidPreview('lines', 'List the lines the fulfillment would ship.');
124
+ }
125
+ for (const [index, line] of input.lines.entries()) {
126
+ const at = `lines[${String(index)}]`;
127
+ const id = isObject(line) ? line.orderLineId : undefined;
128
+ if (typeof id !== 'string' || id.trim() === '') {
129
+ throw invalidPreview(`${at}.orderLineId`, 'Each line names its order line.');
130
+ }
131
+ if (!Number.isInteger(line.quantity)) {
132
+ throw invalidPreview(`${at}.quantity`, 'A quantity is a whole number.');
133
+ }
134
+ }
135
+ }
136
+ export function createFulfillmentCreateMethods(transport) {
137
+ return {
138
+ async create(input, options) {
139
+ assertCreateInput(input);
140
+ const key = options?.idempotencyKey ?? mintIdempotencyKey();
141
+ try {
142
+ const data = await transport.graphql({
143
+ api: 'admin',
144
+ query: CREATE_WAREHOUSE_FULFILLMENTS_MUTATION,
145
+ variables: {
146
+ input: {
147
+ stockLocationId: input.stockLocationId,
148
+ groups: input.groups.map((group) => ({
149
+ lines: group.lines.map(({ orderLineId, quantity }) => ({
150
+ orderLineId,
151
+ quantity,
152
+ })),
153
+ handlerCode: group.handlerCode,
154
+ ...(group.handlerArgs
155
+ ? { handlerArgs: group.handlerArgs.map(({ name, value }) => ({ name, value })) }
156
+ : {}),
157
+ ...(group.fulfillmentProfileId
158
+ ? { fulfillmentProfileId: group.fulfillmentProfileId }
159
+ : {}),
160
+ })),
161
+ ...(input.startPicking === undefined ? {} : { startPicking: input.startPicking }),
162
+ ...(input.overridePreferredLocation === undefined
163
+ ? {}
164
+ : { overridePreferredLocation: input.overridePreferredLocation }),
165
+ },
166
+ idempotencyKey: key,
167
+ },
168
+ }, { ...options, idempotencyKey: key });
169
+ const result = data.createWarehouseFulfillments;
170
+ // The whole call refused: classified like every other warehouse refusal (W10-37 F-4).
171
+ if (isWarehouseErrorMember(result))
172
+ throw warehouseRefusalError(result);
173
+ const outcome = result;
174
+ return {
175
+ created: outcome.created,
176
+ failed: outcome.failed,
177
+ results: outcome.results.map((item) => ({
178
+ index: item.index,
179
+ fulfillment: item.fulfillment ? toFulfillment(item.fulfillment) : null,
180
+ error: toRefusal(item.error),
181
+ claimError: toRefusal(item.claimError),
182
+ })),
183
+ idempotencyKey: key,
184
+ };
185
+ }
186
+ catch (error) {
187
+ throw withAttemptKey(error, key);
188
+ }
189
+ },
190
+ async profileChargePreview(input, options) {
191
+ assertPreviewInput(input);
192
+ const data = await transport.graphql({
193
+ api: 'admin',
194
+ query: FULFILLMENT_PROFILE_CHARGE_PREVIEW_QUERY,
195
+ variables: {
196
+ input: {
197
+ fulfillmentProfileId: input.fulfillmentProfileId,
198
+ lines: input.lines.map(({ orderLineId, quantity }) => ({ orderLineId, quantity })),
199
+ },
200
+ },
201
+ }, options);
202
+ const preview = data.fulfillmentProfileChargePreview;
203
+ return {
204
+ profileName: preview.profileName,
205
+ currencyCode: preview.currencyCode,
206
+ minOrder: preview.minOrder,
207
+ selectedNet: preview.selectedNet,
208
+ shortfall: preview.shortfall,
209
+ deliveryCharge: preview.deliveryCharge ?? null,
210
+ deliveryChargeIncludesTax: preview.deliveryChargeIncludesTax ?? null,
211
+ settled: preview.settled,
212
+ handedOver: preview.handedOver,
213
+ };
214
+ },
215
+ };
216
+ }
@@ -1,6 +1,10 @@
1
1
  import { type Transport } from '@sixtyninecommerce/core';
2
2
  import type { OrderOverpaymentChoice, OverpaymentOption } from '../orders/surcharges.js';
3
3
  import type { Call } from '../types.js';
4
+ import { type FulfillmentCreateMethods } from './create.js';
5
+ import { type FulfillmentPaymentPolicyModule } from './payment-policy.js';
6
+ import { type WarehouseDemandRouting, type WarehouseFulfillmentsModule } from './warehouse.js';
7
+ export type { WarehouseDemandRouting };
4
8
  /**
5
9
  * A fulfillment's parcels as the order records them: one MyParcel shipment per
6
10
  * parcel, and the barcodes the carrier has issued so far.
@@ -40,8 +44,6 @@ export interface FulfillmentParcelTracking {
40
44
  parcelCount: number;
41
45
  }
42
46
  export type FulfillmentLabelFormat = 'A4' | 'A6';
43
- /** How a warehouse's "To ship" queue routes a line (`WarehouseDemandRouting`). */
44
- export type WarehouseDemandRouting = 'preferred' | 'allocated' | 'unrouted' | 'no_stock';
45
47
  /**
46
48
  * Which "To ship" entry of an order to read. The entry, and so whether it
47
49
  * holds the whole order, depends on the warehouse and on the routing filters:
@@ -196,6 +198,11 @@ export interface FulfillmentCancelSettlement {
196
198
  amount: number;
197
199
  currencyCode: string;
198
200
  choice: OrderOverpaymentChoice;
201
+ /**
202
+ * For `ACCOUNT_CREDIT`: the store's customer-credit book the credit lands in (`AR` or
203
+ * `STORE_CREDIT`); null for `REFUND` and from an engine before it.
204
+ */
205
+ book?: string | null;
199
206
  }
200
207
  /** A cancelled fulfillment and what its cancel queued. */
201
208
  export interface CancelledFulfillment {
@@ -262,8 +269,11 @@ export declare const FULFILLMENT_COVERAGE_REASON_MAX_LENGTH = 500;
262
269
  * Fulfillment parcels (multi-parcel shipments). Each method is its own request
263
270
  * on purpose: a caller deployed ahead of an engine without these fields sees
264
271
  * only that call refused, never the order or fulfillment read beside it.
272
+ *
273
+ * `create` and `profileChargePreview` (the shared create flow) are declared in
274
+ * `fulfillments/create.ts`.
265
275
  */
266
- export interface FulfillmentsModule {
276
+ export interface FulfillmentsModule extends FulfillmentCreateMethods {
267
277
  /** Every fulfillment of an order, with its parcels. Needs `ReadOrder`. */
268
278
  parcelsOfOrder(orderId: string, options?: Call): Promise<OrderFulfillmentParcels[]>;
269
279
  /**
@@ -281,7 +291,11 @@ export interface FulfillmentsModule {
281
291
  /**
282
292
  * Every parcel's MyParcel label merged by MyParcel into one PDF, fetched live
283
293
  * and never cached. Needs `ReadOrder`. Allowed up to 55s: the engine retries
284
- * a slow MyParcel within a budget the default timeout does not cover.
294
+ * a slow MyParcel within a budget the default timeout does not cover. A
295
+ * credential restricted to stock locations (an API token or app installation
296
+ * with `locationIds`) prints it only for a fulfillment that ships from one of
297
+ * them; any other, another store's and a missing one included, is
298
+ * `LOCATION_OUT_OF_SCOPE` (422).
285
299
  */
286
300
  myparcelLabel(fulfillmentId: string, format: FulfillmentLabelFormat, options?: Call): Promise<FulfillmentLabel>;
287
301
  /**
@@ -303,8 +317,11 @@ export interface FulfillmentsModule {
303
317
  * `NotFoundError` (`MYPARCEL_ORDER_NOT_FOUND_ERROR`); a cancelled one, or
304
318
  * one holding no shipment, a `BusinessRuleError`
305
319
  * (`MYPARCEL_VALIDATION_ERROR`), as is MyParcel switched off for the store
306
- * (`MYPARCEL_NOT_CONFIGURED_ERROR`). Only queues work, so the default
307
- * timeout applies.
320
+ * (`MYPARCEL_NOT_CONFIGURED_ERROR`). A credential restricted to stock
321
+ * locations (an API token or app installation with `locationIds`) is refused
322
+ * `LOCATION_OUT_OF_SCOPE` (422) first for a fulfillment that does not ship
323
+ * from one of them, another store's and a missing one included. Only queues
324
+ * work, so the default timeout applies.
308
325
  */
309
326
  labelMyparcelParcels(fulfillmentId: string, input?: LabelMyparcelParcelsInput, options?: Call): Promise<MyparcelParcelsLabelRequest>;
310
327
  /**
@@ -336,7 +353,10 @@ export interface FulfillmentsModule {
336
353
  * What cancelling the fulfillment would owe each order's customer back (a delivery charge
337
354
  * they already paid), and which ways of settling it are open. Read now, without a lock; the
338
355
  * cancel judges it again. Needs `UpdateOrder`. Another store's fulfillment is a
339
- * `NotFoundError` (`ENTITY_NOT_FOUND`).
356
+ * `NotFoundError` (`ENTITY_NOT_FOUND`). A credential restricted to stock locations (an API
357
+ * token or app installation with `locationIds`) reads it only for a fulfillment that ships
358
+ * from one of them; any other, another store's and a missing one included, is
359
+ * `LOCATION_OUT_OF_SCOPE` (422).
340
360
  */
341
361
  cancelPreview(fulfillmentId: string, options?: Call): Promise<FulfillmentCancelPreview>;
342
362
  /**
@@ -355,7 +375,10 @@ export interface FulfillmentsModule {
355
375
  * `AR_ACCOUNT_IN_ERP`, `ORDER_OVERPAYMENT_REFUND_UNRECONCILED`, …);
356
376
  * `FULFILLMENT_CANCEL_REFUSED` (→ `BusinessRuleError`) when the fulfillment's process refuses
357
377
  * the cancel (already cancelled, a carrier that cannot let go). Another store's fulfillment is
358
- * a `NotFoundError`.
378
+ * a `NotFoundError`. A credential restricted to stock locations (an API token or app
379
+ * installation with `locationIds`) cancels only a fulfillment that ships from one of them; any
380
+ * other (one with no recorded warehouse, another store's and a missing one included) is
381
+ * `LOCATION_OUT_OF_SCOPE` (422), before the key is claimed.
359
382
  *
360
383
  * `options.idempotencyKey`: a repeat under it answers the first call's result, never a second
361
384
  * cancel; the same key with a different choice is `IDEMPOTENCY_CONFLICT`.
@@ -389,14 +412,25 @@ export interface FulfillmentsModule {
389
412
  allowUncovered(orderId: string, reason: string, options?: Call & {
390
413
  idempotencyKey?: string;
391
414
  }): Promise<FulfillmentCoverageOverride>;
415
+ /**
416
+ * The store's fulfilment payment policy (`fulfillmentPaymentPolicy`): whether a fulfilment of
417
+ * an order not paid in full is refused `ORDER_NOT_COVERED`, and which payment methods are
418
+ * exempt. Read as the engine applies it; written whole (`UpdateChannel`).
419
+ */
420
+ paymentPolicy: FulfillmentPaymentPolicyModule;
421
+ /**
422
+ * The pick/pack/ship workspace: the warehouse API (price-free, location-scoped), the pick list
423
+ * and consolidation. See `fulfillments/warehouse.ts`.
424
+ */
425
+ warehouse: WarehouseFulfillmentsModule;
392
426
  }
393
427
  /**
394
428
  * Its own document, like every call here: on an engine without the query this call alone fails
395
429
  * validation.
396
430
  */
397
- export declare const FULFILLMENT_CANCEL_PREVIEW_QUERY = "\n query FulfillmentCancelPreview($fulfillmentId: ID!) {\n fulfillmentCancelPreview(fulfillmentId: $fulfillmentId) {\n fulfillmentId\n overpayments {\n orderId\n orderCode\n amount\n currencyCode\n refund { \n available\n code\n message\n }\n accountCredit { \n available\n code\n message\n }\n }\n }\n }\n";
431
+ export declare const FULFILLMENT_CANCEL_PREVIEW_QUERY = "\n query FulfillmentCancelPreview($fulfillmentId: ID!) {\n fulfillmentCancelPreview(fulfillmentId: $fulfillmentId) {\n fulfillmentId\n overpayments {\n orderId\n orderCode\n amount\n currencyCode\n refund { \n available\n code\n message\n book\n }\n accountCredit { \n available\n code\n message\n book\n }\n }\n }\n }\n";
398
432
  /** `$overpayment` and `$idempotencyKey` are optional and left out of the variables when not given. */
399
- export declare const CANCEL_FULFILLMENT_MUTATION = "\n mutation CancelFulfillment(\n $fulfillmentId: ID!\n $overpayment: [FulfillmentCancelOverpaymentInput!]\n $idempotencyKey: String\n ) {\n cancelFulfillment(\n fulfillmentId: $fulfillmentId\n overpayment: $overpayment\n idempotencyKey: $idempotencyKey\n ) {\n fulfillment {\n id\n state\n }\n settlements {\n orderId\n orderCode\n amount\n currencyCode\n choice\n }\n }\n }\n";
433
+ export declare const CANCEL_FULFILLMENT_MUTATION = "\n mutation CancelFulfillment(\n $fulfillmentId: ID!\n $overpayment: [FulfillmentCancelOverpaymentInput!]\n $idempotencyKey: String\n ) {\n cancelFulfillment(\n fulfillmentId: $fulfillmentId\n overpayment: $overpayment\n idempotencyKey: $idempotencyKey\n ) {\n fulfillment {\n id\n state\n }\n settlements {\n orderId\n orderCode\n amount\n currencyCode\n choice\n book\n }\n }\n }\n";
400
434
  /** Its own document: on an engine without the query this call alone fails validation. */
401
435
  export declare const ORDER_FULFILLMENT_COVERAGE_QUERY = "\n query OrderFulfillmentCoverage($orderId: ID!) {\n orderFulfillmentCoverage(orderId: $orderId) {\n orderId\n orderCode\n currencyCode\n policyActive\n covered\n outstanding\n exempt\n exemptReason\n allowed\n override { \n id\n orderId\n reason\n actorKind\n actorId\n outstandingAtGrant\n currencyCode\n createdAt\n active\n }\n }\n }\n";
402
436
  /** `$idempotencyKey` is optional and left out of the variables when not given. */
@@ -1,4 +1,8 @@
1
1
  import { errorFromErrorResult, isErrorResult, NotFoundError, ValidationError, } from '@sixtyninecommerce/core';
2
+ import { storeCreditAware } from '../payments/store-credit-fields.js';
3
+ import { createFulfillmentCreateMethods } from './create.js';
4
+ import { createFulfillmentPaymentPolicyModule, } from './payment-policy.js';
5
+ import { createWarehouseFulfillmentsModule, } from './warehouse.js';
2
6
  /** The longest override reason the engine stores. */
3
7
  export const FULFILLMENT_COVERAGE_REASON_MAX_LENGTH = 500;
4
8
  /** Every field of `OrderOverpaymentOption`. */
@@ -6,6 +10,7 @@ const OVERPAYMENT_OPTION_FIELDS = /* GraphQL */ `
6
10
  available
7
11
  code
8
12
  message
13
+ book
9
14
  `;
10
15
  /**
11
16
  * Its own document, like every call here: on an engine without the query this call alone fails
@@ -48,6 +53,7 @@ export const CANCEL_FULFILLMENT_MUTATION = /* GraphQL */ `
48
53
  amount
49
54
  currencyCode
50
55
  choice
56
+ book
51
57
  }
52
58
  }
53
59
  }
@@ -360,6 +366,9 @@ function assertLabelRequest(fulfillmentId, format) {
360
366
  }
361
367
  export function createFulfillmentsModule(transport) {
362
368
  return {
369
+ ...createFulfillmentCreateMethods(transport),
370
+ paymentPolicy: createFulfillmentPaymentPolicyModule(transport),
371
+ warehouse: createWarehouseFulfillmentsModule(transport),
363
372
  async parcelsOfOrder(orderId, options) {
364
373
  const data = await transport.graphql({ api: 'admin', query: ORDER_FULFILLMENT_PARCELS_QUERY, variables: { id: orderId } }, options);
365
374
  if (!data.order)
@@ -442,7 +451,7 @@ export function createFulfillmentsModule(transport) {
442
451
  if (typeof fulfillmentId !== 'string' || fulfillmentId.trim() === '') {
443
452
  throw invalidCancel('fulfillmentId', 'A fulfillment id is required.');
444
453
  }
445
- const data = await transport.graphql({ api: 'admin', query: FULFILLMENT_CANCEL_PREVIEW_QUERY, variables: { fulfillmentId } }, options);
454
+ const data = await storeCreditAware(transport).graphql({ api: 'admin', query: FULFILLMENT_CANCEL_PREVIEW_QUERY, variables: { fulfillmentId } }, options);
446
455
  const preview = data.fulfillmentCancelPreview;
447
456
  return {
448
457
  fulfillmentId: preview.fulfillmentId,
@@ -459,7 +468,7 @@ export function createFulfillmentsModule(transport) {
459
468
  async cancel(fulfillmentId, input = {}, options) {
460
469
  assertCancelRequest(fulfillmentId, input);
461
470
  const overpayment = input.overpayment ?? [];
462
- const data = await transport.graphql({
471
+ const data = await storeCreditAware(transport).graphql({
463
472
  api: 'admin',
464
473
  query: CANCEL_FULFILLMENT_MUTATION,
465
474
  // A variable, not a header: the Admin API takes the key as an argument.
@@ -0,0 +1,64 @@
1
+ import { type Transport } from '@sixtyninecommerce/core';
2
+ import type { Call } from '../types.js';
3
+ /** The most payment method codes `exemptMethodCodes` may name. */
4
+ export declare const FULFILLMENT_PAYMENT_POLICY_EXEMPT_METHODS_MAX = 50;
5
+ /** The longest payment method code the list accepts (`PaymentMethod.code` is a varchar(255)). */
6
+ export declare const FULFILLMENT_PAYMENT_POLICY_METHOD_CODE_MAX_LENGTH = 255;
7
+ /**
8
+ * The store's fulfilment payment policy (`Channel.customFields.fulfillmentPaymentPolicy`):
9
+ * whether goods are handed over before an order is paid in full. Every field present: this is
10
+ * what the engine APPLIES, absent and malformed fields read as their defaults (OFF).
11
+ */
12
+ export interface FulfillmentPaymentPolicy {
13
+ /**
14
+ * On: a fulfilment is created, extended or shipped only once the money COLLECTED for the
15
+ * order (settled, or held by a payment provider) covers what it bills, unless the order is
16
+ * exempt or an override was recorded (`fulfillments.allowUncovered`). Otherwise refused
17
+ * `ORDER_NOT_COVERED`.
18
+ */
19
+ requireFullPayment: boolean;
20
+ /**
21
+ * Payment method CODES whose orders are handed over unpaid as a matter of course (cash on
22
+ * delivery, a bank transfer the store ships against), judged on the order's latest live
23
+ * payment. Read as the engine compares them: trimmed, lower-cased, once each.
24
+ */
25
+ exemptMethodCodes: string[];
26
+ }
27
+ /** The policy of a store that never set one, and of a column that cannot be read: off. */
28
+ export declare const DEFAULT_FULFILLMENT_PAYMENT_POLICY: Readonly<FulfillmentPaymentPolicy>;
29
+ /**
30
+ * The ACTIVE store's fulfilment payment policy (`admin.fulfillments.paymentPolicy`), stored as a
31
+ * Channel custom field and written through core `updateChannel`.
32
+ *
33
+ * Reading needs an authenticated administrator on the store; writing needs `UpdateChannel`.
34
+ */
35
+ export interface FulfillmentPaymentPolicyModule {
36
+ /**
37
+ * The policy the engine applies, read as tolerantly as the engine reads it
38
+ * (`resolveFulfillmentPaymentPolicy`): a store that never set one, a malformed column and a
39
+ * field of the wrong type all answer OFF ({@link DEFAULT_FULFILLMENT_PAYMENT_POLICY}); the
40
+ * exempt codes are the non-blank ones, trimmed, lower-cased and once each.
41
+ */
42
+ get(options?: Call): Promise<FulfillmentPaymentPolicy>;
43
+ /**
44
+ * Replace the whole policy, and answer it as the engine now applies it.
45
+ *
46
+ * Both fields are required: read it with {@link get}, change what you mean to, and send it
47
+ * back. Only the schema's fields are stored, the codes trimmed.
48
+ *
49
+ * Refused before any request with `FULFILLMENT_PAYMENT_POLICY_INVALID` ({@link ValidationError},
50
+ * one `details[]` entry per failing field): a non-boolean switch, an exempt list that is not a
51
+ * list, holds a blank or over-long code, names one code twice in any case, or more than 50.
52
+ * The engine's own write validator refuses the same values (a `ValidationError` too, carrying
53
+ * its sentence), so a value that slips past this check is still never stored.
54
+ *
55
+ * Absent and "set to the defaults" mean the same thing to the engine, and a store's column is
56
+ * never backfilled: write the policy when a merchant changed it.
57
+ */
58
+ set(policy: FulfillmentPaymentPolicy, options?: Call): Promise<FulfillmentPaymentPolicy>;
59
+ }
60
+ export declare const FULFILLMENT_PAYMENT_POLICY_QUERY = "\n query FulfillmentPaymentPolicy {\n activeChannel { \n id\n customFields {\n fulfillmentPaymentPolicy\n }\n }\n }\n";
61
+ export declare const SET_FULFILLMENT_PAYMENT_POLICY_MUTATION = "\n mutation SetFulfillmentPaymentPolicy($input: UpdateChannelInput!) {\n updateChannel(input: $input) {\n ... on Channel { \n id\n customFields {\n fulfillmentPaymentPolicy\n }\n }\n ... on ErrorResult { errorCode message }\n }\n }\n";
62
+ /** A payment method code as the engine compares it (`normalizeMethodCode`). */
63
+ export declare function normalizeFulfillmentPolicyMethodCode(code: string): string;
64
+ export declare function createFulfillmentPaymentPolicyModule(transport: Transport): FulfillmentPaymentPolicyModule;