@aglyn/plugins-commerce 1.0.0-beta.231 → 1.0.0-beta.233

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 (266) hide show
  1. package/package.json +13 -13
  2. package/src/lib/components/cart-extras.d.ts +6 -0
  3. package/src/lib/components/cart-extras.js +4 -1
  4. package/src/lib/components/cart-extras.js.map +1 -1
  5. package/src/lib/components/cart-fulfillment.d.ts +117 -0
  6. package/src/lib/components/cart-fulfillment.js +367 -0
  7. package/src/lib/components/cart-fulfillment.js.map +1 -0
  8. package/src/lib/components/cart.js +52 -10
  9. package/src/lib/components/cart.js.map +1 -1
  10. package/src/lib/components/commerce-console-page.js +42 -1
  11. package/src/lib/components/commerce-console-page.js.map +1 -1
  12. package/src/lib/components/console/catalog-organization-card.component.js +1 -0
  13. package/src/lib/components/console/catalog-organization-card.component.js.map +1 -1
  14. package/src/lib/components/console/host-orders-card.component.js +42 -11
  15. package/src/lib/components/console/host-orders-card.component.js.map +1 -1
  16. package/src/lib/components/console/local-delivery-settings-card.component.d.ts +37 -0
  17. package/src/lib/components/console/local-delivery-settings-card.component.js +542 -0
  18. package/src/lib/components/console/local-delivery-settings-card.component.js.map +1 -0
  19. package/src/lib/components/console/locations-card.component.js +177 -3
  20. package/src/lib/components/console/locations-card.component.js.map +1 -1
  21. package/src/lib/components/console/order-detail-dialog.component.js +10 -0
  22. package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
  23. package/src/lib/components/console/order-local-fulfillment-panel.component.d.ts +44 -0
  24. package/src/lib/components/console/order-local-fulfillment-panel.component.js +265 -0
  25. package/src/lib/components/console/order-local-fulfillment-panel.component.js.map +1 -0
  26. package/src/lib/components/console/order-offline-notice.component.d.ts +12 -0
  27. package/src/lib/components/console/order-offline-notice.component.js +53 -0
  28. package/src/lib/components/console/order-offline-notice.component.js.map +1 -0
  29. package/src/lib/components/console/pickup-delivery-queue-card.component.d.ts +35 -0
  30. package/src/lib/components/console/pickup-delivery-queue-card.component.js +222 -0
  31. package/src/lib/components/console/pickup-delivery-queue-card.component.js.map +1 -0
  32. package/src/lib/components/console/pos/pos-api.d.ts +24 -1
  33. package/src/lib/components/console/pos/pos-api.js +13 -0
  34. package/src/lib/components/console/pos/pos-api.js.map +1 -1
  35. package/src/lib/components/console/pos/pos-item-dialog.component.d.ts +12 -0
  36. package/src/lib/components/console/pos/pos-item-dialog.component.js +10 -8
  37. package/src/lib/components/console/pos/pos-item-dialog.component.js.map +1 -1
  38. package/src/lib/components/console/pos/pos-kiosk-queue.component.d.ts +22 -0
  39. package/src/lib/components/console/pos/pos-kiosk-queue.component.js +168 -0
  40. package/src/lib/components/console/pos/pos-kiosk-queue.component.js.map +1 -0
  41. package/src/lib/components/console/pos/pos-tender-dialogs.component.d.ts +18 -0
  42. package/src/lib/components/console/pos/pos-tender-dialogs.component.js +116 -1
  43. package/src/lib/components/console/pos/pos-tender-dialogs.component.js.map +1 -1
  44. package/src/lib/components/console/pos/pos-tender-panel.component.d.ts +8 -0
  45. package/src/lib/components/console/pos/pos-tender-panel.component.js +77 -18
  46. package/src/lib/components/console/pos/pos-tender-panel.component.js.map +1 -1
  47. package/src/lib/components/console/pos/use-pos-display.d.ts +5 -2
  48. package/src/lib/components/console/pos/use-pos-display.js +3 -2
  49. package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
  50. package/src/lib/components/console/pos-devices-card.component.js +2 -2
  51. package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
  52. package/src/lib/components/console/pos-display/pairing-screen.d.ts +5 -2
  53. package/src/lib/components/console/pos-display/pairing-screen.js +7 -5
  54. package/src/lib/components/console/pos-display/pairing-screen.js.map +1 -1
  55. package/src/lib/components/console/pos-display/pos-display-api.d.ts +7 -1
  56. package/src/lib/components/console/pos-display/pos-display-api.js +7 -2
  57. package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
  58. package/src/lib/components/console/pos-kiosk/kiosk-checkout.d.ts +41 -0
  59. package/src/lib/components/console/pos-kiosk/kiosk-checkout.js +275 -0
  60. package/src/lib/components/console/pos-kiosk/kiosk-checkout.js.map +1 -0
  61. package/src/lib/components/console/pos-kiosk/kiosk-menu.d.ts +32 -0
  62. package/src/lib/components/console/pos-kiosk/kiosk-menu.js +344 -0
  63. package/src/lib/components/console/pos-kiosk/kiosk-menu.js.map +1 -0
  64. package/src/lib/components/console/pos-kiosk/kiosk-staff.d.ts +12 -0
  65. package/src/lib/components/console/pos-kiosk/kiosk-staff.js +257 -0
  66. package/src/lib/components/console/pos-kiosk/kiosk-staff.js.map +1 -0
  67. package/src/lib/components/console/pos-kiosk/pos-kiosk-api.d.ts +114 -0
  68. package/src/lib/components/console/pos-kiosk/pos-kiosk-api.js +189 -0
  69. package/src/lib/components/console/pos-kiosk/pos-kiosk-api.js.map +1 -0
  70. package/src/lib/components/console/pos-kiosk/use-kiosk-idle.d.ts +16 -0
  71. package/src/lib/components/console/pos-kiosk/use-kiosk-idle.js +80 -0
  72. package/src/lib/components/console/pos-kiosk/use-kiosk-idle.js.map +1 -0
  73. package/src/lib/components/console/pos-kiosk-page.component.d.ts +28 -0
  74. package/src/lib/components/console/pos-kiosk-page.component.js +791 -0
  75. package/src/lib/components/console/pos-kiosk-page.component.js.map +1 -0
  76. package/src/lib/components/console/pos-offline/pos-offline-api.d.ts +44 -0
  77. package/src/lib/components/console/pos-offline/pos-offline-api.js +69 -0
  78. package/src/lib/components/console/pos-offline/pos-offline-api.js.map +1 -0
  79. package/src/lib/components/console/pos-offline/pos-offline-banner.component.d.ts +7 -0
  80. package/src/lib/components/console/pos-offline/pos-offline-banner.component.js +135 -0
  81. package/src/lib/components/console/pos-offline/pos-offline-banner.component.js.map +1 -0
  82. package/src/lib/components/console/pos-offline/pos-offline-checkout.component.d.ts +32 -0
  83. package/src/lib/components/console/pos-offline/pos-offline-checkout.component.js +287 -0
  84. package/src/lib/components/console/pos-offline/pos-offline-checkout.component.js.map +1 -0
  85. package/src/lib/components/console/pos-offline/pos-offline-store.d.ts +63 -0
  86. package/src/lib/components/console/pos-offline/pos-offline-store.js +145 -0
  87. package/src/lib/components/console/pos-offline/pos-offline-store.js.map +1 -0
  88. package/src/lib/components/console/pos-offline/register-offline.d.ts +24 -0
  89. package/src/lib/components/console/pos-offline/register-offline.js +24 -0
  90. package/src/lib/components/console/pos-offline/register-offline.js.map +1 -0
  91. package/src/lib/components/console/pos-offline/use-pos-offline.d.ts +85 -0
  92. package/src/lib/components/console/pos-offline/use-pos-offline.js +542 -0
  93. package/src/lib/components/console/pos-offline/use-pos-offline.js.map +1 -0
  94. package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js +72 -17
  95. package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js.map +1 -1
  96. package/src/lib/components/console/pos-page.component.js +228 -51
  97. package/src/lib/components/console/pos-page.component.js.map +1 -1
  98. package/src/lib/components/console/pos-zones.d.ts +23 -0
  99. package/src/lib/components/console/pos-zones.js +31 -0
  100. package/src/lib/components/console/pos-zones.js.map +1 -0
  101. package/src/lib/components/console/product-editor-dialog.component.js +10 -64
  102. package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
  103. package/src/lib/components/console/products-hub-card.component.js +46 -30
  104. package/src/lib/components/console/products-hub-card.component.js.map +1 -1
  105. package/src/lib/components/console/shipping-settings-card.component.js +1 -1
  106. package/src/lib/components/console/shipping-settings-card.component.js.map +1 -1
  107. package/src/lib/components/console/stock-movements-card.component.js +48 -16
  108. package/src/lib/components/console/stock-movements-card.component.js.map +1 -1
  109. package/src/lib/components/console/store-zones.d.ts +8 -1
  110. package/src/lib/components/console/store-zones.js +11 -1
  111. package/src/lib/components/console/store-zones.js.map +1 -1
  112. package/src/lib/components/console/storefront-tax-summary-card.component.js +1 -0
  113. package/src/lib/components/console/storefront-tax-summary-card.component.js.map +1 -1
  114. package/src/lib/components/order-status.js +66 -0
  115. package/src/lib/components/order-status.js.map +1 -1
  116. package/src/lib/components/product-detail.js +42 -15
  117. package/src/lib/components/product-detail.js.map +1 -1
  118. package/src/lib/constants/local-fulfillment-list-query.d.ts +48 -0
  119. package/src/lib/constants/local-fulfillment-list-query.js +84 -0
  120. package/src/lib/constants/local-fulfillment-list-query.js.map +1 -0
  121. package/src/lib/constants/orders-list-query.d.ts +7 -2
  122. package/src/lib/constants/orders-list-query.js +89 -8
  123. package/src/lib/constants/orders-list-query.js.map +1 -1
  124. package/src/lib/constants/pos-shift-list-query.d.ts +22 -0
  125. package/src/lib/constants/pos-shift-list-query.js +115 -0
  126. package/src/lib/constants/pos-shift-list-query.js.map +1 -0
  127. package/src/lib/constants/product-list-query.d.ts +6 -1
  128. package/src/lib/constants/product-list-query.js +77 -8
  129. package/src/lib/constants/product-list-query.js.map +1 -1
  130. package/src/lib/constants/stock-movement-query.d.ts +3 -2
  131. package/src/lib/constants/stock-movement-query.js +52 -8
  132. package/src/lib/constants/stock-movement-query.js.map +1 -1
  133. package/src/lib/declarations.server.js +21 -0
  134. package/src/lib/declarations.server.js.map +1 -1
  135. package/src/lib/model/buyer-notifications.d.ts +5 -3
  136. package/src/lib/model/buyer-notifications.js +25 -4
  137. package/src/lib/model/buyer-notifications.js.map +1 -1
  138. package/src/lib/model/commerce-orders.d.ts +103 -1
  139. package/src/lib/model/commerce-orders.js +2 -1
  140. package/src/lib/model/commerce-orders.js.map +1 -1
  141. package/src/lib/model/commerce-pos-kiosk.d.ts +175 -0
  142. package/src/lib/model/commerce-pos-kiosk.js +147 -0
  143. package/src/lib/model/commerce-pos-kiosk.js.map +1 -0
  144. package/src/lib/model/commerce-pos-offline.d.ts +234 -0
  145. package/src/lib/model/commerce-pos-offline.js +301 -0
  146. package/src/lib/model/commerce-pos-offline.js.map +1 -0
  147. package/src/lib/model/commerce-pos-ops.d.ts +16 -6
  148. package/src/lib/model/commerce-pos-ops.js +12 -4
  149. package/src/lib/model/commerce-pos-ops.js.map +1 -1
  150. package/src/lib/model/commerce-pos.d.ts +13 -1
  151. package/src/lib/model/commerce-pos.js +5 -4
  152. package/src/lib/model/commerce-pos.js.map +1 -1
  153. package/src/lib/model/commerce-stock-holds.d.ts +24 -3
  154. package/src/lib/model/commerce-stock-holds.js +26 -8
  155. package/src/lib/model/commerce-stock-holds.js.map +1 -1
  156. package/src/lib/model/commerce.d.ts +7 -1
  157. package/src/lib/model/commerce.js.map +1 -1
  158. package/src/lib/model/index.d.ts +5 -0
  159. package/src/lib/model/index.js +5 -0
  160. package/src/lib/model/index.js.map +1 -1
  161. package/src/lib/model/local-fulfillment-settings.d.ts +178 -0
  162. package/src/lib/model/local-fulfillment-settings.js +361 -0
  163. package/src/lib/model/local-fulfillment-settings.js.map +1 -0
  164. package/src/lib/model/order-list-fields.d.ts +10 -1
  165. package/src/lib/model/order-list-fields.js +1 -0
  166. package/src/lib/model/order-list-fields.js.map +1 -1
  167. package/src/lib/model/order-local-fulfillment.d.ts +131 -0
  168. package/src/lib/model/order-local-fulfillment.js +125 -0
  169. package/src/lib/model/order-local-fulfillment.js.map +1 -0
  170. package/src/lib/model/order-shipping-export.js +4 -0
  171. package/src/lib/model/order-shipping-export.js.map +1 -1
  172. package/src/lib/model/order-status-view.d.ts +20 -1
  173. package/src/lib/model/order-status-view.js +60 -6
  174. package/src/lib/model/order-status-view.js.map +1 -1
  175. package/src/lib/model/product-write.d.ts +186 -0
  176. package/src/lib/model/product-write.js +116 -0
  177. package/src/lib/model/product-write.js.map +1 -0
  178. package/src/lib/plugin-config.js +6 -2
  179. package/src/lib/plugin-config.js.map +1 -1
  180. package/src/lib/plugin.js +11 -0
  181. package/src/lib/plugin.js.map +1 -1
  182. package/src/lib/pos-kiosk-config.d.ts +26 -0
  183. package/src/lib/pos-kiosk-config.js +59 -0
  184. package/src/lib/pos-kiosk-config.js.map +1 -0
  185. package/src/lib/server/api-v1/openapi.js +8 -0
  186. package/src/lib/server/api-v1/openapi.js.map +1 -1
  187. package/src/lib/server/api-v1/order-view.d.ts +19 -0
  188. package/src/lib/server/api-v1/order-view.js +35 -0
  189. package/src/lib/server/api-v1/order-view.js.map +1 -1
  190. package/src/lib/server/billing-webhook.js +238 -87
  191. package/src/lib/server/billing-webhook.js.map +1 -1
  192. package/src/lib/server/cart-checkout.d.ts +2 -0
  193. package/src/lib/server/cart-checkout.js +173 -13
  194. package/src/lib/server/cart-checkout.js.map +1 -1
  195. package/src/lib/server/channel-order-updates.d.ts +50 -0
  196. package/src/lib/server/channel-order-updates.js +290 -0
  197. package/src/lib/server/channel-order-updates.js.map +1 -0
  198. package/src/lib/server/channel-orders.d.ts +85 -0
  199. package/src/lib/server/channel-orders.js +543 -0
  200. package/src/lib/server/channel-orders.js.map +1 -0
  201. package/src/lib/server/checkout-extras.js +18 -4
  202. package/src/lib/server/checkout-extras.js.map +1 -1
  203. package/src/lib/server/checkout.js +71 -14
  204. package/src/lib/server/checkout.js.map +1 -1
  205. package/src/lib/server/local-fulfillment-status.d.ts +86 -0
  206. package/src/lib/server/local-fulfillment-status.js +379 -0
  207. package/src/lib/server/local-fulfillment-status.js.map +1 -0
  208. package/src/lib/server/local-fulfillment.d.ts +190 -0
  209. package/src/lib/server/local-fulfillment.js +580 -0
  210. package/src/lib/server/local-fulfillment.js.map +1 -0
  211. package/src/lib/server/membership-register.js +3 -1
  212. package/src/lib/server/membership-register.js.map +1 -1
  213. package/src/lib/server/order-notifications.js +61 -0
  214. package/src/lib/server/order-notifications.js.map +1 -1
  215. package/src/lib/server/pos-display.d.ts +27 -1
  216. package/src/lib/server/pos-display.js +50 -9
  217. package/src/lib/server/pos-display.js.map +1 -1
  218. package/src/lib/server/pos-kiosk-principal.d.ts +29 -0
  219. package/src/lib/server/pos-kiosk-principal.js +42 -0
  220. package/src/lib/server/pos-kiosk-principal.js.map +1 -0
  221. package/src/lib/server/pos-kiosk.d.ts +54 -0
  222. package/src/lib/server/pos-kiosk.js +972 -0
  223. package/src/lib/server/pos-kiosk.js.map +1 -0
  224. package/src/lib/server/pos-offline-sync.d.ts +85 -0
  225. package/src/lib/server/pos-offline-sync.js +765 -0
  226. package/src/lib/server/pos-offline-sync.js.map +1 -0
  227. package/src/lib/server/pos-order.js +22 -4
  228. package/src/lib/server/pos-order.js.map +1 -1
  229. package/src/lib/server/pos-payment.d.ts +6 -0
  230. package/src/lib/server/pos-payment.js +225 -6
  231. package/src/lib/server/pos-payment.js.map +1 -1
  232. package/src/lib/server/pos-print.js +5 -0
  233. package/src/lib/server/pos-print.js.map +1 -1
  234. package/src/lib/server/pos-return.js +27 -0
  235. package/src/lib/server/pos-return.js.map +1 -1
  236. package/src/lib/server/pos-sale.d.ts +6 -0
  237. package/src/lib/server/pos-sale.js +2 -0
  238. package/src/lib/server/pos-sale.js.map +1 -1
  239. package/src/lib/server/pos-shift.js +8 -1
  240. package/src/lib/server/pos-shift.js.map +1 -1
  241. package/src/lib/server/product-catalog.js +5 -1
  242. package/src/lib/server/product-catalog.js.map +1 -1
  243. package/src/lib/server/product-drafts.d.ts +5 -1
  244. package/src/lib/server/product-drafts.js +3 -3
  245. package/src/lib/server/product-drafts.js.map +1 -1
  246. package/src/lib/server/product-writer.d.ts +19 -0
  247. package/src/lib/server/product-writer.js +261 -0
  248. package/src/lib/server/product-writer.js.map +1 -0
  249. package/src/lib/server/products-write.d.ts +61 -0
  250. package/src/lib/server/products-write.js +375 -0
  251. package/src/lib/server/products-write.js.map +1 -0
  252. package/src/lib/server/refund.js +3 -0
  253. package/src/lib/server/refund.js.map +1 -1
  254. package/src/lib/server/stock-hold.d.ts +9 -1
  255. package/src/lib/server/stock-hold.js +15 -7
  256. package/src/lib/server/stock-hold.js.map +1 -1
  257. package/src/lib/server.js +21 -0
  258. package/src/lib/server.js.map +1 -1
  259. package/src/lib/tenant-emails.js +161 -0
  260. package/src/lib/tenant-emails.js.map +1 -1
  261. package/src/lib/testing/memory-firestore.d.ts +16 -3
  262. package/src/lib/testing/memory-firestore.js +11 -3
  263. package/src/lib/testing/memory-firestore.js.map +1 -1
  264. package/src/lib/transfer/products.server.d.ts +5 -0
  265. package/src/lib/transfer/products.server.js +2 -2
  266. package/src/lib/transfer/products.server.js.map +1 -1
@@ -16,8 +16,10 @@
16
16
  */ /**
17
17
  * What a store tells its buyer, and when (AGL-3610).
18
18
  *
19
- * Five moments in an order's life each send the buyer one message: the
20
- * receipt, each shipment, delivery, each refund and a cancellation. A store
19
+ * Each moment in an order's life sends the buyer one message: the receipt,
20
+ * each shipment, delivery, each refund and a cancellation — and, for an
21
+ * order collected or brought by the store (AGL-3624), ready for pickup,
22
+ * picked up and out for delivery. A store
21
23
  * turns any of them off on `hosts/{hostId}/settings/store.buyerNotifications`
22
24
  * — and ONLY off: every moment is ON unless an explicit `false` is stored,
23
25
  * because transaction messages are on by default for every store, existing
@@ -33,14 +35,21 @@
33
35
  'shipped',
34
36
  'delivered',
35
37
  'refunded',
36
- 'cancelled'
38
+ 'cancelled',
39
+ // Pickup and the store's own delivery (AGL-3624).
40
+ 'ready_for_pickup',
41
+ 'picked_up',
42
+ 'out_for_delivery'
37
43
  ];
38
44
  /** The designable email each moment sends: keys in `tenant-emails.ts`. */ export const BUYER_NOTIFICATION_EMAIL_KEYS = {
39
45
  receipt: 'order-receipt',
40
46
  shipped: 'order-shipped',
41
47
  delivered: 'order-delivered',
42
48
  refunded: 'order-refunded',
43
- cancelled: 'order-cancelled'
49
+ cancelled: 'order-cancelled',
50
+ ready_for_pickup: 'order-ready-for-pickup',
51
+ picked_up: 'order-picked-up',
52
+ out_for_delivery: 'order-out-for-delivery'
44
53
  };
45
54
  /** How the store settings card names each moment. */ export const BUYER_NOTIFICATION_LABELS = {
46
55
  receipt: {
@@ -62,6 +71,18 @@
62
71
  cancelled: {
63
72
  label: 'Order canceled',
64
73
  description: 'When you cancel an order.'
74
+ },
75
+ ready_for_pickup: {
76
+ label: 'Ready for pickup',
77
+ description: 'When you mark a pickup order ready, with where to collect it and the pickup hours.'
78
+ },
79
+ picked_up: {
80
+ label: 'Order picked up',
81
+ description: 'When a pickup order is collected.'
82
+ },
83
+ out_for_delivery: {
84
+ label: 'Out for delivery',
85
+ description: 'When your own driver sets out with a local delivery order.'
65
86
  }
66
87
  };
67
88
  /** Whether a moment (or the `texts` channel) is on. Only `false` is off. */ export function buyerNotificationEnabled(settings, key) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/model/buyer-notifications.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * What a store tells its buyer, and when (AGL-3610).\n *\n * Five moments in an order's life each send the buyer one message: the\n * receipt, each shipment, delivery, each refund and a cancellation. A store\n * turns any of them off on `hosts/{hostId}/settings/store.buyerNotifications`\n * — and ONLY off: every moment is ON unless an explicit `false` is stored,\n * because transaction messages are on by default for every store, existing\n * and new (the 2026-10-06 decision AGL-3600 implemented for the owner's own\n * notices). An absent map, an absent key and a malformed value all read as\n * on, so a schema slip can never silence a store's receipts.\n *\n * `texts` is the channel switch rather than a moment: when the platform can\n * send texts and the order carries the buyer's phone number, each moment that\n * is on also goes by text unless the store turned texts off.\n */\nexport const BUYER_NOTIFICATION_EVENTS = [\n 'receipt',\n 'shipped',\n 'delivered',\n 'refunded',\n 'cancelled',\n] as const\n\nexport type BuyerNotificationEvent = (typeof BUYER_NOTIFICATION_EVENTS)[number]\n\nexport type BuyerNotificationChannel = 'email' | 'sms'\n\nexport type BuyerNotificationSettings = Partial<\n Record<BuyerNotificationEvent | 'texts', boolean>\n>\n\n/** The designable email each moment sends: keys in `tenant-emails.ts`. */\nexport const BUYER_NOTIFICATION_EMAIL_KEYS: Readonly<\n Record<BuyerNotificationEvent, string>\n> = {\n receipt: 'order-receipt',\n shipped: 'order-shipped',\n delivered: 'order-delivered',\n refunded: 'order-refunded',\n cancelled: 'order-cancelled',\n}\n\n/** How the store settings card names each moment. */\nexport const BUYER_NOTIFICATION_LABELS: Readonly<\n Record<BuyerNotificationEvent, { label: string; description: string }>\n> = {\n receipt: {\n label: 'Order receipt',\n description:\n 'When an order is paid: online, from a payment link, or at the register when the customer gives an email.',\n },\n shipped: {\n label: 'Order shipped',\n description:\n 'Each time you ship part or all of an order, with the carrier and tracking link.',\n },\n delivered: {\n label: 'Order delivered',\n description: 'When you mark an order delivered.',\n },\n refunded: {\n label: 'Refund issued',\n description: 'Each refund, with the amount and any items you named.',\n },\n cancelled: {\n label: 'Order canceled',\n description: 'When you cancel an order.',\n },\n}\n\n/** Whether a moment (or the `texts` channel) is on. Only `false` is off. */\nexport function buyerNotificationEnabled(\n settings: unknown,\n key: BuyerNotificationEvent | 'texts',\n): boolean {\n if (!settings || typeof settings !== 'object') return true\n return (settings as Record<string, unknown>)[key] !== false\n}\n\n/**\n * The idempotency key for one message: which moment, which occurrence of it\n * (a shipment id, a refund id; `order` for the once-per-order moments) and\n * which channel. Stored as a field name under `buyerNotifications` on the\n * order, so it is restricted to characters a Firestore field path takes\n * without quoting.\n */\nexport function buyerNotificationMarker(\n event: BuyerNotificationEvent,\n occurrence: string,\n channel: BuyerNotificationChannel,\n): string {\n const safe = (value: string) =>\n String(value || 'order')\n .replace(/[^A-Za-z0-9_-]/g, '_')\n .slice(0, 120)\n return `${event}__${safe(occurrence)}__${channel}`\n}\n\n/**\n * Formats integer cents in the store's currency. Falls back to a plain dollar\n * figure for a currency code `Intl` does not know, rather than throwing on a\n * stored typo.\n */\nexport function formatOrderMoney(cents: number, currency = 'USD'): string {\n const amount = (Number(cents) || 0) / 100\n try {\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: String(currency || 'USD').toUpperCase(),\n }).format(amount)\n } catch {\n return `$${amount.toFixed(2)}`\n }\n}\n"],"names":["BUYER_NOTIFICATION_EVENTS","BUYER_NOTIFICATION_EMAIL_KEYS","receipt","shipped","delivered","refunded","cancelled","BUYER_NOTIFICATION_LABELS","label","description","buyerNotificationEnabled","settings","key","buyerNotificationMarker","event","occurrence","channel","safe","value","String","replace","slice","formatOrderMoney","cents","currency","amount","Number","Intl","NumberFormat","style","toUpperCase","format","toFixed"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;CAeC,GACD,OAAO,MAAMA,4BAA4B;IACvC;IACA;IACA;IACA;IACA;CACD,CAAS;AAUV,wEAAwE,GACxE,OAAO,MAAMC,gCAET;IACFC,SAAS;IACTC,SAAS;IACTC,WAAW;IACXC,UAAU;IACVC,WAAW;AACb,EAAC;AAED,mDAAmD,GACnD,OAAO,MAAMC,4BAET;IACFL,SAAS;QACPM,OAAO;QACPC,aACE;IACJ;IACAN,SAAS;QACPK,OAAO;QACPC,aACE;IACJ;IACAL,WAAW;QACTI,OAAO;QACPC,aAAa;IACf;IACAJ,UAAU;QACRG,OAAO;QACPC,aAAa;IACf;IACAH,WAAW;QACTE,OAAO;QACPC,aAAa;IACf;AACF,EAAC;AAED,0EAA0E,GAC1E,OAAO,SAASC,yBACdC,QAAiB,EACjBC,GAAqC;IAErC,IAAI,CAACD,YAAY,OAAOA,aAAa,UAAU,OAAO;IACtD,OAAO,AAACA,QAAoC,CAACC,IAAI,KAAK;AACxD;AAEA;;;;;;CAMC,GACD,OAAO,SAASC,wBACdC,KAA6B,EAC7BC,UAAkB,EAClBC,OAAiC;IAEjC,MAAMC,OAAO,CAACC,QACZC,OAAOD,SAAS,SACbE,OAAO,CAAC,mBAAmB,KAC3BC,KAAK,CAAC,GAAG;IACd,OAAO,GAAGP,MAAM,EAAE,EAAEG,KAAKF,YAAY,EAAE,EAAEC,SAAS;AACpD;AAEA;;;;CAIC,GACD,OAAO,SAASM,iBAAiBC,KAAa,EAAEC,WAAW,KAAK;IAC9D,MAAMC,SAAS,AAACC,CAAAA,OAAOH,UAAU,CAAA,IAAK;IACtC,IAAI;QACF,OAAO,IAAII,KAAKC,YAAY,CAAC,SAAS;YACpCC,OAAO;YACPL,UAAUL,OAAOK,YAAY,OAAOM,WAAW;QACjD,GAAGC,MAAM,CAACN;IACZ,EAAE,eAAM;QACN,OAAO,CAAC,CAAC,EAAEA,OAAOO,OAAO,CAAC,IAAI;IAChC;AACF"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/model/buyer-notifications.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * What a store tells its buyer, and when (AGL-3610).\n *\n * Each moment in an order's life sends the buyer one message: the receipt,\n * each shipment, delivery, each refund and a cancellation — and, for an\n * order collected or brought by the store (AGL-3624), ready for pickup,\n * picked up and out for delivery. A store\n * turns any of them off on `hosts/{hostId}/settings/store.buyerNotifications`\n * — and ONLY off: every moment is ON unless an explicit `false` is stored,\n * because transaction messages are on by default for every store, existing\n * and new (the 2026-10-06 decision AGL-3600 implemented for the owner's own\n * notices). An absent map, an absent key and a malformed value all read as\n * on, so a schema slip can never silence a store's receipts.\n *\n * `texts` is the channel switch rather than a moment: when the platform can\n * send texts and the order carries the buyer's phone number, each moment that\n * is on also goes by text unless the store turned texts off.\n */\nexport const BUYER_NOTIFICATION_EVENTS = [\n 'receipt',\n 'shipped',\n 'delivered',\n 'refunded',\n 'cancelled',\n // Pickup and the store's own delivery (AGL-3624).\n 'ready_for_pickup',\n 'picked_up',\n 'out_for_delivery',\n] as const\n\nexport type BuyerNotificationEvent = (typeof BUYER_NOTIFICATION_EVENTS)[number]\n\nexport type BuyerNotificationChannel = 'email' | 'sms'\n\nexport type BuyerNotificationSettings = Partial<\n Record<BuyerNotificationEvent | 'texts', boolean>\n>\n\n/** The designable email each moment sends: keys in `tenant-emails.ts`. */\nexport const BUYER_NOTIFICATION_EMAIL_KEYS: Readonly<\n Record<BuyerNotificationEvent, string>\n> = {\n receipt: 'order-receipt',\n shipped: 'order-shipped',\n delivered: 'order-delivered',\n refunded: 'order-refunded',\n cancelled: 'order-cancelled',\n ready_for_pickup: 'order-ready-for-pickup',\n picked_up: 'order-picked-up',\n out_for_delivery: 'order-out-for-delivery',\n}\n\n/** How the store settings card names each moment. */\nexport const BUYER_NOTIFICATION_LABELS: Readonly<\n Record<BuyerNotificationEvent, { label: string; description: string }>\n> = {\n receipt: {\n label: 'Order receipt',\n description:\n 'When an order is paid: online, from a payment link, or at the register when the customer gives an email.',\n },\n shipped: {\n label: 'Order shipped',\n description:\n 'Each time you ship part or all of an order, with the carrier and tracking link.',\n },\n delivered: {\n label: 'Order delivered',\n description: 'When you mark an order delivered.',\n },\n refunded: {\n label: 'Refund issued',\n description: 'Each refund, with the amount and any items you named.',\n },\n cancelled: {\n label: 'Order canceled',\n description: 'When you cancel an order.',\n },\n ready_for_pickup: {\n label: 'Ready for pickup',\n description: 'When you mark a pickup order ready, with where to collect it and the pickup hours.',\n },\n picked_up: {\n label: 'Order picked up',\n description: 'When a pickup order is collected.',\n },\n out_for_delivery: {\n label: 'Out for delivery',\n description: 'When your own driver sets out with a local delivery order.',\n },\n}\n\n/** Whether a moment (or the `texts` channel) is on. Only `false` is off. */\nexport function buyerNotificationEnabled(\n settings: unknown,\n key: BuyerNotificationEvent | 'texts',\n): boolean {\n if (!settings || typeof settings !== 'object') return true\n return (settings as Record<string, unknown>)[key] !== false\n}\n\n/**\n * The idempotency key for one message: which moment, which occurrence of it\n * (a shipment id, a refund id; `order` for the once-per-order moments) and\n * which channel. Stored as a field name under `buyerNotifications` on the\n * order, so it is restricted to characters a Firestore field path takes\n * without quoting.\n */\nexport function buyerNotificationMarker(\n event: BuyerNotificationEvent,\n occurrence: string,\n channel: BuyerNotificationChannel,\n): string {\n const safe = (value: string) =>\n String(value || 'order')\n .replace(/[^A-Za-z0-9_-]/g, '_')\n .slice(0, 120)\n return `${event}__${safe(occurrence)}__${channel}`\n}\n\n/**\n * Formats integer cents in the store's currency. Falls back to a plain dollar\n * figure for a currency code `Intl` does not know, rather than throwing on a\n * stored typo.\n */\nexport function formatOrderMoney(cents: number, currency = 'USD'): string {\n const amount = (Number(cents) || 0) / 100\n try {\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: String(currency || 'USD').toUpperCase(),\n }).format(amount)\n } catch {\n return `$${amount.toFixed(2)}`\n }\n}\n"],"names":["BUYER_NOTIFICATION_EVENTS","BUYER_NOTIFICATION_EMAIL_KEYS","receipt","shipped","delivered","refunded","cancelled","ready_for_pickup","picked_up","out_for_delivery","BUYER_NOTIFICATION_LABELS","label","description","buyerNotificationEnabled","settings","key","buyerNotificationMarker","event","occurrence","channel","safe","value","String","replace","slice","formatOrderMoney","cents","currency","amount","Number","Intl","NumberFormat","style","toUpperCase","format","toFixed"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;CAiBC,GACD,OAAO,MAAMA,4BAA4B;IACvC;IACA;IACA;IACA;IACA;IACA,kDAAkD;IAClD;IACA;IACA;CACD,CAAS;AAUV,wEAAwE,GACxE,OAAO,MAAMC,gCAET;IACFC,SAAS;IACTC,SAAS;IACTC,WAAW;IACXC,UAAU;IACVC,WAAW;IACXC,kBAAkB;IAClBC,WAAW;IACXC,kBAAkB;AACpB,EAAC;AAED,mDAAmD,GACnD,OAAO,MAAMC,4BAET;IACFR,SAAS;QACPS,OAAO;QACPC,aACE;IACJ;IACAT,SAAS;QACPQ,OAAO;QACPC,aACE;IACJ;IACAR,WAAW;QACTO,OAAO;QACPC,aAAa;IACf;IACAP,UAAU;QACRM,OAAO;QACPC,aAAa;IACf;IACAN,WAAW;QACTK,OAAO;QACPC,aAAa;IACf;IACAL,kBAAkB;QAChBI,OAAO;QACPC,aAAa;IACf;IACAJ,WAAW;QACTG,OAAO;QACPC,aAAa;IACf;IACAH,kBAAkB;QAChBE,OAAO;QACPC,aAAa;IACf;AACF,EAAC;AAED,0EAA0E,GAC1E,OAAO,SAASC,yBACdC,QAAiB,EACjBC,GAAqC;IAErC,IAAI,CAACD,YAAY,OAAOA,aAAa,UAAU,OAAO;IACtD,OAAO,AAACA,QAAoC,CAACC,IAAI,KAAK;AACxD;AAEA;;;;;;CAMC,GACD,OAAO,SAASC,wBACdC,KAA6B,EAC7BC,UAAkB,EAClBC,OAAiC;IAEjC,MAAMC,OAAO,CAACC,QACZC,OAAOD,SAAS,SACbE,OAAO,CAAC,mBAAmB,KAC3BC,KAAK,CAAC,GAAG;IACd,OAAO,GAAGP,MAAM,EAAE,EAAEG,KAAKF,YAAY,EAAE,EAAEC,SAAS;AACpD;AAEA;;;;CAIC,GACD,OAAO,SAASM,iBAAiBC,KAAa,EAAEC,WAAW,KAAK;IAC9D,MAAMC,SAAS,AAACC,CAAAA,OAAOH,UAAU,CAAA,IAAK;IACtC,IAAI;QACF,OAAO,IAAII,KAAKC,YAAY,CAAC,SAAS;YACpCC,OAAO;YACPL,UAAUL,OAAOK,YAAY,OAAOM,WAAW;QACjD,GAAGC,MAAM,CAACN;IACZ,EAAE,eAAM;QACN,OAAO,CAAC,CAAC,EAAEA,OAAOO,OAAO,CAAC,IAAI;IAChC;AACF"}
@@ -27,6 +27,8 @@ import type { PaymentRisk } from '@aglyn/aglyn/app-utils/payment-risk';
27
27
  import type { ProductType } from './commerce';
28
28
  import type { StorefrontTaxMode } from './commerce-tax-decision';
29
29
  import type { OrderPayment } from './commerce-pos';
30
+ import type { PosOfflineOrderStamp } from './commerce-pos-offline';
31
+ import type { OrderFulfillmentMethod, OrderLocalDelivery, OrderPickup } from './order-local-fulfillment';
30
32
  export type OrderStatus = 'pending' | 'paid' | 'partially_fulfilled' | 'fulfilled' | 'delivered' | 'cancelled' | 'refunded';
31
33
  /**
32
34
  * Where the sale came through. `subscription` is a recurring cycle of a
@@ -37,7 +39,48 @@ export type OrderStatus = 'pending' | 'paid' | 'partially_fulfilled' | 'fulfille
37
39
  * there is nothing to ship, and AGL-1732's "a subscription is not an order"
38
40
  * stands for them.
39
41
  */
40
- export type OrderChannel = 'online' | 'pos' | 'draft' | 'subscription';
42
+ export type OrderChannel = 'online' | 'pos' | 'draft' | 'subscription' | 'marketplace';
43
+ /**
44
+ * Where an order sold on an outside channel came from (AGL-3638): a
45
+ * marketplace that took the buyer's money and pays the merchant out. Written
46
+ * once, by the import that recorded the order (`server/channel-orders.ts`).
47
+ */
48
+ export interface OrderChannelSource {
49
+ /** The importer's id for the channel, e.g. `ebay`. */
50
+ channelId: string;
51
+ /** What the merchant calls it, e.g. `eBay`. */
52
+ channelLabel: string;
53
+ /** The channel's own order id, the import's idempotency key. */
54
+ externalOrderId: string;
55
+ /** What the merchant sees on the channel. */
56
+ externalRef: string;
57
+ /** Which order line each of the channel's lines became, for a shipment sent back to it. */
58
+ lines: Array<{
59
+ lineIndex: number;
60
+ externalLineId: string;
61
+ }>;
62
+ /** ISO 4217, upper case: the currency every amount on the order is in. */
63
+ currency: string;
64
+ /** The channel collected this order's tax and remits it, as the marketplace facilitator. */
65
+ taxRemittedByChannel: true;
66
+ /**
67
+ * What the channel charged the merchant for the sale, RECORDED for the
68
+ * merchant's books and never charged by Aglyn; `null` until the channel
69
+ * says.
70
+ */
71
+ fees: Array<{
72
+ label: string;
73
+ amountCents: number;
74
+ }> | null;
75
+ feesTotalCents: number | null;
76
+ /**
77
+ * How the goods leave (AGL-3644): `courier`, handed to the channel's own
78
+ * courier (a delivery app); absent reads as `ship`.
79
+ */
80
+ handoff?: 'ship' | 'courier';
81
+ /** The channel's ids of the refunds and adjustments recorded on the order, so each is recorded once (AGL-3644). */
82
+ refundIds?: string[];
83
+ }
41
84
  /** Snapshot of what was bought — self-contained for history. */
42
85
  export interface OrderLineItem {
43
86
  productId: string;
@@ -148,6 +191,12 @@ export interface OrderFulfillment {
148
191
  updatedAtMs?: number;
149
192
  /** Whether the buyer was to be told about this shipment. */
150
193
  notify?: boolean;
194
+ /**
195
+ * Handed over rather than shipped (AGL-3624): collected at a pickup
196
+ * location or brought by the store's own driver. No carrier, no tracking,
197
+ * and no "your order has shipped" message.
198
+ */
199
+ handover?: 'pickup' | 'local_delivery';
151
200
  atMs: number;
152
201
  }
153
202
  /**
@@ -306,13 +355,38 @@ export interface OrderUnresolvedLine {
306
355
  quantity: number;
307
356
  }
308
357
  /** `hosts/{hostId}/orders/{id}` doc. */
358
+ /**
359
+ * Store credit another plugin kept that came off an online sale (AGL-3640),
360
+ * as core's checkout-credits seam records it (`PluginCheckoutCreditSold`),
361
+ * restated here so the order model stays pure for the native apps.
362
+ */
363
+ export interface OrderCredit {
364
+ /** `{pluginId}.{key}`. */
365
+ providerId: string;
366
+ pluginId: string;
367
+ key: string;
368
+ /** The provider's own handle on the account; never a code. */
369
+ reference: string;
370
+ label: string;
371
+ last4: string;
372
+ amountCents: number;
373
+ appliedAs: 'discount' | 'tender';
374
+ }
309
375
  export interface HostOrder {
310
376
  /** Human order number, sequential per host (e.g. #1042). */
311
377
  number?: number;
312
378
  /** Optional lines the buyer added at checkout (AGL-3635); see {@link OrderExtra}. */
313
379
  extras?: OrderExtra[];
380
+ /**
381
+ * Store credit another plugin kept that came off an ONLINE sale (AGL-3640),
382
+ * as its provider recorded it. A register sale's credit is one of its
383
+ * `payments` instead.
384
+ */
385
+ credits?: OrderCredit[];
314
386
  status: OrderStatus;
315
387
  channel?: OrderChannel;
388
+ /** The outside channel an order with channel `marketplace` was sold on (AGL-3638). */
389
+ channelSource?: OrderChannelSource;
316
390
  /**
317
391
  * Which location's stock this sale came off, for the multi-location counts
318
392
  * of AGL-286. Written by the POS register, the only sale path that decrements
@@ -323,6 +397,16 @@ export interface HostOrder {
323
397
  * erases the restock.
324
398
  */
325
399
  locationId?: string;
400
+ /**
401
+ * How the buyer chose to receive the order (AGL-3624). Absent reads as
402
+ * shipped, which every order before pickup and local delivery was. Also
403
+ * stamps `locationId` above when the stock came off that location.
404
+ */
405
+ fulfillmentMethod?: OrderFulfillmentMethod;
406
+ /** The pickup the buyer chose (AGL-3624), with `fulfillmentMethod` `pickup`. */
407
+ pickup?: OrderPickup;
408
+ /** The store's own delivery the buyer chose (AGL-3624), with `fulfillmentMethod` `local_delivery`. */
409
+ localDelivery?: OrderLocalDelivery;
326
410
  /**
327
411
  * The register a POS sale was rung on, and the console user who rang it
328
412
  * (AGL-472, AGL-3607).
@@ -354,6 +438,18 @@ export interface HostOrder {
354
438
  to?: string;
355
439
  atMs: number;
356
440
  };
441
+ /**
442
+ * A register sale a customer built at a self-service kiosk (AGL-3623), and
443
+ * the kiosk (its device token's hash prefix).
444
+ */
445
+ posSource?: 'kiosk';
446
+ kioskDeviceId?: string;
447
+ /**
448
+ * Set while a kiosk order waits in its register's queue for a cashier to
449
+ * take payment ("Pay at counter"), and when it joined.
450
+ */
451
+ kioskQueueRegisterId?: string;
452
+ kioskQueuedAtMs?: number;
357
453
  /**
358
454
  * The register discount that was applied, and the member who applied it
359
455
  * (AGL-2161). Present only on a POS order that carries a discount.
@@ -421,6 +517,12 @@ export interface HostOrder {
421
517
  shippingAddress?: OrderAddress;
422
518
  billingAddress?: OrderAddress;
423
519
  timeline?: OrderTimelineEvent[];
520
+ /**
521
+ * A register sale rung while offline (AGL-3625): when it was rung, when it
522
+ * synced, and what did not match — stock that went short, a price that
523
+ * changed. Absent on every other order.
524
+ */
525
+ offline?: PosOfflineOrderStamp;
424
526
  fulfillments?: OrderFulfillment[];
425
527
  note?: string;
426
528
  couponCode?: string;
@@ -852,7 +852,8 @@ export function computeCheckoutSessionTotals(lineItems, session, parts) {
852
852
  online: 'Online',
853
853
  pos: 'POS',
854
854
  draft: 'Draft',
855
- subscription: 'Subscription'
855
+ subscription: 'Subscription',
856
+ marketplace: 'Marketplace'
856
857
  };
857
858
  /** Human label for a channel, tolerating a legacy/unknown value. */ export function orderChannelLabel(channel) {
858
859
  var _ref, _ORDER_CHANNEL_LABELS_;