@sixtyninecommerce/admin 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/README.md +5772 -118
  2. package/dist/auth/index.d.ts +7 -1
  3. package/dist/auth/index.js +8 -1
  4. package/dist/catalog/assets.d.ts +120 -8
  5. package/dist/catalog/assets.js +98 -12
  6. package/dist/catalog/collections.d.ts +279 -14
  7. package/dist/catalog/collections.js +246 -15
  8. package/dist/catalog/documents.d.ts +142 -0
  9. package/dist/catalog/documents.js +114 -0
  10. package/dist/catalog/index.d.ts +54 -6
  11. package/dist/catalog/index.js +10 -1
  12. package/dist/catalog/metadata.d.ts +244 -0
  13. package/dist/catalog/metadata.js +220 -0
  14. package/dist/catalog/products.d.ts +159 -19
  15. package/dist/catalog/products.js +88 -13
  16. package/dist/catalog/properties.d.ts +140 -14
  17. package/dist/catalog/properties.js +65 -1
  18. package/dist/catalog/recommendations.d.ts +288 -0
  19. package/dist/catalog/recommendations.js +237 -0
  20. package/dist/catalog/reviews.d.ts +381 -0
  21. package/dist/catalog/reviews.js +325 -0
  22. package/dist/catalog/types.d.ts +17 -1
  23. package/dist/catalog/types.js +10 -0
  24. package/dist/catalog/variant-find.d.ts +136 -0
  25. package/dist/catalog/variant-find.js +239 -0
  26. package/dist/catalog/variants.d.ts +293 -26
  27. package/dist/catalog/variants.js +164 -7
  28. package/dist/catalog/visibility.d.ts +38 -7
  29. package/dist/catalog/visibility.js +19 -1
  30. package/dist/client.d.ts +121 -9
  31. package/dist/client.js +53 -14
  32. package/dist/content/assets.d.ts +285 -0
  33. package/dist/content/assets.js +181 -0
  34. package/dist/content/forms.d.ts +332 -1
  35. package/dist/content/forms.js +140 -4
  36. package/dist/content/items.d.ts +292 -0
  37. package/dist/content/items.js +170 -0
  38. package/dist/content/menus.d.ts +254 -0
  39. package/dist/content/menus.js +70 -0
  40. package/dist/content/strings.d.ts +137 -0
  41. package/dist/content/strings.js +82 -0
  42. package/dist/content/types.d.ts +282 -0
  43. package/dist/content/types.js +100 -0
  44. package/dist/customers/age-verification.d.ts +66 -0
  45. package/dist/customers/age-verification.js +79 -0
  46. package/dist/customers/credit.d.ts +263 -0
  47. package/dist/customers/credit.js +244 -0
  48. package/dist/customers/delivery-preferences.d.ts +120 -0
  49. package/dist/customers/delivery-preferences.js +97 -0
  50. package/dist/customers/delivery-terms.d.ts +44 -0
  51. package/dist/customers/delivery-terms.js +32 -0
  52. package/dist/customers/groups.d.ts +207 -0
  53. package/dist/customers/groups.js +438 -0
  54. package/dist/customers/index.d.ts +462 -37
  55. package/dist/customers/index.js +317 -40
  56. package/dist/customers/invitation-status.d.ts +57 -0
  57. package/dist/customers/invitation-status.js +21 -0
  58. package/dist/customers/notes.d.ts +67 -0
  59. package/dist/customers/notes.js +51 -0
  60. package/dist/customers/notification-recipients.d.ts +97 -0
  61. package/dist/customers/notification-recipients.js +84 -0
  62. package/dist/customers/saved-lists.d.ts +42 -0
  63. package/dist/customers/saved-lists.js +61 -0
  64. package/dist/customers/vat.d.ts +83 -0
  65. package/dist/customers/vat.js +46 -0
  66. package/dist/customers/wire.d.ts +20 -0
  67. package/dist/customers/wire.js +35 -0
  68. package/dist/documents/ar.d.ts +307 -0
  69. package/dist/documents/ar.js +254 -0
  70. package/dist/documents/emails.d.ts +150 -0
  71. package/dist/documents/emails.js +220 -0
  72. package/dist/documents/index.d.ts +744 -21
  73. package/dist/documents/index.js +438 -24
  74. package/dist/documents/pdf.d.ts +2 -0
  75. package/dist/documents/pdf.js +11 -0
  76. package/dist/fulfillments/create.d.ts +167 -0
  77. package/dist/fulfillments/create.js +216 -0
  78. package/dist/fulfillments/index.d.ts +163 -11
  79. package/dist/fulfillments/index.js +135 -6
  80. package/dist/fulfillments/payment-policy.d.ts +64 -0
  81. package/dist/fulfillments/payment-policy.js +140 -0
  82. package/dist/fulfillments/warehouse.d.ts +724 -0
  83. package/dist/fulfillments/warehouse.js +914 -0
  84. package/dist/geo/index.d.ts +119 -0
  85. package/dist/geo/index.js +107 -0
  86. package/dist/index.d.ts +147 -39
  87. package/dist/index.js +51 -12
  88. package/dist/integrations/afas-actions.d.ts +234 -0
  89. package/dist/integrations/afas-actions.js +310 -0
  90. package/dist/integrations/afas-types.d.ts +483 -0
  91. package/dist/integrations/afas-types.js +5 -0
  92. package/dist/integrations/afas.d.ts +234 -0
  93. package/dist/integrations/afas.js +290 -0
  94. package/dist/integrations/connections.d.ts +103 -0
  95. package/dist/integrations/connections.js +55 -0
  96. package/dist/integrations/esp.d.ts +313 -0
  97. package/dist/integrations/esp.js +169 -0
  98. package/dist/integrations/exact-online-types.d.ts +965 -0
  99. package/dist/integrations/exact-online-types.js +6 -0
  100. package/dist/integrations/exact-online.d.ts +784 -0
  101. package/dist/integrations/exact-online.js +1089 -0
  102. package/dist/integrations/index.d.ts +44 -3
  103. package/dist/integrations/index.js +23 -3
  104. package/dist/integrations/pipeline-discoveries.d.ts +65 -0
  105. package/dist/integrations/pipeline-discoveries.js +65 -0
  106. package/dist/integrations/pipeline-keys.d.ts +13 -0
  107. package/dist/integrations/pipeline-keys.js +22 -0
  108. package/dist/integrations/pipeline-runs.d.ts +119 -0
  109. package/dist/integrations/pipeline-runs.js +87 -0
  110. package/dist/integrations/pipelines.d.ts +87 -15
  111. package/dist/integrations/pipelines.js +41 -22
  112. package/dist/integrations/price-import.d.ts +223 -0
  113. package/dist/integrations/price-import.js +124 -0
  114. package/dist/integrations/types.d.ts +367 -3
  115. package/dist/integrations/types.js +4 -3
  116. package/dist/locations/index.d.ts +66 -0
  117. package/dist/locations/index.js +31 -0
  118. package/dist/meta/index.d.ts +172 -0
  119. package/dist/metafields/index.d.ts +8 -1
  120. package/dist/metafields/index.js +10 -0
  121. package/dist/orders/cancel-with-money.d.ts +237 -0
  122. package/dist/orders/cancel-with-money.js +155 -0
  123. package/dist/orders/commit-edit.d.ts +23 -1
  124. package/dist/orders/commit-edit.js +19 -2
  125. package/dist/orders/deposit-policy.d.ts +3 -1
  126. package/dist/orders/drafts.d.ts +800 -0
  127. package/dist/orders/drafts.js +771 -0
  128. package/dist/orders/fields.d.ts +245 -0
  129. package/dist/orders/fields.js +188 -0
  130. package/dist/orders/get.d.ts +29 -19
  131. package/dist/orders/get.js +17 -8
  132. package/dist/orders/index.d.ts +66 -15
  133. package/dist/orders/index.js +25 -2
  134. package/dist/orders/lifecycle.d.ts +128 -0
  135. package/dist/orders/lifecycle.js +158 -0
  136. package/dist/orders/line-price-preview.d.ts +7 -2
  137. package/dist/orders/list.d.ts +243 -0
  138. package/dist/orders/list.js +487 -0
  139. package/dist/orders/manual-discounts.d.ts +13 -5
  140. package/dist/orders/manual-pricing.d.ts +5 -0
  141. package/dist/orders/money-view.d.ts +149 -0
  142. package/dist/orders/money-view.js +99 -0
  143. package/dist/orders/order-entry.d.ts +20 -7
  144. package/dist/orders/plan-edit.d.ts +34 -2
  145. package/dist/orders/plan-edit.js +112 -11
  146. package/dist/orders/settings.d.ts +201 -0
  147. package/dist/orders/settings.js +325 -0
  148. package/dist/orders/status.d.ts +159 -13
  149. package/dist/orders/status.js +21 -0
  150. package/dist/orders/surcharges.d.ts +20 -1
  151. package/dist/orders/surcharges.js +37 -11
  152. package/dist/payments/account-credit.d.ts +46 -0
  153. package/dist/payments/account-credit.js +42 -0
  154. package/dist/payments/ar.d.ts +292 -0
  155. package/dist/payments/ar.js +223 -0
  156. package/dist/payments/connected-account.d.ts +47 -0
  157. package/dist/payments/connected-account.js +61 -0
  158. package/dist/payments/credit-noted-fields.d.ts +19 -0
  159. package/dist/payments/credit-noted-fields.js +69 -0
  160. package/dist/payments/customer-consent.d.ts +30 -0
  161. package/dist/payments/customer-consent.js +49 -0
  162. package/dist/payments/index.d.ts +340 -19
  163. package/dist/payments/index.js +151 -1
  164. package/dist/payments/methods.d.ts +303 -8
  165. package/dist/payments/methods.js +337 -7
  166. package/dist/payments/mollie-methods.d.ts +159 -0
  167. package/dist/payments/mollie-methods.js +141 -0
  168. package/dist/payments/payment-links.d.ts +180 -0
  169. package/dist/payments/payment-links.js +97 -0
  170. package/dist/payments/provider-keys.d.ts +150 -0
  171. package/dist/payments/provider-keys.js +118 -0
  172. package/dist/payments/providers.d.ts +86 -11
  173. package/dist/payments/providers.js +29 -0
  174. package/dist/payments/requests.d.ts +147 -0
  175. package/dist/payments/requests.js +93 -0
  176. package/dist/payments/store-credit-fields.d.ts +15 -0
  177. package/dist/payments/store-credit-fields.js +51 -0
  178. package/dist/pickups/index.d.ts +106 -0
  179. package/dist/pickups/index.js +108 -0
  180. package/dist/platform/channels.d.ts +132 -0
  181. package/dist/platform/channels.js +128 -0
  182. package/dist/platform/email-gateways.d.ts +165 -0
  183. package/dist/platform/email-gateways.js +78 -0
  184. package/dist/platform/geo.d.ts +123 -0
  185. package/dist/platform/geo.js +144 -0
  186. package/dist/platform/tax.d.ts +162 -0
  187. package/dist/platform/tax.js +169 -0
  188. package/dist/pos/anomalies.d.ts +158 -0
  189. package/dist/pos/anomalies.js +64 -0
  190. package/dist/pos/assisted-selling.d.ts +79 -0
  191. package/dist/pos/assisted-selling.js +38 -0
  192. package/dist/pos/exchanges.d.ts +108 -0
  193. package/dist/pos/exchanges.js +22 -0
  194. package/dist/pos/gift-cards.d.ts +135 -0
  195. package/dist/pos/gift-cards.js +47 -0
  196. package/dist/pos/index.d.ts +2370 -58
  197. package/dist/pos/index.js +854 -7
  198. package/dist/pos/no-receipt.d.ts +94 -0
  199. package/dist/pos/no-receipt.js +25 -0
  200. package/dist/pos/offline-sales.d.ts +228 -0
  201. package/dist/pos/offline-sales.js +170 -0
  202. package/dist/pos/pay-by-link.d.ts +143 -0
  203. package/dist/pos/pay-by-link.js +57 -0
  204. package/dist/pos/quick-keys.d.ts +103 -0
  205. package/dist/pos/quick-keys.js +45 -0
  206. package/dist/pos/reports.d.ts +360 -0
  207. package/dist/pos/reports.js +62 -0
  208. package/dist/pos/returns.d.ts +244 -0
  209. package/dist/pos/returns.js +83 -0
  210. package/dist/pricing/bulk-coupons.d.ts +139 -0
  211. package/dist/pricing/bulk-coupons.js +112 -0
  212. package/dist/pricing/index.d.ts +174 -4
  213. package/dist/pricing/index.js +174 -1
  214. package/dist/pricing/price-lists.d.ts +606 -0
  215. package/dist/pricing/price-lists.js +600 -0
  216. package/dist/purchasing/alerts.d.ts +104 -0
  217. package/dist/purchasing/alerts.js +88 -0
  218. package/dist/purchasing/backorders.d.ts +61 -0
  219. package/dist/purchasing/backorders.js +92 -0
  220. package/dist/purchasing/cost.d.ts +110 -0
  221. package/dist/purchasing/cost.js +86 -0
  222. package/dist/purchasing/index.d.ts +54 -0
  223. package/dist/purchasing/index.js +24 -0
  224. package/dist/purchasing/links.d.ts +263 -0
  225. package/dist/purchasing/links.js +192 -0
  226. package/dist/purchasing/purchase-orders.d.ts +551 -0
  227. package/dist/purchasing/purchase-orders.js +491 -0
  228. package/dist/purchasing/receipts.d.ts +396 -0
  229. package/dist/purchasing/receipts.js +287 -0
  230. package/dist/purchasing/replenishment.d.ts +281 -0
  231. package/dist/purchasing/replenishment.js +240 -0
  232. package/dist/purchasing/returns.d.ts +273 -0
  233. package/dist/purchasing/returns.js +229 -0
  234. package/dist/purchasing/settings.d.ts +152 -0
  235. package/dist/purchasing/settings.js +181 -0
  236. package/dist/purchasing/suppliers.d.ts +476 -0
  237. package/dist/purchasing/suppliers.js +438 -0
  238. package/dist/quotes/index.d.ts +518 -0
  239. package/dist/quotes/index.js +439 -0
  240. package/dist/reports/index.d.ts +71 -8
  241. package/dist/reports/index.js +74 -11
  242. package/dist/returns/index.d.ts +675 -21
  243. package/dist/returns/index.js +756 -11
  244. package/dist/search/index.d.ts +76 -1
  245. package/dist/search/index.js +63 -0
  246. package/dist/seo/config.d.ts +128 -0
  247. package/dist/seo/config.js +95 -0
  248. package/dist/seo/redirects.d.ts +125 -0
  249. package/dist/seo/redirects.js +60 -1
  250. package/dist/seo/settings.d.ts +147 -0
  251. package/dist/seo/settings.js +209 -0
  252. package/dist/shipping/definitions.d.ts +29 -0
  253. package/dist/shipping/definitions.js +47 -0
  254. package/dist/shipping/fulfillment-profiles.d.ts +174 -0
  255. package/dist/shipping/fulfillment-profiles.js +104 -0
  256. package/dist/shipping/hendriks.d.ts +97 -0
  257. package/dist/shipping/hendriks.js +50 -0
  258. package/dist/shipping/index.d.ts +54 -0
  259. package/dist/shipping/index.js +27 -0
  260. package/dist/shipping/methods.d.ts +205 -0
  261. package/dist/shipping/methods.js +240 -0
  262. package/dist/shipping/myparcel.d.ts +668 -0
  263. package/dist/shipping/myparcel.js +466 -0
  264. package/dist/shipping/parcel-count-suggestion.d.ts +2 -0
  265. package/dist/shipping/parcel-rule.d.ts +6 -5
  266. package/dist/shipping/parcel-rule.js +21 -23
  267. package/dist/shipping/rate-tables.d.ts +324 -0
  268. package/dist/shipping/rate-tables.js +390 -0
  269. package/dist/shipping/ship-to-countries.d.ts +75 -0
  270. package/dist/shipping/ship-to-countries.js +47 -0
  271. package/dist/stock/by-location.d.ts +86 -0
  272. package/dist/stock/by-location.js +94 -0
  273. package/dist/stock/index.d.ts +18 -4
  274. package/dist/stock/index.js +7 -0
  275. package/dist/stock/locations.d.ts +144 -0
  276. package/dist/stock/locations.js +168 -0
  277. package/dist/stock/settings.d.ts +106 -0
  278. package/dist/stock/settings.js +103 -0
  279. package/dist/stock/transfers.d.ts +386 -52
  280. package/dist/stock/transfers.js +222 -17
  281. package/dist/stored-value/index.d.ts +312 -11
  282. package/dist/stored-value/index.js +223 -4
  283. package/dist/subscriptions/index.d.ts +682 -0
  284. package/dist/subscriptions/index.js +815 -0
  285. package/dist/tax/display-policy.d.ts +105 -0
  286. package/dist/tax/display-policy.js +84 -0
  287. package/dist/tax/index.d.ts +79 -1
  288. package/dist/tax/index.js +52 -0
  289. package/dist/tenant/email-style.d.ts +102 -0
  290. package/dist/tenant/email-style.js +72 -0
  291. package/dist/tenant/email-templates.d.ts +287 -0
  292. package/dist/tenant/email-templates.js +271 -0
  293. package/dist/tenant/notifications.d.ts +23 -17
  294. package/dist/tenant/settings-sources.d.ts +1 -1
  295. package/dist/tenant/time-zone.d.ts +17 -0
  296. package/dist/tenant/time-zone.js +11 -0
  297. package/dist/types.d.ts +50 -3
  298. package/dist/users/index.d.ts +3 -0
  299. package/dist/users/index.js +2 -0
  300. package/dist/users/warehouses.d.ts +50 -0
  301. package/dist/users/warehouses.js +51 -0
  302. package/package.json +2 -2
@@ -1,4 +1,9 @@
1
- import { errorFromErrorResult, isErrorResult, NotFoundError, ValidationError, } from '@sixtyninecommerce/core';
1
+ import { errorForStatus, errorFromErrorResult, errorFromGraphQLErrors, isErrorResult, NotFoundError, ValidationError, } from '@sixtyninecommerce/core';
2
+ import { customerAgreedVariable, statedCustomerAgreed } from '../payments/customer-consent.js';
3
+ import { storeCreditAware } from '../payments/store-credit-fields.js';
4
+ import { createFulfillmentCreateMethods } from './create.js';
5
+ import { createFulfillmentPaymentPolicyModule, } from './payment-policy.js';
6
+ import { createWarehouseFulfillmentsModule, } from './warehouse.js';
2
7
  /** The longest override reason the engine stores. */
3
8
  export const FULFILLMENT_COVERAGE_REASON_MAX_LENGTH = 500;
4
9
  /** Every field of `OrderOverpaymentOption`. */
@@ -6,6 +11,7 @@ const OVERPAYMENT_OPTION_FIELDS = /* GraphQL */ `
6
11
  available
7
12
  code
8
13
  message
14
+ book
9
15
  `;
10
16
  /**
11
17
  * Its own document, like every call here: on an engine without the query this call alone fails
@@ -48,10 +54,39 @@ export const CANCEL_FULFILLMENT_MUTATION = /* GraphQL */ `
48
54
  amount
49
55
  currencyCode
50
56
  choice
57
+ book
51
58
  }
52
59
  }
53
60
  }
54
61
  `;
62
+ /**
63
+ * The refusal member is selected for its facts: `message` is core's per-code template ("Cannot
64
+ * transition Fulfillment from X to Y"), and the refusing step's reason is `transitionError` alone.
65
+ */
66
+ export const TRANSITION_FULFILLMENT_MUTATION = /* GraphQL */ `
67
+ mutation TransitionFulfillment($id: ID!, $state: String!) {
68
+ transitionFulfillmentToState(id: $id, state: $state) {
69
+ __typename
70
+ ... on Fulfillment {
71
+ id
72
+ state
73
+ nextStates
74
+ }
75
+ ... on FulfillmentStateTransitionError {
76
+ errorCode
77
+ message
78
+ fromState
79
+ toState
80
+ transitionError
81
+ }
82
+ }
83
+ }
84
+ `;
85
+ export const RESEND_FULFILLMENT_LABEL_HANDOFF_MUTATION = /* GraphQL */ `
86
+ mutation ResendFulfillmentLabelHandoff($fulfillmentId: ID!) {
87
+ resendFulfillmentLabelHandoff(fulfillmentId: $fulfillmentId)
88
+ }
89
+ `;
55
90
  /** Every field of `OrderFulfillmentCoverageOverride`. */
56
91
  const COVERAGE_OVERRIDE_FIELDS = /* GraphQL */ `
57
92
  id
@@ -154,15 +189,27 @@ function assertCancelRequest(fulfillmentId, input) {
154
189
  if (!OVERPAYMENT_CHOICES.has(entry.choice)) {
155
190
  throw invalidCancel(`overpayment[${String(index)}].choice`, `The choice for order ${orderId} must be REFUND or ACCOUNT_CREDIT; got ${JSON.stringify(entry.choice)}.`);
156
191
  }
192
+ if (entry.customerAgreed != null &&
193
+ customerAgreedVariable(entry.customerAgreed) === undefined) {
194
+ throw invalidCancel(`overpayment[${String(index)}].customerAgreed`, `The customer's answer for order ${orderId} must be true or false; got ${JSON.stringify(entry.customerAgreed)}.`);
195
+ }
157
196
  if (seen.has(orderId)) {
158
197
  throw invalidCancel(`overpayment[${String(index)}].orderId`, `Order ${orderId} is named twice: give one choice per order.`);
159
198
  }
160
199
  seen.add(orderId);
161
200
  }
162
201
  }
163
- /** An option as the SDK types it: `code` and `message` are null when it is open. */
202
+ /**
203
+ * An option as the SDK types it: `code` and `message` are null when it is open; `book` (the
204
+ * account credit's, incentives sprint 8) null on the refund and from an engine before it.
205
+ */
164
206
  function toOption(raw) {
165
- return { available: raw.available, code: raw.code ?? null, message: raw.message ?? null };
207
+ return {
208
+ available: raw.available,
209
+ code: raw.code ?? null,
210
+ message: raw.message ?? null,
211
+ book: raw.book ?? null,
212
+ };
166
213
  }
167
214
  export const REPORT_APP_FULFILLMENT_MUTATION = /* GraphQL */ `
168
215
  mutation ReportAppFulfillment(
@@ -358,8 +405,55 @@ function assertLabelRequest(fulfillmentId, format) {
358
405
  throw invalidLabelRequest('format', `format must be 'A4' or 'A6', or left out to label every parcel still missing one; got ${JSON.stringify(format)}.`);
359
406
  }
360
407
  }
408
+ function invalidTransition(field, message) {
409
+ return new ValidationError({
410
+ code: 'FULFILLMENT_TRANSITION_INVALID',
411
+ message,
412
+ status: 400,
413
+ service: 'vendure',
414
+ details: [{ field, code: 'FULFILLMENT_TRANSITION_INVALID', message }],
415
+ });
416
+ }
417
+ /** The `[CODE]` a step of the fulfillment process prefixes its refusal text with. */
418
+ const STEP_CODE = /^\s*\[([A-Z][A-Z0-9_]*)\]\s*/;
419
+ /**
420
+ * A refused move as the coded error it is. Core carries a step's refusal only as text, so the
421
+ * step's own code is read off its `[CODE]` prefix and classed through the GraphQL dialect, as the
422
+ * warehouse API's refusals of the same codes are (`warehouseRefusalError`): one code, one class,
423
+ * whichever door answered it.
424
+ */
425
+ export function fulfillmentTransitionRefusal(result) {
426
+ const text = typeof result.transitionError === 'string' ? result.transitionError.trim() : '';
427
+ const facts = {
428
+ errorCode: result.errorCode,
429
+ fromState: result.fromState ?? '',
430
+ toState: result.toState ?? '',
431
+ transitionError: text,
432
+ };
433
+ const step = STEP_CODE.exec(text);
434
+ const sentence = step ? text.slice(step[0].length).trim() : text;
435
+ // Core's `message` is a per-code template, untranslated on some engines
436
+ // ("errorResult.FULFILLMENT_STATE_TRANSITION_ERROR"): said only when the move is unknown too.
437
+ const message = sentence ||
438
+ (facts.fromState && facts.toState
439
+ ? `The fulfillment cannot move from ${facts.fromState} to ${facts.toState}.`
440
+ : result.message);
441
+ if (step?.[1]) {
442
+ return errorFromGraphQLErrors([{ message, extensions: { ...facts, code: step[1] } }]);
443
+ }
444
+ const base = errorFromErrorResult({ errorCode: result.errorCode, message });
445
+ return errorForStatus(base.status, {
446
+ code: base.code,
447
+ message,
448
+ service: 'vendure',
449
+ extensions: { ...facts },
450
+ });
451
+ }
361
452
  export function createFulfillmentsModule(transport) {
362
453
  return {
454
+ ...createFulfillmentCreateMethods(transport),
455
+ paymentPolicy: createFulfillmentPaymentPolicyModule(transport),
456
+ warehouse: createWarehouseFulfillmentsModule(transport),
363
457
  async parcelsOfOrder(orderId, options) {
364
458
  const data = await transport.graphql({ api: 'admin', query: ORDER_FULFILLMENT_PARCELS_QUERY, variables: { id: orderId } }, options);
365
459
  if (!data.order)
@@ -442,7 +536,7 @@ export function createFulfillmentsModule(transport) {
442
536
  if (typeof fulfillmentId !== 'string' || fulfillmentId.trim() === '') {
443
537
  throw invalidCancel('fulfillmentId', 'A fulfillment id is required.');
444
538
  }
445
- const data = await transport.graphql({ api: 'admin', query: FULFILLMENT_CANCEL_PREVIEW_QUERY, variables: { fulfillmentId } }, options);
539
+ const data = await storeCreditAware(transport).graphql({ api: 'admin', query: FULFILLMENT_CANCEL_PREVIEW_QUERY, variables: { fulfillmentId } }, options);
446
540
  const preview = data.fulfillmentCancelPreview;
447
541
  return {
448
542
  fulfillmentId: preview.fulfillmentId,
@@ -459,14 +553,21 @@ export function createFulfillmentsModule(transport) {
459
553
  async cancel(fulfillmentId, input = {}, options) {
460
554
  assertCancelRequest(fulfillmentId, input);
461
555
  const overpayment = input.overpayment ?? [];
462
- const data = await transport.graphql({
556
+ const data = await storeCreditAware(transport).graphql({
463
557
  api: 'admin',
464
558
  query: CANCEL_FULFILLMENT_MUTATION,
465
559
  // A variable, not a header: the Admin API takes the key as an argument.
466
560
  variables: {
467
561
  fulfillmentId,
468
562
  ...(overpayment.length > 0
469
- ? { overpayment: overpayment.map(({ orderId, choice }) => ({ orderId, choice })) }
563
+ ? {
564
+ overpayment: overpayment.map(({ orderId, choice, customerAgreed }) => ({
565
+ orderId,
566
+ choice,
567
+ // Named only when stated: an engine before the field takes the rest.
568
+ ...statedCustomerAgreed(customerAgreed),
569
+ })),
570
+ }
470
571
  : {}),
471
572
  ...(options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {}),
472
573
  },
@@ -480,6 +581,7 @@ export function createFulfillmentsModule(transport) {
480
581
  amount: entry.amount,
481
582
  currencyCode: entry.currencyCode,
482
583
  choice: entry.choice,
584
+ book: entry.book ?? null,
483
585
  })),
484
586
  };
485
587
  },
@@ -515,6 +617,33 @@ export function createFulfillmentsModule(transport) {
515
617
  }, options);
516
618
  return toCoverageOverride(data.allowUncoveredFulfillment);
517
619
  },
620
+ async transition(fulfillmentId, state, options) {
621
+ if (typeof fulfillmentId !== 'string' || fulfillmentId.trim() === '') {
622
+ throw invalidTransition('fulfillmentId', 'A fulfillment id is required.');
623
+ }
624
+ if (typeof state !== 'string' || state.trim() === '') {
625
+ throw invalidTransition('state', 'Name the state to move the fulfillment to.');
626
+ }
627
+ const data = await transport.graphql({
628
+ api: 'admin',
629
+ query: TRANSITION_FULFILLMENT_MUTATION,
630
+ variables: { id: fulfillmentId, state },
631
+ }, options);
632
+ const result = data.transitionFulfillmentToState;
633
+ if (isErrorResult(result))
634
+ throw fulfillmentTransitionRefusal(result);
635
+ const moved = result;
636
+ return { id: moved.id, state: moved.state, nextStates: [...(moved.nextStates ?? [])] };
637
+ },
638
+ async resendLabelHandoff(fulfillmentId, options) {
639
+ assertLabelRequest(fulfillmentId, undefined);
640
+ const data = await transport.graphql({
641
+ api: 'admin',
642
+ query: RESEND_FULFILLMENT_LABEL_HANDOFF_MUTATION,
643
+ variables: { fulfillmentId },
644
+ }, options);
645
+ return data.resendFulfillmentLabelHandoff;
646
+ },
518
647
  async reportAppFulfillment(fulfillmentId, input, options) {
519
648
  const data = await transport.graphql({
520
649
  api: 'admin',
@@ -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;
@@ -0,0 +1,140 @@
1
+ import { errorFromErrorResult, isErrorResult, ValidationError, } from '@sixtyninecommerce/core';
2
+ // The bounds of the meta catalog's `fulfillment_payment_policy` schema
3
+ // (`packages/shared/src/meta-catalog/settings-schemas.ts`), which the spec reads
4
+ // back from that schema, and of the engine's write validator
5
+ // (`validateFulfillmentPaymentPolicyValue`), which refuses the same values.
6
+ /** The most payment method codes `exemptMethodCodes` may name. */
7
+ export const FULFILLMENT_PAYMENT_POLICY_EXEMPT_METHODS_MAX = 50;
8
+ /** The longest payment method code the list accepts (`PaymentMethod.code` is a varchar(255)). */
9
+ export const FULFILLMENT_PAYMENT_POLICY_METHOD_CODE_MAX_LENGTH = 255;
10
+ /** The policy of a store that never set one, and of a column that cannot be read: off. */
11
+ export const DEFAULT_FULFILLMENT_PAYMENT_POLICY = Object.freeze({
12
+ requireFullPayment: false,
13
+ exemptMethodCodes: [],
14
+ });
15
+ const POLICY_FIELDS = /* GraphQL */ `
16
+ id
17
+ customFields {
18
+ fulfillmentPaymentPolicy
19
+ }
20
+ `;
21
+ export const FULFILLMENT_PAYMENT_POLICY_QUERY = /* GraphQL */ `
22
+ query FulfillmentPaymentPolicy {
23
+ activeChannel { ${POLICY_FIELDS} }
24
+ }
25
+ `;
26
+ export const SET_FULFILLMENT_PAYMENT_POLICY_MUTATION = /* GraphQL */ `
27
+ mutation SetFulfillmentPaymentPolicy($input: UpdateChannelInput!) {
28
+ updateChannel(input: $input) {
29
+ ... on Channel { ${POLICY_FIELDS} }
30
+ ... on ErrorResult { errorCode message }
31
+ }
32
+ }
33
+ `;
34
+ function isRecord(value) {
35
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
36
+ }
37
+ /** A payment method code as the engine compares it (`normalizeMethodCode`). */
38
+ export function normalizeFulfillmentPolicyMethodCode(code) {
39
+ return code.trim().toLowerCase();
40
+ }
41
+ /** The column, read as the engine reads it: anything unreadable is OFF. */
42
+ function readFulfillmentPaymentPolicy(raw) {
43
+ let parsed = raw;
44
+ if (typeof raw === 'string') {
45
+ try {
46
+ parsed = JSON.parse(raw);
47
+ }
48
+ catch {
49
+ parsed = null;
50
+ }
51
+ }
52
+ if (!isRecord(parsed))
53
+ return { requireFullPayment: false, exemptMethodCodes: [] };
54
+ const codes = Array.isArray(parsed.exemptMethodCodes)
55
+ ? [
56
+ ...new Set(parsed.exemptMethodCodes
57
+ .filter((code) => typeof code === 'string' && code.trim() !== '')
58
+ .map(normalizeFulfillmentPolicyMethodCode)),
59
+ ].slice(0, FULFILLMENT_PAYMENT_POLICY_EXEMPT_METHODS_MAX)
60
+ : [];
61
+ return { requireFullPayment: parsed.requireFullPayment === true, exemptMethodCodes: codes };
62
+ }
63
+ /** Every way `policy` breaks the schema, one entry per field. */
64
+ function problemsOf(policy) {
65
+ const problems = [];
66
+ const add = (field, message) => problems.push({ field, code: 'FULFILLMENT_PAYMENT_POLICY_INVALID', message });
67
+ if (!isRecord(policy)) {
68
+ add('policy', 'Pass the whole policy as an object: read it with get(), change it, send it back.');
69
+ return problems;
70
+ }
71
+ if (typeof policy.requireFullPayment !== 'boolean') {
72
+ add('requireFullPayment', 'requireFullPayment must be true or false.');
73
+ }
74
+ const codes = policy.exemptMethodCodes;
75
+ if (!Array.isArray(codes)) {
76
+ add('exemptMethodCodes', 'exemptMethodCodes must be a list of payment method codes.');
77
+ }
78
+ else if (codes.some((code) => typeof code !== 'string' || code.trim() === '')) {
79
+ add('exemptMethodCodes', 'exemptMethodCodes may hold only non-blank payment method codes.');
80
+ }
81
+ else if (codes.some((code) => code.trim().length > FULFILLMENT_PAYMENT_POLICY_METHOD_CODE_MAX_LENGTH)) {
82
+ add('exemptMethodCodes', `A payment method code is at most ${String(FULFILLMENT_PAYMENT_POLICY_METHOD_CODE_MAX_LENGTH)} characters.`);
83
+ }
84
+ else if (new Set(codes.map((code) => normalizeFulfillmentPolicyMethodCode(code))).size !==
85
+ codes.length) {
86
+ add('exemptMethodCodes', 'exemptMethodCodes names a payment method code more than once (codes are compared ignoring case).');
87
+ }
88
+ else if (codes.length > FULFILLMENT_PAYMENT_POLICY_EXEMPT_METHODS_MAX) {
89
+ add('exemptMethodCodes', `exemptMethodCodes may name at most ${String(FULFILLMENT_PAYMENT_POLICY_EXEMPT_METHODS_MAX)} payment methods.`);
90
+ }
91
+ return problems;
92
+ }
93
+ /** Exactly the schema's fields, in its order, codes trimmed: what the column stores. */
94
+ function storedOf(policy) {
95
+ return {
96
+ requireFullPayment: policy.requireFullPayment,
97
+ exemptMethodCodes: policy.exemptMethodCodes.map((code) => code.trim()),
98
+ };
99
+ }
100
+ export function createFulfillmentPaymentPolicyModule(transport) {
101
+ const read = async (options) => {
102
+ const data = await transport.graphql({ api: 'admin', query: FULFILLMENT_PAYMENT_POLICY_QUERY }, options);
103
+ return data.activeChannel;
104
+ };
105
+ return {
106
+ async get(options) {
107
+ const channel = await read(options);
108
+ return readFulfillmentPaymentPolicy(channel.customFields?.fulfillmentPaymentPolicy ?? null);
109
+ },
110
+ async set(policy, options) {
111
+ const problems = problemsOf(policy);
112
+ if (problems.length > 0) {
113
+ throw new ValidationError({
114
+ code: 'FULFILLMENT_PAYMENT_POLICY_INVALID',
115
+ message: problems.map((problem) => problem.message).join(' '),
116
+ status: 400,
117
+ service: 'vendure',
118
+ details: problems,
119
+ });
120
+ }
121
+ // `updateChannel` needs the id, and the active channel is the one the client is scoped
122
+ // to: read it with the SAME call options, so a per-call tenant writes its own channel.
123
+ const { id } = await read(options);
124
+ const data = await transport.graphql({
125
+ api: 'admin',
126
+ query: SET_FULFILLMENT_PAYMENT_POLICY_MUTATION,
127
+ variables: {
128
+ // The column is `text` holding JSON, so it is sent as a string.
129
+ input: {
130
+ id,
131
+ customFields: { fulfillmentPaymentPolicy: JSON.stringify(storedOf(policy)) },
132
+ },
133
+ },
134
+ }, options);
135
+ if (isErrorResult(data.updateChannel))
136
+ throw errorFromErrorResult(data.updateChannel);
137
+ return readFulfillmentPaymentPolicy(data.updateChannel.customFields?.fulfillmentPaymentPolicy ?? null);
138
+ },
139
+ };
140
+ }