@aglyn/plugins-commerce 1.0.0-beta.284 → 1.0.0-beta.287

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 (420) hide show
  1. package/README.md +1 -1
  2. package/package.json +13 -13
  3. package/src/lib/components/cart.js +25 -12
  4. package/src/lib/components/cart.js.map +1 -1
  5. package/src/lib/components/commerce-console-page.js +70 -13
  6. package/src/lib/components/commerce-console-page.js.map +1 -1
  7. package/src/lib/components/console/order-detail-dialog.component.js +2 -1
  8. package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
  9. package/src/lib/components/console/payment-methods-card.component.js +1 -1
  10. package/src/lib/components/console/payment-methods-card.component.js.map +1 -1
  11. package/src/lib/components/console/pos/pos-cart-panel.component.d.ts +5 -0
  12. package/src/lib/components/console/pos/pos-cart-panel.component.js +18 -12
  13. package/src/lib/components/console/pos/pos-cart-panel.component.js.map +1 -1
  14. package/src/lib/components/console/pos/pos-hardware-api.d.ts +76 -5
  15. package/src/lib/components/console/pos/pos-hardware-api.js +53 -11
  16. package/src/lib/components/console/pos/pos-hardware-api.js.map +1 -1
  17. package/src/lib/components/console/pos/pos-hardware-buyer.component.d.ts +18 -0
  18. package/src/lib/components/console/pos/pos-hardware-buyer.component.js +629 -0
  19. package/src/lib/components/console/pos/pos-hardware-buyer.component.js.map +1 -0
  20. package/src/lib/components/console/pos/pos-hardware-sale-api.d.ts +162 -0
  21. package/src/lib/components/console/pos/pos-hardware-sale-api.js +122 -0
  22. package/src/lib/components/console/pos/pos-hardware-sale-api.js.map +1 -0
  23. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.d.ts +39 -0
  24. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js +251 -0
  25. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js.map +1 -0
  26. package/src/lib/components/console/pos/use-pos-display.js +50 -0
  27. package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
  28. package/src/lib/components/console/pos-cellular-control.component.d.ts +41 -0
  29. package/src/lib/components/console/pos-cellular-control.component.js +211 -0
  30. package/src/lib/components/console/pos-cellular-control.component.js.map +1 -0
  31. package/src/lib/components/console/pos-devices-card.component.d.ts +9 -1
  32. package/src/lib/components/console/pos-devices-card.component.js +47 -15
  33. package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
  34. package/src/lib/components/console/pos-display/pos-display-api.d.ts +6 -0
  35. package/src/lib/components/console/pos-display/pos-display-api.js +8 -1
  36. package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
  37. package/src/lib/components/console/pos-display-page.component.d.ts +13 -0
  38. package/src/lib/components/console/pos-display-page.component.js +44 -2
  39. package/src/lib/components/console/pos-display-page.component.js.map +1 -1
  40. package/src/lib/components/console/pos-hardware-card.component.d.ts +12 -4
  41. package/src/lib/components/console/pos-hardware-card.component.js +157 -36
  42. package/src/lib/components/console/pos-hardware-card.component.js.map +1 -1
  43. package/src/lib/components/console/pos-hardware-orders-staff-page.component.js +360 -80
  44. package/src/lib/components/console/pos-hardware-orders-staff-page.component.js.map +1 -1
  45. package/src/lib/components/console/pos-hardware-terms-page.component.d.ts +34 -0
  46. package/src/lib/components/console/pos-hardware-terms-page.component.js +257 -0
  47. package/src/lib/components/console/pos-hardware-terms-page.component.js.map +1 -0
  48. package/src/lib/components/console/pos-hardware-terms-sign-page.component.d.ts +27 -0
  49. package/src/lib/components/console/pos-hardware-terms-sign-page.component.js +104 -0
  50. package/src/lib/components/console/pos-hardware-terms-sign-page.component.js.map +1 -0
  51. package/src/lib/components/console/pos-hardware-waiting-card.component.d.ts +24 -0
  52. package/src/lib/components/console/pos-hardware-waiting-card.component.js +205 -0
  53. package/src/lib/components/console/pos-hardware-waiting-card.component.js.map +1 -0
  54. package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js +297 -201
  55. package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js.map +1 -1
  56. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.d.ts +3 -0
  57. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js +260 -92
  58. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js.map +1 -1
  59. package/src/lib/components/console/pos-ops/pos-operations-bar.component.d.ts +9 -0
  60. package/src/lib/components/console/pos-ops/pos-operations-bar.component.js +15 -6
  61. package/src/lib/components/console/pos-ops/pos-operations-bar.component.js.map +1 -1
  62. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.d.ts +25 -0
  63. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js +136 -0
  64. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js.map +1 -0
  65. package/src/lib/components/console/pos-ops/pos-shift-panel.component.d.ts +6 -0
  66. package/src/lib/components/console/pos-ops/pos-shift-panel.component.js +48 -31
  67. package/src/lib/components/console/pos-ops/pos-shift-panel.component.js.map +1 -1
  68. package/src/lib/components/console/pos-page.component.d.ts +1 -1
  69. package/src/lib/components/console/pos-page.component.js +63 -12
  70. package/src/lib/components/console/pos-page.component.js.map +1 -1
  71. package/src/lib/components/console/pos-reader-splash-setting.component.js +1 -1
  72. package/src/lib/components/console/pos-reader-splash-setting.component.js.map +1 -1
  73. package/src/lib/components/console/product-check-in-fields.component.d.ts +4 -2
  74. package/src/lib/components/console/product-check-in-fields.component.js +60 -14
  75. package/src/lib/components/console/product-check-in-fields.component.js.map +1 -1
  76. package/src/lib/components/console/product-editor-dialog.component.js +44 -1
  77. package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
  78. package/src/lib/components/console/product-hardware-sku-field.component.d.ts +19 -0
  79. package/src/lib/components/console/product-hardware-sku-field.component.js +92 -0
  80. package/src/lib/components/console/product-hardware-sku-field.component.js.map +1 -0
  81. package/src/lib/components/console/product-kiosk-offer-field.component.d.ts +22 -0
  82. package/src/lib/components/console/product-kiosk-offer-field.component.js +94 -0
  83. package/src/lib/components/console/product-kiosk-offer-field.component.js.map +1 -0
  84. package/src/lib/components/console/product-register-fields.component.d.ts +4 -0
  85. package/src/lib/components/console/product-register-fields.component.js +31 -2
  86. package/src/lib/components/console/product-register-fields.component.js.map +1 -1
  87. package/src/lib/components/console/products-hub-card.component.js +11 -2
  88. package/src/lib/components/console/products-hub-card.component.js.map +1 -1
  89. package/src/lib/components/console/register-hardware-card.component.d.ts +11 -0
  90. package/src/lib/components/console/register-hardware-card.component.js +56 -27
  91. package/src/lib/components/console/register-hardware-card.component.js.map +1 -1
  92. package/src/lib/components/console/reservation-guests-dialog.component.d.ts +28 -0
  93. package/src/lib/components/console/reservation-guests-dialog.component.js +189 -0
  94. package/src/lib/components/console/reservation-guests-dialog.component.js.map +1 -0
  95. package/src/lib/components/console/reservations-card.component.d.ts +9 -0
  96. package/src/lib/components/console/reservations-card.component.js +158 -23
  97. package/src/lib/components/console/reservations-card.component.js.map +1 -1
  98. package/src/lib/components/console/shippingeasy-card.component.js +1 -1
  99. package/src/lib/components/console/shippingeasy-card.component.js.map +1 -1
  100. package/src/lib/components/console/shipstation-card.component.d.ts +1 -1
  101. package/src/lib/components/console/shipstation-card.component.js +3 -3
  102. package/src/lib/components/console/shipstation-card.component.js.map +1 -1
  103. package/src/lib/components/product-detail.d.ts +4 -0
  104. package/src/lib/components/product-detail.js +40 -5
  105. package/src/lib/components/product-detail.js.map +1 -1
  106. package/src/lib/components/product-reviews.js +28 -11
  107. package/src/lib/components/product-reviews.js.map +1 -1
  108. package/src/lib/components/reservation-widget.js +28 -5
  109. package/src/lib/components/reservation-widget.js.map +1 -1
  110. package/src/lib/components/use-day-picker.d.ts +25 -0
  111. package/src/lib/components/use-day-picker.js +57 -0
  112. package/src/lib/components/use-day-picker.js.map +1 -0
  113. package/src/lib/constants/operator-alerts.d.ts +55 -0
  114. package/src/lib/constants/operator-alerts.js +156 -1
  115. package/src/lib/constants/operator-alerts.js.map +1 -1
  116. package/src/lib/declarations.console-server.js +54 -1
  117. package/src/lib/declarations.console-server.js.map +1 -1
  118. package/src/lib/declarations.d.ts +4 -2
  119. package/src/lib/declarations.js +11 -4
  120. package/src/lib/declarations.js.map +1 -1
  121. package/src/lib/declarations.server.js +9 -0
  122. package/src/lib/declarations.server.js.map +1 -1
  123. package/src/lib/model/commerce-cart.d.ts +9 -1
  124. package/src/lib/model/commerce-cart.js +4 -3
  125. package/src/lib/model/commerce-cart.js.map +1 -1
  126. package/src/lib/model/commerce-check-in-product.d.ts +26 -0
  127. package/src/lib/model/commerce-check-in-product.js +64 -2
  128. package/src/lib/model/commerce-check-in-product.js.map +1 -1
  129. package/src/lib/model/commerce-check-in-record.d.ts +127 -0
  130. package/src/lib/model/commerce-check-in-record.js +36 -0
  131. package/src/lib/model/commerce-check-in-record.js.map +1 -0
  132. package/src/lib/model/commerce-check-in.d.ts +91 -87
  133. package/src/lib/model/commerce-check-in.js +186 -62
  134. package/src/lib/model/commerce-check-in.js.map +1 -1
  135. package/src/lib/model/commerce-kiosk-offer.d.ts +31 -0
  136. package/src/lib/model/commerce-kiosk-offer.js +35 -0
  137. package/src/lib/model/commerce-kiosk-offer.js.map +1 -0
  138. package/src/lib/model/commerce-orders.d.ts +76 -0
  139. package/src/lib/model/commerce-orders.js +6 -0
  140. package/src/lib/model/commerce-orders.js.map +1 -1
  141. package/src/lib/model/commerce-pos-day-report.d.ts +54 -1
  142. package/src/lib/model/commerce-pos-day-report.js +39 -2
  143. package/src/lib/model/commerce-pos-day-report.js.map +1 -1
  144. package/src/lib/model/commerce-pos-offline.d.ts +1 -1
  145. package/src/lib/model/commerce-pos-offline.js +6 -1
  146. package/src/lib/model/commerce-pos-offline.js.map +1 -1
  147. package/src/lib/model/commerce-pos-ops.js +3 -2
  148. package/src/lib/model/commerce-pos-ops.js.map +1 -1
  149. package/src/lib/model/commerce-pos.d.ts +36 -3
  150. package/src/lib/model/commerce-pos.js +14 -6
  151. package/src/lib/model/commerce-pos.js.map +1 -1
  152. package/src/lib/model/commerce-receipt.js +3 -2
  153. package/src/lib/model/commerce-receipt.js.map +1 -1
  154. package/src/lib/model/commerce-reservations.d.ts +69 -4
  155. package/src/lib/model/commerce-reservations.js +57 -5
  156. package/src/lib/model/commerce-reservations.js.map +1 -1
  157. package/src/lib/model/commerce.d.ts +66 -0
  158. package/src/lib/model/commerce.js +15 -0
  159. package/src/lib/model/commerce.js.map +1 -1
  160. package/src/lib/model/order-list-fields.d.ts +11 -0
  161. package/src/lib/model/order-list-fields.js +17 -1
  162. package/src/lib/model/order-list-fields.js.map +1 -1
  163. package/src/lib/model/own-store-tax-summary.d.ts +152 -0
  164. package/src/lib/model/own-store-tax-summary.js +288 -0
  165. package/src/lib/model/own-store-tax-summary.js.map +1 -0
  166. package/src/lib/model/plugin-permissions.d.ts +67 -0
  167. package/src/lib/model/plugin-permissions.js +224 -7
  168. package/src/lib/model/plugin-permissions.js.map +1 -1
  169. package/src/lib/model/pos-cellular.d.ts +223 -0
  170. package/src/lib/model/pos-cellular.js +293 -0
  171. package/src/lib/model/pos-cellular.js.map +1 -0
  172. package/src/lib/model/pos-hardware-in-person.d.ts +98 -0
  173. package/src/lib/model/pos-hardware-in-person.js +224 -0
  174. package/src/lib/model/pos-hardware-in-person.js.map +1 -0
  175. package/src/lib/model/pos-hardware-tax-summary.d.ts +166 -0
  176. package/src/lib/model/pos-hardware-tax-summary.js +225 -0
  177. package/src/lib/model/pos-hardware-tax-summary.js.map +1 -0
  178. package/src/lib/model/pos-hardware-terms.d.ts +74 -0
  179. package/src/lib/model/pos-hardware-terms.js +115 -0
  180. package/src/lib/model/pos-hardware-terms.js.map +1 -0
  181. package/src/lib/model/pos-hardware.d.ts +349 -7
  182. package/src/lib/model/pos-hardware.js +291 -20
  183. package/src/lib/model/pos-hardware.js.map +1 -1
  184. package/src/lib/model/product-write.d.ts +10 -0
  185. package/src/lib/model/product-write.js +4 -2
  186. package/src/lib/model/product-write.js.map +1 -1
  187. package/src/lib/plugin.js +16 -0
  188. package/src/lib/plugin.js.map +1 -1
  189. package/src/lib/server/billing-webhook.js +25 -1
  190. package/src/lib/server/billing-webhook.js.map +1 -1
  191. package/src/lib/server/cancel-order.js +7 -5
  192. package/src/lib/server/cancel-order.js.map +1 -1
  193. package/src/lib/server/cart-checkout.js +20 -8
  194. package/src/lib/server/cart-checkout.js.map +1 -1
  195. package/src/lib/server/cart.js +29 -0
  196. package/src/lib/server/cart.js.map +1 -1
  197. package/src/lib/server/checkout.js +42 -13
  198. package/src/lib/server/checkout.js.map +1 -1
  199. package/src/lib/server/collection-membership.d.ts +4 -0
  200. package/src/lib/server/collection-membership.js +5 -10
  201. package/src/lib/server/collection-membership.js.map +1 -1
  202. package/src/lib/server/commerce-site-keys.d.ts +29 -0
  203. package/src/lib/server/commerce-site-keys.js +40 -0
  204. package/src/lib/server/commerce-site-keys.js.map +1 -0
  205. package/src/lib/server/draft-order.js +8 -5
  206. package/src/lib/server/draft-order.js.map +1 -1
  207. package/src/lib/server/fulfill-order.js +7 -5
  208. package/src/lib/server/fulfill-order.js.map +1 -1
  209. package/src/lib/server/gift-cards.js +8 -5
  210. package/src/lib/server/gift-cards.js.map +1 -1
  211. package/src/lib/server/local-fulfillment-status.js +9 -6
  212. package/src/lib/server/local-fulfillment-status.js.map +1 -1
  213. package/src/lib/server/member-post.js +6 -5
  214. package/src/lib/server/member-post.js.map +1 -1
  215. package/src/lib/server/membership-admin-password.d.ts +4 -2
  216. package/src/lib/server/membership-admin-password.js +10 -8
  217. package/src/lib/server/membership-admin-password.js.map +1 -1
  218. package/src/lib/server/membership-admin-remove.d.ts +7 -5
  219. package/src/lib/server/membership-admin-remove.js +9 -9
  220. package/src/lib/server/membership-admin-remove.js.map +1 -1
  221. package/src/lib/server/order-notifications.js +5 -2
  222. package/src/lib/server/order-notifications.js.map +1 -1
  223. package/src/lib/server/order-print.js +7 -5
  224. package/src/lib/server/order-print.js.map +1 -1
  225. package/src/lib/server/order-receipt-send.js +8 -5
  226. package/src/lib/server/order-receipt-send.js.map +1 -1
  227. package/src/lib/server/orders-shipping-prepare.js +9 -6
  228. package/src/lib/server/orders-shipping-prepare.js.map +1 -1
  229. package/src/lib/server/own-store-tax-return-source.d.ts +47 -0
  230. package/src/lib/server/own-store-tax-return-source.js +312 -0
  231. package/src/lib/server/own-store-tax-return-source.js.map +1 -0
  232. package/src/lib/server/payment-methods.js +13 -9
  233. package/src/lib/server/payment-methods.js.map +1 -1
  234. package/src/lib/server/pos-auth.d.ts +37 -6
  235. package/src/lib/server/pos-auth.js +40 -15
  236. package/src/lib/server/pos-auth.js.map +1 -1
  237. package/src/lib/server/pos-cellular-billing.d.ts +81 -0
  238. package/src/lib/server/pos-cellular-billing.js +711 -0
  239. package/src/lib/server/pos-cellular-billing.js.map +1 -0
  240. package/src/lib/server/pos-cellular-notify.d.ts +47 -0
  241. package/src/lib/server/pos-cellular-notify.js +150 -0
  242. package/src/lib/server/pos-cellular-notify.js.map +1 -0
  243. package/src/lib/server/pos-cellular.d.ts +88 -0
  244. package/src/lib/server/pos-cellular.js +339 -0
  245. package/src/lib/server/pos-cellular.js.map +1 -0
  246. package/src/lib/server/pos-check-in.d.ts +5 -1
  247. package/src/lib/server/pos-check-in.js +296 -28
  248. package/src/lib/server/pos-check-in.js.map +1 -1
  249. package/src/lib/server/pos-day-report.js +29 -3
  250. package/src/lib/server/pos-day-report.js.map +1 -1
  251. package/src/lib/server/pos-display.d.ts +16 -0
  252. package/src/lib/server/pos-display.js +129 -2
  253. package/src/lib/server/pos-display.js.map +1 -1
  254. package/src/lib/server/pos-hardware-admin.d.ts +10 -1
  255. package/src/lib/server/pos-hardware-admin.js +250 -84
  256. package/src/lib/server/pos-hardware-admin.js.map +1 -1
  257. package/src/lib/server/pos-hardware-attach.d.ts +105 -0
  258. package/src/lib/server/pos-hardware-attach.js +443 -0
  259. package/src/lib/server/pos-hardware-attach.js.map +1 -0
  260. package/src/lib/server/pos-hardware-buyer-lookup.d.ts +58 -0
  261. package/src/lib/server/pos-hardware-buyer-lookup.js +180 -0
  262. package/src/lib/server/pos-hardware-buyer-lookup.js.map +1 -0
  263. package/src/lib/server/pos-hardware-buyer-record.d.ts +29 -0
  264. package/src/lib/server/pos-hardware-buyer-record.js +86 -0
  265. package/src/lib/server/pos-hardware-buyer-record.js.map +1 -0
  266. package/src/lib/server/pos-hardware-cancel.d.ts +58 -0
  267. package/src/lib/server/pos-hardware-cancel.js +147 -0
  268. package/src/lib/server/pos-hardware-cancel.js.map +1 -0
  269. package/src/lib/server/pos-hardware-closure-notices.d.ts +27 -0
  270. package/src/lib/server/pos-hardware-closure-notices.js +85 -0
  271. package/src/lib/server/pos-hardware-closure-notices.js.map +1 -0
  272. package/src/lib/server/pos-hardware-closure.d.ts +60 -0
  273. package/src/lib/server/pos-hardware-closure.js +153 -0
  274. package/src/lib/server/pos-hardware-closure.js.map +1 -0
  275. package/src/lib/server/pos-hardware-in-person.d.ts +61 -0
  276. package/src/lib/server/pos-hardware-in-person.js +236 -0
  277. package/src/lib/server/pos-hardware-in-person.js.map +1 -0
  278. package/src/lib/server/pos-hardware-notify.d.ts +40 -2
  279. package/src/lib/server/pos-hardware-notify.js +195 -14
  280. package/src/lib/server/pos-hardware-notify.js.map +1 -1
  281. package/src/lib/server/pos-hardware-readers.d.ts +115 -0
  282. package/src/lib/server/pos-hardware-readers.js +430 -0
  283. package/src/lib/server/pos-hardware-readers.js.map +1 -0
  284. package/src/lib/server/pos-hardware-returns.d.ts +116 -0
  285. package/src/lib/server/pos-hardware-returns.js +502 -0
  286. package/src/lib/server/pos-hardware-returns.js.map +1 -0
  287. package/src/lib/server/pos-hardware-sale-fields.d.ts +28 -0
  288. package/src/lib/server/pos-hardware-sale-fields.js +44 -0
  289. package/src/lib/server/pos-hardware-sale-fields.js.map +1 -0
  290. package/src/lib/server/pos-hardware-sale.d.ts +54 -0
  291. package/src/lib/server/pos-hardware-sale.js +369 -0
  292. package/src/lib/server/pos-hardware-sale.js.map +1 -0
  293. package/src/lib/server/pos-hardware-tax-return-source.d.ts +99 -0
  294. package/src/lib/server/pos-hardware-tax-return-source.js +462 -0
  295. package/src/lib/server/pos-hardware-tax-return-source.js.map +1 -0
  296. package/src/lib/server/pos-hardware-terms.d.ts +64 -0
  297. package/src/lib/server/pos-hardware-terms.js +154 -0
  298. package/src/lib/server/pos-hardware-terms.js.map +1 -0
  299. package/src/lib/server/pos-hardware-user-eraser.d.ts +3 -0
  300. package/src/lib/server/pos-hardware-user-eraser.js +31 -7
  301. package/src/lib/server/pos-hardware-user-eraser.js.map +1 -1
  302. package/src/lib/server/pos-hardware-webhook.d.ts +5 -0
  303. package/src/lib/server/pos-hardware-webhook.js +51 -6
  304. package/src/lib/server/pos-hardware-webhook.js.map +1 -1
  305. package/src/lib/server/pos-hardware.d.ts +74 -1
  306. package/src/lib/server/pos-hardware.js +175 -10
  307. package/src/lib/server/pos-hardware.js.map +1 -1
  308. package/src/lib/server/pos-kiosk.d.ts +2 -0
  309. package/src/lib/server/pos-kiosk.js +17 -12
  310. package/src/lib/server/pos-kiosk.js.map +1 -1
  311. package/src/lib/server/pos-offline-card-order.d.ts +64 -0
  312. package/src/lib/server/pos-offline-card-order.js +102 -0
  313. package/src/lib/server/pos-offline-card-order.js.map +1 -0
  314. package/src/lib/server/pos-offline-card-reconcile.d.ts +67 -1
  315. package/src/lib/server/pos-offline-card-reconcile.js +215 -18
  316. package/src/lib/server/pos-offline-card-reconcile.js.map +1 -1
  317. package/src/lib/server/pos-offline-sync.d.ts +39 -0
  318. package/src/lib/server/pos-offline-sync.js +190 -55
  319. package/src/lib/server/pos-offline-sync.js.map +1 -1
  320. package/src/lib/server/pos-ops-gate.d.ts +15 -4
  321. package/src/lib/server/pos-ops-gate.js +42 -9
  322. package/src/lib/server/pos-ops-gate.js.map +1 -1
  323. package/src/lib/server/pos-ops-routes.js +24 -0
  324. package/src/lib/server/pos-ops-routes.js.map +1 -1
  325. package/src/lib/server/pos-order-refund-ids.d.ts +28 -0
  326. package/src/lib/server/pos-order-refund-ids.js +31 -0
  327. package/src/lib/server/pos-order-refund-ids.js.map +1 -0
  328. package/src/lib/server/pos-order.js +52 -49
  329. package/src/lib/server/pos-order.js.map +1 -1
  330. package/src/lib/server/pos-payment.js +1 -1
  331. package/src/lib/server/pos-payment.js.map +1 -1
  332. package/src/lib/server/pos-reader-splash-admin.js +30 -32
  333. package/src/lib/server/pos-reader-splash-admin.js.map +1 -1
  334. package/src/lib/server/pos-reader-splash-images-route.d.ts +17 -0
  335. package/src/lib/server/pos-reader-splash-images-route.js +113 -0
  336. package/src/lib/server/pos-reader-splash-images-route.js.map +1 -0
  337. package/src/lib/server/pos-reader-splash-images.d.ts +51 -0
  338. package/src/lib/server/pos-reader-splash-images.js +123 -0
  339. package/src/lib/server/pos-reader-splash-images.js.map +1 -0
  340. package/src/lib/server/pos-reader-splash.d.ts +68 -1
  341. package/src/lib/server/pos-reader-splash.js +182 -11
  342. package/src/lib/server/pos-reader-splash.js.map +1 -1
  343. package/src/lib/server/pos-readers.d.ts +29 -0
  344. package/src/lib/server/pos-readers.js +134 -35
  345. package/src/lib/server/pos-readers.js.map +1 -1
  346. package/src/lib/server/pos-return.d.ts +10 -0
  347. package/src/lib/server/pos-return.js +26 -1
  348. package/src/lib/server/pos-return.js.map +1 -1
  349. package/src/lib/server/pos-sale.js +6 -1
  350. package/src/lib/server/pos-sale.js.map +1 -1
  351. package/src/lib/server/pos-shift.js +11 -0
  352. package/src/lib/server/pos-shift.js.map +1 -1
  353. package/src/lib/server/pos-staff-pin.js +25 -20
  354. package/src/lib/server/pos-staff-pin.js.map +1 -1
  355. package/src/lib/server/pos-terminal.d.ts +14 -4
  356. package/src/lib/server/pos-terminal.js +34 -38
  357. package/src/lib/server/pos-terminal.js.map +1 -1
  358. package/src/lib/server/printers.d.ts +7 -3
  359. package/src/lib/server/printers.js +18 -12
  360. package/src/lib/server/printers.js.map +1 -1
  361. package/src/lib/server/product-drafts.d.ts +11 -1
  362. package/src/lib/server/product-drafts.js +12 -8
  363. package/src/lib/server/product-drafts.js.map +1 -1
  364. package/src/lib/server/product.d.ts +15 -1
  365. package/src/lib/server/product.js +16 -3
  366. package/src/lib/server/product.js.map +1 -1
  367. package/src/lib/server/products-write.d.ts +26 -2
  368. package/src/lib/server/products-write.js +19 -7
  369. package/src/lib/server/products-write.js.map +1 -1
  370. package/src/lib/server/refund.js +34 -11
  371. package/src/lib/server/refund.js.map +1 -1
  372. package/src/lib/server/reservation-availability-query.d.ts +8 -0
  373. package/src/lib/server/reservation-availability-query.js +11 -1
  374. package/src/lib/server/reservation-availability-query.js.map +1 -1
  375. package/src/lib/server/reservation-availability.d.ts +1 -1
  376. package/src/lib/server/reservation-availability.js +7 -2
  377. package/src/lib/server/reservation-availability.js.map +1 -1
  378. package/src/lib/server/reservation-guests.d.ts +32 -0
  379. package/src/lib/server/reservation-guests.js +285 -0
  380. package/src/lib/server/reservation-guests.js.map +1 -0
  381. package/src/lib/server/reservation-walk-in.d.ts +11 -1
  382. package/src/lib/server/reservation-walk-in.js +56 -12
  383. package/src/lib/server/reservation-walk-in.js.map +1 -1
  384. package/src/lib/server/reserve.js +18 -5
  385. package/src/lib/server/reserve.js.map +1 -1
  386. package/src/lib/server/returns.js +9 -6
  387. package/src/lib/server/returns.js.map +1 -1
  388. package/src/lib/server/reviews.d.ts +22 -2
  389. package/src/lib/server/reviews.js +88 -20
  390. package/src/lib/server/reviews.js.map +1 -1
  391. package/src/lib/server/shipping-connectors.js +10 -11
  392. package/src/lib/server/shipping-connectors.js.map +1 -1
  393. package/src/lib/server/site-page-resolver.js +20 -3
  394. package/src/lib/server/site-page-resolver.js.map +1 -1
  395. package/src/lib/server/store-day.d.ts +33 -0
  396. package/src/lib/server/store-day.js +46 -0
  397. package/src/lib/server/store-day.js.map +1 -0
  398. package/src/lib/server/store-setup-ai-writer.d.ts +2 -1
  399. package/src/lib/server/store-setup-ai-writer.js +5 -6
  400. package/src/lib/server/store-setup-ai-writer.js.map +1 -1
  401. package/src/lib/server/storefront-tax.d.ts +13 -0
  402. package/src/lib/server/storefront-tax.js +8 -1
  403. package/src/lib/server/storefront-tax.js.map +1 -1
  404. package/src/lib/server/tax-return-source.d.ts +32 -3
  405. package/src/lib/server/tax-return-source.js +99 -20
  406. package/src/lib/server/tax-return-source.js.map +1 -1
  407. package/src/lib/server.js +100 -2
  408. package/src/lib/server.js.map +1 -1
  409. package/src/lib/testing/fake-firestore.js +58 -16
  410. package/src/lib/testing/fake-firestore.js.map +1 -1
  411. package/src/lib/testing/pos-ops-memory-firestore.js +18 -4
  412. package/src/lib/testing/pos-ops-memory-firestore.js.map +1 -1
  413. package/src/lib/testing/site-register-permissions.d.ts +29 -0
  414. package/src/lib/testing/site-register-permissions.js +38 -0
  415. package/src/lib/testing/site-register-permissions.js.map +1 -0
  416. package/src/lib/transfer/tracking.server.js +8 -5
  417. package/src/lib/transfer/tracking.server.js.map +1 -1
  418. package/src/lib/utils/add-to-cart.d.ts +2 -0
  419. package/src/lib/utils/add-to-cart.js +6 -3
  420. package/src/lib/utils/add-to-cart.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/model/commerce-pos-ops.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\nimport { apportionCents, type HostOrder } from './commerce-orders'\nimport { orderPayments } from './commerce-pos'\nimport type { PrintReport } from './commerce-printers'\nimport { receiptDataFromOrder } from './commerce-receipt'\n\n/*==========================================\n * RUNNING THE REGISTER (AGL-3609): shifts and the cash drawer, register\n * returns and the receipt. Pure and client-safe: the routes, the register\n * and the reports all compute from these, so a drawer's expected cash is one\n * formula wherever it is shown.\n *\n * Where each thing lives:\n *\n * hosts/{hostId}/registers/{registerId}\n * `openShiftId` — the one open shift, claimed in a transaction\n * hosts/{hostId}/registers/{registerId}/shifts/{shiftId} {@link PosShift}\n * hosts/{hostId}/registers/{registerId}/returns/{returnId} {@link PosRegisterReturn}\n * hosts/{hostId}/posStaffPins/{uid} server-only\n *\n * Everything under `registers` is written by the Admin SDK only (the\n * register pool is billed), and every member of the site may read it.\n *=========================================*/\n\n/** How one payment toward a sale was taken, in the register's tender words. */\nexport type PosTenderMethod =\n | 'cash'\n | 'card_present'\n | 'card_keyed'\n | 'card_link'\n | 'gift_card'\n | 'folio'\n /** Store credit another plugin keeps (AGL-3640). */\n | 'credit'\n\nexport const POS_TENDER_METHODS: readonly PosTenderMethod[] = [\n 'cash',\n 'card_present',\n 'card_keyed',\n 'card_link',\n 'gift_card',\n 'folio',\n 'credit',\n]\n\n/** What each tender is called on a report, a receipt and a refund. */\nexport const POS_TENDER_LABELS: Readonly<Record<PosTenderMethod, string>> = {\n cash: 'Cash',\n card_present: 'Card',\n card_keyed: 'Card (keyed)',\n card_link: 'Card (payment link)',\n gift_card: 'Gift card',\n folio: 'Room charge',\n credit: 'Store credit',\n}\n\n/** The tenders whose money moved through Stripe and goes back through it. */\nexport const POS_STRIPE_TENDERS: ReadonlySet<PosTenderMethod> = new Set([\n 'card_present',\n 'card_keyed',\n 'card_link',\n])\n\n/**\n * One settled payment toward a sale, as the shift report and a register\n * return read it.\n */\nexport interface PosOrderTender {\n /** The payment's id on the order, or `legacy` for an order before the tender ledger. */\n id: string\n method: PosTenderMethod\n /** Cents put toward the sale; never the tip, never the change. */\n amountCents: number\n tipCents: number\n paymentIntentId?: string\n giftCardId?: string\n reservationId?: string\n /** For `credit` (AGL-3640): the provider, its account handle, and its name. */\n creditProviderId?: string\n creditReference?: string\n creditLabel?: string\n cardBrand?: string\n last4?: string\n cashTenderedCents?: number\n changeCents?: number\n}\n\nconst wholeCents = (value: unknown): number => {\n const number = Math.round(Number(value))\n return Number.isFinite(number) && number > 0 ? number : 0\n}\n\n\nconst isTenderMethod = (value: unknown): value is PosTenderMethod =>\n typeof value === 'string' && (POS_TENDER_METHODS as readonly string[]).includes(value)\n\n/** The order fields the tender reader looks at. */\nexport interface PosTenderSource {\n payments?: unknown\n channel?: string\n status?: string\n totals?: { totalCents?: number; tipCents?: number } | null\n amountCents?: number\n reservationId?: string\n checkoutSessionId?: string\n paymentIntentId?: string\n}\n\n/**\n * THE ONE PLACE THE TENDER LEDGER IS READ (AGL-3609).\n *\n * A register sale may carry `payments[]` — one entry per tender, the ledger\n * the split-tender register writes (AGL-3607) — and only the payments that\n * SUCCEEDED count: a declined card or a voided gift card took nothing. An\n * order written before that ledger is one payment, inferred the way the\n * ledger's own reader infers it: a folio when it names a reservation, a card\n * link when Stripe saw it (or it came through the storefront), cash otherwise.\n *\n * The ledger's own reader (`orderPayments`) does both; this narrows it to the\n * settled payments and the fields a report or a refund reads.\n */\nexport function posOrderTenders(order: PosTenderSource | null | undefined): PosOrderTender[] {\n if (!order) return []\n return orderPayments(order as Parameters<typeof orderPayments>[0])\n .filter((payment) => payment.status === 'succeeded' && isTenderMethod(payment.method))\n .map((payment) => ({\n id: payment.id,\n method: payment.method as PosTenderMethod,\n amountCents: wholeCents(payment.amountCents),\n tipCents: wholeCents(payment.tipCents ?? (payment.id === 'legacy' ? order.totals?.tipCents : 0)),\n ...(payment.paymentIntentId ? { paymentIntentId: payment.paymentIntentId } : {}),\n ...(payment.giftCardId ? { giftCardId: payment.giftCardId } : {}),\n ...(payment.reservationId ? { reservationId: payment.reservationId } : {}),\n ...(payment.creditProviderId ? { creditProviderId: payment.creditProviderId } : {}),\n ...(payment.creditReference ? { creditReference: payment.creditReference } : {}),\n ...(payment.creditLabel ? { creditLabel: payment.creditLabel } : {}),\n ...(payment.cardBrand ? { cardBrand: payment.cardBrand } : {}),\n ...(payment.last4 ? { last4: payment.last4 } : {}),\n ...(payment.cashTenderedCents != null ? { cashTenderedCents: wholeCents(payment.cashTenderedCents) } : {}),\n ...(payment.changeCents != null ? { changeCents: wholeCents(payment.changeCents) } : {}),\n }))\n}\n\n/** A tender as one line of a receipt: `Card •• 4242`. */\nexport function posTenderLabel(\n tender: Pick<PosOrderTender, 'method' | 'cardBrand' | 'last4'> & { creditLabel?: string },\n): string {\n const base = (tender.method === 'credit' && tender.creditLabel) || POS_TENDER_LABELS[tender.method] || tender.method\n if (tender.last4) {\n return `${tender.cardBrand ? capitalize(tender.cardBrand) : base} •• ${tender.last4}`\n }\n return base\n}\n\nfunction capitalize(value: string): string {\n return value ? value.charAt(0).toUpperCase() + value.slice(1) : value\n}\n\n/*==========================================\n * SHIFTS AND THE CASH DRAWER\n *=========================================*/\n\n/**\n * Cash that moved through the drawer without a sale: money put in, money\n * paid out for a reason (a delivery, petty cash), a drop to the safe, and\n * a register return paid out in cash.\n */\nexport type PosCashEventType = 'paid_in' | 'paid_out' | 'drop' | 'refund'\n\nexport const POS_CASH_EVENT_LABELS: Readonly<Record<PosCashEventType, string>> = {\n paid_in: 'Paid in',\n paid_out: 'Paid out',\n drop: 'Safe drop',\n refund: 'Cash refund',\n}\n\nexport interface PosCashEvent {\n /** The register's attempt id, so a retried tap records one event. */\n id: string\n type: PosCashEventType\n amountCents: number\n reason: string\n /** The member who moved the cash. */\n by: string\n atMs: number\n /** The order a `refund` paid out against. */\n orderId?: string\n}\n\n/** Sales, refunds and cash movements over one shift. */\nexport interface PosShiftReport {\n orderCount: number\n /** What customers paid for the goods: order totals, tax in, tips out. */\n grossSalesCents: number\n discountsCents: number\n taxCents: number\n tipsCents: number\n salesByTender: Partial<Record<PosTenderMethod, number>>\n refundCount: number\n refundsCents: number\n refundsByTender: Partial<Record<PosTenderMethod, number>>\n /** Gross sales less refunds. */\n netSalesCents: number\n openingFloatCents: number\n cashSalesCents: number\n paidInCents: number\n paidOutCents: number\n dropsCents: number\n cashRefundsCents: number\n /** float + cash sales + paid in − paid out − drops − cash refunds. */\n expectedCashCents: number\n /** More sales were stamped with the shift than the report could read. */\n truncated?: boolean\n}\n\n/** `hosts/{hostId}/registers/{registerId}/shifts/{shiftId}`. */\nexport interface PosShift {\n hostId: string\n registerId: string\n status: 'open' | 'closed'\n openedBy: string\n /** The member's name when the shift opened, for the history and the export. */\n openedByName?: string\n openedAtMs: number\n openingFloatCents: number\n cashEvents: PosCashEvent[]\n closedBy?: string\n closedByName?: string\n /*\n * The history sorts by each of the five below (AGL-3680), and an `orderBy`\n * drops a shift that lacks the field, so the shift is opened with each one\n * `null` and the close fills them — see `POS_SHIFT_LIST_QUERY`.\n */\n closedAtMs?: number | null\n /** What the closing cashier counted in the drawer. */\n countedCashCents?: number | null\n expectedCashCents?: number | null\n /** counted − expected: positive is over, negative is short. */\n varianceCents?: number | null\n /** The Z report's `netSalesCents`, flattened so the history can order by it. */\n netSalesCents?: number | null\n closingNote?: string\n /** The Z report, frozen when the shift closed. */\n report?: PosShiftReport\n}\n\n/** The cash-event sums one formula reads. */\nexport function posCashEventTotals(events: readonly PosCashEvent[] | null | undefined): {\n paidInCents: number\n paidOutCents: number\n dropsCents: number\n cashRefundsCents: number\n} {\n const sum = (type: PosCashEventType) =>\n (events ?? [])\n .filter((event) => event?.type === type)\n .reduce((total, event) => total + wholeCents(event.amountCents), 0)\n return {\n paidInCents: sum('paid_in'),\n paidOutCents: sum('paid_out'),\n dropsCents: sum('drop'),\n cashRefundsCents: sum('refund'),\n }\n}\n\n/**\n * THE DRAWER'S EXPECTED CASH: what should be in it when it is counted.\n *\n * opening float + cash sales + paid in − paid out − safe drops − cash refunds\n *\n * Cash SALES are the cash tender's `amountCents`, which is what the sale took\n * and never what the customer handed over: the change went straight back out\n * of the same drawer. A tip left in cash is in the drawer too, so it counts.\n */\nexport function posExpectedCashCents(input: {\n openingFloatCents: number\n cashSalesCents: number\n paidInCents: number\n paidOutCents: number\n dropsCents: number\n cashRefundsCents: number\n}): number {\n return (\n wholeCents(input.openingFloatCents) +\n wholeCents(input.cashSalesCents) +\n wholeCents(input.paidInCents) -\n wholeCents(input.paidOutCents) -\n wholeCents(input.dropsCents) -\n wholeCents(input.cashRefundsCents)\n )\n}\n\n/** A sale as the shift report reads it. */\nexport interface PosShiftSale extends PosTenderSource {\n totals?: {\n totalCents?: number\n discountCents?: number\n taxCents?: number\n tipCents?: number\n } | null\n}\n\n/** A register return as the shift report reads it. */\nexport interface PosShiftRefund {\n refundedCents: number\n tenders: Array<{ method: PosTenderMethod; amountCents: number }>\n}\n\n/**\n * The X report (mid-shift) and the Z report (at close) are this one function\n * over the sales stamped with the shift, the returns rung at the register\n * during it and the shift's own cash events. A pending sale took no money and\n * a cancelled one gave it back, so neither counts; a sale refunded LATER\n * still counts as a sale, and its refund is counted where it was paid out.\n */\nexport function computePosShiftReport(input: {\n shift: Pick<PosShift, 'openingFloatCents' | 'cashEvents'>\n sales: readonly PosShiftSale[]\n refunds: readonly PosShiftRefund[]\n truncated?: boolean\n}): PosShiftReport {\n const salesByTender: Partial<Record<PosTenderMethod, number>> = {}\n const refundsByTender: Partial<Record<PosTenderMethod, number>> = {}\n let orderCount = 0\n let grossSalesCents = 0\n let discountsCents = 0\n let taxCents = 0\n let tipsCents = 0\n let cashSalesCents = 0\n for (const sale of input.sales) {\n if (sale.status === 'pending' || sale.status === 'cancelled') continue\n const tenders = posOrderTenders(sale)\n orderCount += 1\n grossSalesCents += wholeCents(sale.totals?.totalCents ?? sale.amountCents)\n discountsCents += wholeCents(sale.totals?.discountCents)\n taxCents += wholeCents(sale.totals?.taxCents)\n const tenderTips = tenders.reduce((sum, tender) => sum + tender.tipCents, 0)\n tipsCents += Math.max(wholeCents(sale.totals?.tipCents), tenderTips)\n for (const tender of tenders) {\n salesByTender[tender.method] = (salesByTender[tender.method] ?? 0) + tender.amountCents\n if (tender.method === 'cash') cashSalesCents += tender.amountCents + tender.tipCents\n }\n }\n let refundsCents = 0\n for (const refund of input.refunds) {\n refundsCents += wholeCents(refund.refundedCents)\n for (const tender of refund.tenders ?? []) {\n if (!isTenderMethod(tender.method)) continue\n refundsByTender[tender.method] =\n (refundsByTender[tender.method] ?? 0) + wholeCents(tender.amountCents)\n }\n }\n const cash = posCashEventTotals(input.shift.cashEvents)\n const openingFloatCents = wholeCents(input.shift.openingFloatCents)\n return {\n orderCount,\n grossSalesCents,\n discountsCents,\n taxCents,\n tipsCents,\n salesByTender,\n refundCount: input.refunds.length,\n refundsCents,\n refundsByTender,\n netSalesCents: grossSalesCents - refundsCents,\n openingFloatCents,\n cashSalesCents,\n ...cash,\n expectedCashCents: posExpectedCashCents({ openingFloatCents, cashSalesCents, ...cash }),\n ...(input.truncated ? { truncated: true } : {}),\n }\n}\n\n/** counted − expected; positive is over, negative is short. */\nexport function posCashVarianceCents(countedCashCents: number, expectedCashCents: number): number {\n return Math.round(Number(countedCashCents) || 0) - Math.round(Number(expectedCashCents) || 0)\n}\n\n/** `$12.34`, `-$0.50` — the register's money format, store currency USD. */\nexport function posMoney(cents: number): string {\n const value = Math.round(Number(cents) || 0)\n return `${value < 0 ? '-' : ''}$${(Math.abs(value) / 100).toFixed(2)}`\n}\n\n/** One CSV cell, quoted when it needs to be and never read as a formula. */\nfunction csvCell(value: unknown): string {\n let cell = value == null ? '' : String(value)\n if (/^[=+\\-@\\t\\r]/.test(cell) && !/^-?\\d+(\\.\\d+)?$/.test(cell)) cell = `'${cell}`\n return /[\",\\r\\n]/.test(cell) ? `\"${cell.replace(/\"/g, '\"\"')}\"` : cell\n}\n\nexport { csvCell as posCsvCell }\n\nconst dollars = (cents: number | null | undefined): string =>\n cents == null ? '' : (Math.round(cents) / 100).toFixed(2)\n\n/** The shift history as a spreadsheet: one row per shift, money in dollars. */\nexport function posShiftsCsv(\n shifts: ReadonlyArray<PosShift & { id: string; registerName?: string }>,\n memberName: (uid: string) => string = (uid) => uid,\n): string {\n const header = [\n 'Shift',\n 'Register',\n 'Opened',\n 'Opened by',\n 'Closed',\n 'Closed by',\n 'Orders',\n 'Gross sales',\n 'Refunds',\n 'Net sales',\n 'Discounts',\n 'Tax',\n 'Tips',\n 'Cash sales',\n 'Card sales',\n 'Gift card sales',\n 'Room charges',\n 'Opening float',\n 'Paid in',\n 'Paid out',\n 'Safe drops',\n 'Cash refunds',\n 'Expected cash',\n 'Counted cash',\n 'Variance',\n ]\n const iso = (ms: number | null | undefined) => (ms ? new Date(ms).toISOString() : '')\n const rows = shifts.map((shift) => {\n const report = shift.report\n const card = report\n ? (report.salesByTender.card_present ?? 0) +\n (report.salesByTender.card_keyed ?? 0) +\n (report.salesByTender.card_link ?? 0)\n : undefined\n return [\n shift.id,\n shift.registerName ?? shift.registerId,\n iso(shift.openedAtMs),\n shift.openedByName ?? memberName(shift.openedBy),\n iso(shift.closedAtMs),\n shift.closedBy ? (shift.closedByName ?? memberName(shift.closedBy)) : '',\n report?.orderCount ?? '',\n dollars(report?.grossSalesCents),\n dollars(report?.refundsCents),\n dollars(report?.netSalesCents),\n dollars(report?.discountsCents),\n dollars(report?.taxCents),\n dollars(report?.tipsCents),\n dollars(report?.cashSalesCents),\n dollars(card),\n dollars(report ? (report.salesByTender.gift_card ?? 0) : undefined),\n dollars(report ? (report.salesByTender.folio ?? 0) : undefined),\n dollars(shift.openingFloatCents),\n dollars(report?.paidInCents),\n dollars(report?.paidOutCents),\n dollars(report?.dropsCents),\n dollars(report?.cashRefundsCents),\n dollars(shift.expectedCashCents ?? report?.expectedCashCents),\n dollars(shift.countedCashCents),\n dollars(shift.varianceCents),\n ]\n })\n return [header, ...rows].map((row) => row.map(csvCell).join(',')).join('\\r\\n')\n}\n\n/*==========================================\n * RETURNS AT THE REGISTER\n *=========================================*/\n\n/** One line picked for return: its index on the order and how many units. */\nexport interface PosReturnPick {\n index: number\n quantity: number\n}\n\n/** The order fields a return reads. */\nexport interface PosReturnSource extends PosTenderSource {\n lineItems?: Array<{ unitAmountCents?: number; quantity?: number; name?: string }> | null\n totals?: {\n totalCents?: number\n discountCents?: number\n taxCents?: number\n shippingCents?: number\n tipCents?: number\n } | null\n refundedCents?: number\n refundedLineItemIds?: number[]\n /** Units of each line already returned at a register, by line index. */\n returnedQuantities?: Record<string, number>\n /** Cents already refunded to each payment by a register return. */\n posPaymentRefunds?: Record<string, number>\n}\n\n/**\n * What each line is worth back, whole: its price less its share of the\n * order's discount, plus its share of the order's tax — the same\n * apportionment `orderLineRefundCents` uses for the discount, extended to the\n * tax a register sale charged on top. Shipping and tips are not a line's.\n */\nexport function posReturnLineValues(order: PosReturnSource): number[] {\n const lines = order.lineItems ?? []\n const gross = lines.map(\n (line) =>\n Math.max(0, Math.round(Number(line?.unitAmountCents ?? 0))) *\n Math.max(1, Math.round(Number(line?.quantity ?? 1))),\n )\n const discountShares = apportionCents(gross, wholeCents(order.totals?.discountCents))\n const net = gross.map((cents, index) => Math.max(0, cents - (discountShares[index] ?? 0)))\n const taxShares = apportionCents(net, wholeCents(order.totals?.taxCents))\n return net.map((cents, index) => cents + (taxShares[index] ?? 0))\n}\n\n/** Units of each line already returned, a line refunded whole counting as all of it. */\nexport function posReturnedQuantities(order: PosReturnSource): number[] {\n const lines = order.lineItems ?? []\n const wholeLines = new Set(order.refundedLineItemIds ?? [])\n return lines.map((line, index) => {\n const quantity = Math.max(1, Math.round(Number(line?.quantity ?? 1)))\n if (wholeLines.has(index)) return quantity\n const returned = Math.round(Number(order.returnedQuantities?.[String(index)] ?? 0))\n return Math.min(quantity, Math.max(0, Number.isFinite(returned) ? returned : 0))\n })\n}\n\nexport type PosReturnPlan =\n | {\n ok: true\n refundCents: number\n /** Cents per picked line, in the order picked. */\n lineCents: number[]\n /** The order's per-line returned quantities after this return. */\n returnedQuantities: Record<string, number>\n /** Lines this return finishes, for `refundedLineItemIds`. */\n completedLines: number[]\n }\n | { ok: false; error: string }\n\n/**\n * What a return of these picks refunds, to the cent.\n *\n * Each line's value is split across its units CUMULATIVELY: returning `k` of\n * `n` units already returned `r` refunds `round(V·(r+k)/n) − round(V·r/n)`,\n * so returning a line one unit at a time refunds exactly what returning it\n * whole would have, and the rounding never strands or invents a cent. The\n * sum is capped at what is left to refund on the order — a refund given\n * from the order dialog already took its share.\n *\n * `heldElsewhere` is, per line, the units an online return (the returns\n * flow) already holds or took back. They cap what the register may take, but\n * they are not written into `returnedQuantities`, which counts only what the\n * register itself took.\n */\nexport function planPosReturn(\n order: PosReturnSource,\n picks: readonly PosReturnPick[],\n heldElsewhere: readonly number[] = [],\n): PosReturnPlan {\n const lines = order.lineItems ?? []\n if (!picks.length) return { ok: false, error: 'Pick at least one item to return.' }\n const values = posReturnLineValues(order)\n const returned = posReturnedQuantities(order)\n const seen = new Set<number>()\n const lineCents: number[] = []\n const nextReturned: Record<string, number> = {}\n for (const [index, count] of returned.entries()) if (count > 0) nextReturned[String(index)] = count\n const completedLines: number[] = []\n for (const pick of picks) {\n const index = Number(pick.index)\n const quantity = Number(pick.quantity)\n if (!Number.isInteger(index) || index < 0 || index >= lines.length) {\n return { ok: false, error: `Line ${pick.index} is not on this order.` }\n }\n if (seen.has(index)) return { ok: false, error: 'Each line can be picked once.' }\n seen.add(index)\n if (!Number.isInteger(quantity) || quantity < 1) {\n return { ok: false, error: 'Return at least one of each line you pick.' }\n }\n const total = Math.max(1, Math.round(Number(lines[index]?.quantity ?? 1)))\n const already = returned[index] ?? 0\n const held = Math.max(0, Math.round(Number(heldElsewhere[index] ?? 0)))\n if (already + held + quantity > total) {\n const left = Math.max(0, total - already - held)\n return {\n ok: false,\n error:\n left > 0\n ? `Only ${left} of \"${lines[index]?.name ?? 'that item'}\" can still be returned.`\n : held > 0\n ? `\"${lines[index]?.name ?? 'That item'}\" is already in a return. Finish it under Returns.`\n : `\"${lines[index]?.name ?? 'That item'}\" has already been returned.`,\n }\n }\n const value = values[index] ?? 0\n lineCents.push(\n Math.round((value * (already + quantity)) / total) - Math.round((value * already) / total),\n )\n nextReturned[String(index)] = already + quantity\n if (already + quantity === total) completedLines.push(index)\n }\n const remaining = Math.max(\n 0,\n wholeCents(order.totals?.totalCents) - wholeCents(order.refundedCents),\n )\n const asked = lineCents.reduce((sum, cents) => sum + cents, 0)\n const refundCents = Math.min(asked, remaining)\n if (!(refundCents > 0)) return { ok: false, error: 'Nothing is left to refund on this order.' }\n return { ok: true, refundCents, lineCents, returnedQuantities: nextReturned, completedLines }\n}\n\n/** One slice of a refund, sent back to one of the sale's payments. */\nexport interface PosRefundAllocation {\n paymentId: string\n method: PosTenderMethod\n amountCents: number\n}\n\n/**\n * What each payment can still take back: what it put toward the sale, less\n * what register returns already sent to it. A refund given from the order\n * dialog refunds through Stripe without naming a payment, so whatever it\n * took that no payment accounts for comes off the Stripe payments first.\n */\nexport function posRefundableByTender(order: PosReturnSource): Array<PosOrderTender & { refundableCents: number }> {\n const tenders = posOrderTenders(order)\n const attributed = Object.values(order.posPaymentRefunds ?? {}).reduce(\n (sum, cents) => sum + wholeCents(cents),\n 0,\n )\n let unattributed = Math.max(0, wholeCents(order.refundedCents) - attributed)\n const ordered = [...tenders].sort(\n (a, b) => Number(POS_STRIPE_TENDERS.has(b.method)) - Number(POS_STRIPE_TENDERS.has(a.method)),\n )\n const refundable = new Map<string, number>()\n for (const tender of ordered) {\n let left = Math.max(0, tender.amountCents - wholeCents(order.posPaymentRefunds?.[tender.id]))\n if (POS_STRIPE_TENDERS.has(tender.method) && unattributed > 0) {\n const taken = Math.min(left, unattributed)\n left -= taken\n unattributed -= taken\n }\n refundable.set(tender.id, left)\n }\n return tenders.map((tender) => ({ ...tender, refundableCents: refundable.get(tender.id) ?? 0 }))\n}\n\n/**\n * The order a refund goes back in, when the cashier does not split it by\n * hand: the cards first, then store credit, then the room, and the drawer\n * LAST — so cash leaves the till only for what the customer paid in cash.\n */\nconst REFUND_ORDER: readonly PosTenderMethod[] = [\n 'card_present',\n 'card_keyed',\n 'card_link',\n 'gift_card',\n 'credit',\n 'folio',\n 'cash',\n]\n\nexport type PosRefundSplit =\n | { ok: true; allocations: PosRefundAllocation[] }\n | { ok: false; error: string }\n\n/**\n * Sends `amountCents` back to the sale's own payments.\n *\n * With no `requested` split, each payment takes what it can in\n * {@link REFUND_ORDER}. With one, every slice must name a payment of this\n * sale and fit what that payment can still take, and the slices must add up\n * to the refund exactly — a refund is never sent to a tender the sale was\n * not paid with.\n */\nexport function splitPosRefund(\n order: PosReturnSource,\n amountCents: number,\n requested?: ReadonlyArray<{ paymentId: string; amountCents: number }> | null,\n): PosRefundSplit {\n const amount = wholeCents(amountCents)\n const tenders = posRefundableByTender(order)\n if (!tenders.length) return { ok: false, error: 'This order has no payment to refund to.' }\n if (requested && requested.length) {\n const allocations: PosRefundAllocation[] = []\n const used = new Set<string>()\n for (const slice of requested) {\n const tender = tenders.find((candidate) => candidate.id === slice.paymentId)\n if (!tender) return { ok: false, error: 'That payment is not on this order.' }\n if (used.has(tender.id)) return { ok: false, error: 'Each payment can be named once.' }\n used.add(tender.id)\n const cents = Math.round(Number(slice.amountCents))\n if (!Number.isFinite(cents) || cents < 0) return { ok: false, error: 'Refund amounts must be positive.' }\n if (cents === 0) continue\n if (cents > tender.refundableCents) {\n return {\n ok: false,\n error: `${posTenderLabel(tender)} can take back at most ${posMoney(tender.refundableCents)}.`,\n }\n }\n allocations.push({ paymentId: tender.id, method: tender.method, amountCents: cents })\n }\n const total = allocations.reduce((sum, slice) => sum + slice.amountCents, 0)\n if (total !== amount) {\n return {\n ok: false,\n error: `The refund is ${posMoney(amount)}; the split adds up to ${posMoney(total)}.`,\n }\n }\n return { ok: true, allocations }\n }\n const ordered = [...tenders].sort(\n (a, b) => REFUND_ORDER.indexOf(a.method) - REFUND_ORDER.indexOf(b.method),\n )\n const allocations: PosRefundAllocation[] = []\n let left = amount\n for (const tender of ordered) {\n if (!(left > 0)) break\n const cents = Math.min(left, tender.refundableCents)\n if (!(cents > 0)) continue\n allocations.push({ paymentId: tender.id, method: tender.method, amountCents: cents })\n left -= cents\n }\n if (left > 0) {\n return {\n ok: false,\n error: `Only ${posMoney(amount - left)} can go back to this sale's payments.`,\n }\n }\n return { ok: true, allocations }\n}\n\n/** `hosts/{hostId}/registers/{registerId}/returns/{returnId}`. */\nexport interface PosRegisterReturn {\n hostId: string\n registerId: string\n orderId: string\n orderNumber?: number\n /** The shift the drawer was in when the return was rung, if one was open. */\n shiftId?: string\n lines: Array<{ index: number; quantity: number; name: string; refundCents: number }>\n refundedCents: number\n tenders: Array<PosRefundAllocation & { status: 'refunded' | 'failed'; refundId?: string; error?: string }>\n restocked: boolean\n locationId?: string\n /** The member at the register (by PIN or by sign-in). */\n cashierId: string\n /** The manager whose PIN allowed a refund above the cashier's limit. */\n approvedBy?: string\n reason?: string\n status: 'refunded' | 'partial'\n atMs: number\n}\n\n/*==========================================\n * STAFF PINS\n *=========================================*/\n\n/** How long a cashier PIN switch lasts before the register asks again. */\nexport const POS_CASHIER_ASSERTION_TTL_MS = 15 * 60 * 1000\n/** A manager's approval is for the one refund in front of them. */\nexport const POS_MANAGER_ASSERTION_TTL_MS = 2 * 60 * 1000\n/** Wrong PINs in a row before the member is locked out. */\nexport const POS_PIN_MAX_ATTEMPTS = 5\n/** How long a lockout lasts. */\nexport const POS_PIN_LOCKOUT_MS = 15 * 60 * 1000\n\n/**\n * Why a PIN cannot be used, or `null` when it can: 4 to 6 digits, and not\n * one a stranger tries first — every digit the same, or a straight run.\n */\nexport function posPinProblem(pin: unknown): string | null {\n const value = typeof pin === 'string' ? pin : ''\n if (!/^\\d{4,6}$/.test(value)) return 'A PIN is 4 to 6 digits.'\n if (/^(\\d)\\1+$/.test(value)) return 'Pick a PIN that is not one digit repeated.'\n const digits = [...value].map(Number)\n const step = (digits[1] ?? 0) - (digits[0] ?? 0)\n if (\n (step === 1 || step === -1) &&\n digits.every((digit, index) => index === 0 || digit - (digits[index - 1] ?? 0) === step)\n ) {\n return 'Pick a PIN that is not a straight run like 1234.'\n }\n return null\n}\n\n/*==========================================\n * THE THERMAL RECEIPT\n *=========================================*/\n\nexport interface PosReceiptLine {\n name: string\n variantLabel?: string\n quantity: number\n unitAmountCents: number\n lineCents: number\n}\n\nexport interface PosReceipt {\n storeName: string\n logoUrl?: string\n addressLines: string[]\n orderNumber: string\n /** The digits the barcode encodes and the register's return lookup reads. */\n barcodeValue: string\n dateLabel: string\n cashierName?: string\n registerName?: string\n customerName?: string\n lines: PosReceiptLine[]\n subtotalCents: number\n discountCents: number\n taxCents: number\n totalCents: number\n tipCents: number\n tenders: Array<{ label: string; amountCents: number }>\n changeCents: number\n refundedCents: number\n footer?: string\n returnPolicy?: string\n /** A gift receipt: the items and nothing about what they cost. */\n gift: boolean\n}\n\n/** The order fields a receipt prints. */\nexport interface PosReceiptOrder extends PosReturnSource {\n number?: number\n createdAtMs?: number\n customerName?: string | null\n lineItems?: Array<{\n name?: string\n variantLabel?: string\n unitAmountCents?: number\n quantity?: number\n }> | null\n}\n\n/**\n * The receipt for one sale, from the order alone plus what the store prints\n * on every receipt. The sale's lines, totals, tenders and change are the\n * receipt model's (`receiptDataFromOrder`, the one the cloud printers print\n * from), so a browser print and a cloud print never disagree; this adds the\n * logo, the address, the return policy and the gift receipt. A gift receipt\n * keeps the lines and the barcode — the recipient's way to return — and\n * drops every price, total and tender.\n */\nexport function buildPosReceipt(input: {\n orderId: string\n order: PosReceiptOrder\n store: {\n name: string\n logoUrl?: string\n address?: string\n footer?: string\n returnPolicy?: string\n }\n cashierName?: string\n registerName?: string\n gift?: boolean\n /** How the date prints; the register's own locale by default. */\n formatDate?: (ms: number) => string\n}): PosReceipt {\n const { order } = input\n const gift = input.gift === true\n const data = receiptDataFromOrder(input.orderId, order as unknown as HostOrder & Record<string, any>, {\n storeName: input.store.name,\n })\n const lines: PosReceiptLine[] = data.lines.map((line) => ({\n name: line.name,\n ...(line.detail ? { variantLabel: line.detail } : {}),\n quantity: line.quantity,\n unitAmountCents: gift ? 0 : line.unitCents,\n lineCents: gift ? 0 : line.totalCents,\n }))\n const number = Number(order.number)\n const digits = Number.isInteger(number) && number > 0 ? String(number) : ''\n const createdAtMs = Number(order.createdAtMs) || 0\n const formatDate =\n input.formatDate ?? ((ms: number) => (ms ? new Date(ms).toLocaleString() : ''))\n const money = (cents: number | undefined) => (gift ? 0 : wholeCents(cents))\n return {\n storeName: input.store.name,\n ...(input.store.logoUrl ? { logoUrl: input.store.logoUrl } : {}),\n addressLines: String(input.store.address ?? '')\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean),\n orderNumber: digits ? `#${digits}` : `#${input.orderId.slice(0, 8)}`,\n barcodeValue: digits || input.orderId,\n dateLabel: formatDate(createdAtMs),\n ...(input.cashierName ? { cashierName: input.cashierName } : {}),\n ...(input.registerName ? { registerName: input.registerName } : {}),\n ...(order.customerName ? { customerName: String(order.customerName) } : {}),\n lines,\n subtotalCents: money(data.subtotalCents),\n discountCents: money(data.discountCents),\n taxCents: money(data.taxCents),\n totalCents: money(data.totalCents),\n tipCents: money(data.tipCents),\n tenders: gift ? [] : (data.tenders ?? []),\n changeCents: money(data.changeCents),\n refundedCents: money(data.refundedCents),\n ...(input.store.footer ? { footer: input.store.footer } : {}),\n ...(input.store.returnPolicy ? { returnPolicy: input.store.returnPolicy } : {}),\n gift,\n }\n}\n\n/** One titled block of an X or Z report: what the screen, the browser print and a cloud printer all show. */\nexport interface PosShiftReportSection {\n section: string\n rows: Array<{ label: string; value: string; strong?: boolean }>\n}\n\n/** The rows of an X or Z report, in the order a manager reads them. */\nexport function posShiftReportRows(\n report: PosShiftReport,\n shift?: Pick<PosShift, 'countedCashCents' | 'varianceCents'>,\n): PosShiftReportSection[] {\n const tenders = POS_TENDER_METHODS.filter(\n (method) => (report.salesByTender[method] ?? 0) > 0 || (report.refundsByTender[method] ?? 0) > 0,\n )\n return [\n {\n section: 'Sales',\n rows: [\n { label: 'Orders', value: String(report.orderCount) },\n { label: 'Gross sales', value: posMoney(report.grossSalesCents) },\n { label: 'Discounts', value: posMoney(report.discountsCents) },\n { label: 'Tax', value: posMoney(report.taxCents) },\n { label: 'Tips', value: posMoney(report.tipsCents) },\n { label: `Refunds (${report.refundCount})`, value: `-${posMoney(report.refundsCents)}` },\n { label: 'Net sales', value: posMoney(report.netSalesCents), strong: true },\n ],\n },\n {\n section: 'By tender',\n rows: tenders.length\n ? tenders.map((method) => ({\n label: POS_TENDER_LABELS[method],\n value:\n posMoney(report.salesByTender[method] ?? 0) +\n ((report.refundsByTender[method] ?? 0) > 0\n ? ` (−${posMoney(report.refundsByTender[method] ?? 0)})`\n : ''),\n }))\n : [{ label: 'No sales yet', value: '' }],\n },\n {\n section: 'Cash drawer',\n rows: [\n { label: 'Starting cash', value: posMoney(report.openingFloatCents) },\n { label: 'Cash sales', value: posMoney(report.cashSalesCents) },\n { label: 'Paid in', value: posMoney(report.paidInCents) },\n { label: 'Paid out', value: `-${posMoney(report.paidOutCents)}` },\n { label: 'Safe drops', value: `-${posMoney(report.dropsCents)}` },\n { label: 'Cash refunds', value: `-${posMoney(report.cashRefundsCents)}` },\n { label: 'Expected in drawer', value: posMoney(report.expectedCashCents), strong: true },\n ...(shift?.countedCashCents != null\n ? [\n { label: 'Counted', value: posMoney(shift.countedCashCents) },\n {\n label: (shift.varianceCents ?? 0) < 0 ? 'Short' : (shift.varianceCents ?? 0) > 0 ? 'Over' : 'Balanced',\n value: posMoney(shift.varianceCents ?? 0),\n strong: true,\n },\n ]\n : []),\n ],\n },\n ]\n}\n\n/** A shift's X or Z report as the receipt printer prints it. */\nexport function posShiftPrintReport(input: {\n title: 'X REPORT' | 'Z REPORT'\n storeName: string\n registerName?: string\n report: PosShiftReport\n shift?: Pick<PosShift, 'countedCashCents' | 'varianceCents'>\n subtitle?: string\n}): PrintReport {\n return {\n title: input.title,\n storeName: input.storeName,\n ...(input.subtitle || input.registerName\n ? { subtitle: [input.registerName, input.subtitle].filter(Boolean).join(' - ') }\n : {}),\n sections: posShiftReportRows(input.report, input.shift),\n }\n}\n"],"names":["apportionCents","orderPayments","receiptDataFromOrder","POS_TENDER_METHODS","POS_TENDER_LABELS","cash","card_present","card_keyed","card_link","gift_card","folio","credit","POS_STRIPE_TENDERS","Set","wholeCents","value","number","Math","round","Number","isFinite","isTenderMethod","includes","posOrderTenders","order","filter","payment","status","method","map","id","amountCents","tipCents","totals","paymentIntentId","giftCardId","reservationId","creditProviderId","creditReference","creditLabel","cardBrand","last4","cashTenderedCents","changeCents","posTenderLabel","tender","base","capitalize","charAt","toUpperCase","slice","POS_CASH_EVENT_LABELS","paid_in","paid_out","drop","refund","posCashEventTotals","events","sum","type","event","reduce","total","paidInCents","paidOutCents","dropsCents","cashRefundsCents","posExpectedCashCents","input","openingFloatCents","cashSalesCents","computePosShiftReport","salesByTender","refundsByTender","orderCount","grossSalesCents","discountsCents","taxCents","tipsCents","sale","sales","tenders","totalCents","discountCents","tenderTips","max","refundsCents","refunds","refundedCents","shift","cashEvents","refundCount","length","netSalesCents","expectedCashCents","truncated","posCashVarianceCents","countedCashCents","posMoney","cents","abs","toFixed","csvCell","cell","String","test","replace","posCsvCell","dollars","posShiftsCsv","shifts","memberName","uid","header","iso","ms","Date","toISOString","rows","report","card","undefined","registerName","registerId","openedAtMs","openedByName","openedBy","closedAtMs","closedBy","closedByName","varianceCents","row","join","posReturnLineValues","lines","lineItems","gross","line","unitAmountCents","quantity","discountShares","net","index","taxShares","posReturnedQuantities","wholeLines","refundedLineItemIds","has","returned","returnedQuantities","min","planPosReturn","picks","heldElsewhere","ok","error","values","seen","lineCents","nextReturned","count","entries","completedLines","pick","isInteger","add","already","held","left","name","push","remaining","asked","refundCents","posRefundableByTender","attributed","Object","posPaymentRefunds","unattributed","ordered","sort","a","b","refundable","Map","taken","set","refundableCents","get","REFUND_ORDER","splitPosRefund","requested","amount","allocations","used","find","candidate","paymentId","indexOf","POS_CASHIER_ASSERTION_TTL_MS","POS_MANAGER_ASSERTION_TTL_MS","POS_PIN_MAX_ATTEMPTS","POS_PIN_LOCKOUT_MS","posPinProblem","pin","digits","step","every","digit","buildPosReceipt","data","gift","orderId","storeName","store","detail","variantLabel","unitCents","createdAtMs","formatDate","toLocaleString","money","logoUrl","addressLines","address","split","trim","Boolean","orderNumber","barcodeValue","dateLabel","cashierName","customerName","subtotalCents","footer","returnPolicy","posShiftReportRows","section","label","strong","posShiftPrintReport","title","subtitle","sections"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/model/commerce-pos-ops.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\nimport { apportionCents, type HostOrder } from './commerce-orders'\nimport { withPosHardwareReceiptNotice } from './pos-hardware-terms'\nimport { orderPayments } from './commerce-pos'\nimport type { PrintReport } from './commerce-printers'\nimport { receiptDataFromOrder } from './commerce-receipt'\n\n/*==========================================\n * RUNNING THE REGISTER (AGL-3609): shifts and the cash drawer, register\n * returns and the receipt. Pure and client-safe: the routes, the register\n * and the reports all compute from these, so a drawer's expected cash is one\n * formula wherever it is shown.\n *\n * Where each thing lives:\n *\n * hosts/{hostId}/registers/{registerId}\n * `openShiftId` — the one open shift, claimed in a transaction\n * hosts/{hostId}/registers/{registerId}/shifts/{shiftId} {@link PosShift}\n * hosts/{hostId}/registers/{registerId}/returns/{returnId} {@link PosRegisterReturn}\n * hosts/{hostId}/posStaffPins/{uid} server-only\n *\n * Everything under `registers` is written by the Admin SDK only (the\n * register pool is billed), and every member of the site may read it.\n *=========================================*/\n\n/** How one payment toward a sale was taken, in the register's tender words. */\nexport type PosTenderMethod =\n | 'cash'\n | 'card_present'\n | 'card_keyed'\n | 'card_link'\n | 'gift_card'\n | 'folio'\n /** Store credit another plugin keeps (AGL-3640). */\n | 'credit'\n\nexport const POS_TENDER_METHODS: readonly PosTenderMethod[] = [\n 'cash',\n 'card_present',\n 'card_keyed',\n 'card_link',\n 'gift_card',\n 'folio',\n 'credit',\n]\n\n/** What each tender is called on a report, a receipt and a refund. */\nexport const POS_TENDER_LABELS: Readonly<Record<PosTenderMethod, string>> = {\n cash: 'Cash',\n card_present: 'Card',\n card_keyed: 'Card (keyed)',\n card_link: 'Card (payment link)',\n gift_card: 'Gift card',\n folio: 'Room charge',\n credit: 'Store credit',\n}\n\n/** The tenders whose money moved through Stripe and goes back through it. */\nexport const POS_STRIPE_TENDERS: ReadonlySet<PosTenderMethod> = new Set([\n 'card_present',\n 'card_keyed',\n 'card_link',\n])\n\n/**\n * One settled payment toward a sale, as the shift report and a register\n * return read it.\n */\nexport interface PosOrderTender {\n /** The payment's id on the order, or `legacy` for an order before the tender ledger. */\n id: string\n method: PosTenderMethod\n /** Cents put toward the sale; never the tip, never the change. */\n amountCents: number\n tipCents: number\n paymentIntentId?: string\n giftCardId?: string\n reservationId?: string\n /** For `credit` (AGL-3640): the provider, its account handle, and its name. */\n creditProviderId?: string\n creditReference?: string\n creditLabel?: string\n cardBrand?: string\n last4?: string\n cashTenderedCents?: number\n changeCents?: number\n}\n\nconst wholeCents = (value: unknown): number => {\n const number = Math.round(Number(value))\n return Number.isFinite(number) && number > 0 ? number : 0\n}\n\n\nconst isTenderMethod = (value: unknown): value is PosTenderMethod =>\n typeof value === 'string' && (POS_TENDER_METHODS as readonly string[]).includes(value)\n\n/** The order fields the tender reader looks at. */\nexport interface PosTenderSource {\n payments?: unknown\n channel?: string\n status?: string\n totals?: { totalCents?: number; tipCents?: number } | null\n amountCents?: number\n reservationId?: string\n checkoutSessionId?: string\n paymentIntentId?: string\n}\n\n/**\n * THE ONE PLACE THE TENDER LEDGER IS READ (AGL-3609).\n *\n * A register sale may carry `payments[]` — one entry per tender, the ledger\n * the split-tender register writes (AGL-3607) — and only the payments that\n * SUCCEEDED count: a declined card or a voided gift card took nothing. An\n * order written before that ledger is one payment, inferred the way the\n * ledger's own reader infers it: a folio when it names a reservation, a card\n * link when Stripe saw it (or it came through the storefront), cash otherwise.\n *\n * The ledger's own reader (`orderPayments`) does both; this narrows it to the\n * settled payments and the fields a report or a refund reads.\n */\nexport function posOrderTenders(order: PosTenderSource | null | undefined): PosOrderTender[] {\n if (!order) return []\n return orderPayments(order as Parameters<typeof orderPayments>[0])\n .filter((payment) => payment.status === 'succeeded' && isTenderMethod(payment.method))\n .map((payment) => ({\n id: payment.id,\n method: payment.method as PosTenderMethod,\n amountCents: wholeCents(payment.amountCents),\n tipCents: wholeCents(payment.tipCents ?? (payment.id === 'legacy' ? order.totals?.tipCents : 0)),\n ...(payment.paymentIntentId ? { paymentIntentId: payment.paymentIntentId } : {}),\n ...(payment.giftCardId ? { giftCardId: payment.giftCardId } : {}),\n ...(payment.reservationId ? { reservationId: payment.reservationId } : {}),\n ...(payment.creditProviderId ? { creditProviderId: payment.creditProviderId } : {}),\n ...(payment.creditReference ? { creditReference: payment.creditReference } : {}),\n ...(payment.creditLabel ? { creditLabel: payment.creditLabel } : {}),\n ...(payment.cardBrand ? { cardBrand: payment.cardBrand } : {}),\n ...(payment.last4 ? { last4: payment.last4 } : {}),\n ...(payment.cashTenderedCents != null ? { cashTenderedCents: wholeCents(payment.cashTenderedCents) } : {}),\n ...(payment.changeCents != null ? { changeCents: wholeCents(payment.changeCents) } : {}),\n }))\n}\n\n/** A tender as one line of a receipt: `Card •• 4242`. */\nexport function posTenderLabel(\n tender: Pick<PosOrderTender, 'method' | 'cardBrand' | 'last4'> & { creditLabel?: string },\n): string {\n const base = (tender.method === 'credit' && tender.creditLabel) || POS_TENDER_LABELS[tender.method] || tender.method\n if (tender.last4) {\n return `${tender.cardBrand ? capitalize(tender.cardBrand) : base} •• ${tender.last4}`\n }\n return base\n}\n\nfunction capitalize(value: string): string {\n return value ? value.charAt(0).toUpperCase() + value.slice(1) : value\n}\n\n/*==========================================\n * SHIFTS AND THE CASH DRAWER\n *=========================================*/\n\n/**\n * Cash that moved through the drawer without a sale: money put in, money\n * paid out for a reason (a delivery, petty cash), a drop to the safe, and\n * a register return paid out in cash.\n */\nexport type PosCashEventType = 'paid_in' | 'paid_out' | 'drop' | 'refund'\n\nexport const POS_CASH_EVENT_LABELS: Readonly<Record<PosCashEventType, string>> = {\n paid_in: 'Paid in',\n paid_out: 'Paid out',\n drop: 'Safe drop',\n refund: 'Cash refund',\n}\n\nexport interface PosCashEvent {\n /** The register's attempt id, so a retried tap records one event. */\n id: string\n type: PosCashEventType\n amountCents: number\n reason: string\n /** The member who moved the cash. */\n by: string\n atMs: number\n /** The order a `refund` paid out against. */\n orderId?: string\n}\n\n/** Sales, refunds and cash movements over one shift. */\nexport interface PosShiftReport {\n orderCount: number\n /** What customers paid for the goods: order totals, tax in, tips out. */\n grossSalesCents: number\n discountsCents: number\n taxCents: number\n tipsCents: number\n salesByTender: Partial<Record<PosTenderMethod, number>>\n refundCount: number\n refundsCents: number\n refundsByTender: Partial<Record<PosTenderMethod, number>>\n /** Gross sales less refunds. */\n netSalesCents: number\n openingFloatCents: number\n cashSalesCents: number\n paidInCents: number\n paidOutCents: number\n dropsCents: number\n cashRefundsCents: number\n /** float + cash sales + paid in − paid out − drops − cash refunds. */\n expectedCashCents: number\n /** More sales were stamped with the shift than the report could read. */\n truncated?: boolean\n}\n\n/** `hosts/{hostId}/registers/{registerId}/shifts/{shiftId}`. */\nexport interface PosShift {\n hostId: string\n registerId: string\n status: 'open' | 'closed'\n openedBy: string\n /** The member's name when the shift opened, for the history and the export. */\n openedByName?: string\n openedAtMs: number\n openingFloatCents: number\n cashEvents: PosCashEvent[]\n closedBy?: string\n closedByName?: string\n /*\n * The history sorts by each of the five below (AGL-3680), and an `orderBy`\n * drops a shift that lacks the field, so the shift is opened with each one\n * `null` and the close fills them — see `POS_SHIFT_LIST_QUERY`.\n */\n closedAtMs?: number | null\n /** What the closing cashier counted in the drawer. */\n countedCashCents?: number | null\n expectedCashCents?: number | null\n /** counted − expected: positive is over, negative is short. */\n varianceCents?: number | null\n /** The Z report's `netSalesCents`, flattened so the history can order by it. */\n netSalesCents?: number | null\n closingNote?: string\n /** The Z report, frozen when the shift closed. */\n report?: PosShiftReport\n}\n\n/** The cash-event sums one formula reads. */\nexport function posCashEventTotals(events: readonly PosCashEvent[] | null | undefined): {\n paidInCents: number\n paidOutCents: number\n dropsCents: number\n cashRefundsCents: number\n} {\n const sum = (type: PosCashEventType) =>\n (events ?? [])\n .filter((event) => event?.type === type)\n .reduce((total, event) => total + wholeCents(event.amountCents), 0)\n return {\n paidInCents: sum('paid_in'),\n paidOutCents: sum('paid_out'),\n dropsCents: sum('drop'),\n cashRefundsCents: sum('refund'),\n }\n}\n\n/**\n * THE DRAWER'S EXPECTED CASH: what should be in it when it is counted.\n *\n * opening float + cash sales + paid in − paid out − safe drops − cash refunds\n *\n * Cash SALES are the cash tender's `amountCents`, which is what the sale took\n * and never what the customer handed over: the change went straight back out\n * of the same drawer. A tip left in cash is in the drawer too, so it counts.\n */\nexport function posExpectedCashCents(input: {\n openingFloatCents: number\n cashSalesCents: number\n paidInCents: number\n paidOutCents: number\n dropsCents: number\n cashRefundsCents: number\n}): number {\n return (\n wholeCents(input.openingFloatCents) +\n wholeCents(input.cashSalesCents) +\n wholeCents(input.paidInCents) -\n wholeCents(input.paidOutCents) -\n wholeCents(input.dropsCents) -\n wholeCents(input.cashRefundsCents)\n )\n}\n\n/** A sale as the shift report reads it. */\nexport interface PosShiftSale extends PosTenderSource {\n totals?: {\n totalCents?: number\n discountCents?: number\n taxCents?: number\n tipCents?: number\n } | null\n}\n\n/** A register return as the shift report reads it. */\nexport interface PosShiftRefund {\n refundedCents: number\n tenders: Array<{ method: PosTenderMethod; amountCents: number }>\n}\n\n/**\n * The X report (mid-shift) and the Z report (at close) are this one function\n * over the sales stamped with the shift, the returns rung at the register\n * during it and the shift's own cash events. A pending sale took no money and\n * a cancelled one gave it back, so neither counts; a sale refunded LATER\n * still counts as a sale, and its refund is counted where it was paid out.\n */\nexport function computePosShiftReport(input: {\n shift: Pick<PosShift, 'openingFloatCents' | 'cashEvents'>\n sales: readonly PosShiftSale[]\n refunds: readonly PosShiftRefund[]\n truncated?: boolean\n}): PosShiftReport {\n const salesByTender: Partial<Record<PosTenderMethod, number>> = {}\n const refundsByTender: Partial<Record<PosTenderMethod, number>> = {}\n let orderCount = 0\n let grossSalesCents = 0\n let discountsCents = 0\n let taxCents = 0\n let tipsCents = 0\n let cashSalesCents = 0\n for (const sale of input.sales) {\n if (sale.status === 'pending' || sale.status === 'cancelled') continue\n const tenders = posOrderTenders(sale)\n orderCount += 1\n grossSalesCents += wholeCents(sale.totals?.totalCents ?? sale.amountCents)\n discountsCents += wholeCents(sale.totals?.discountCents)\n taxCents += wholeCents(sale.totals?.taxCents)\n const tenderTips = tenders.reduce((sum, tender) => sum + tender.tipCents, 0)\n tipsCents += Math.max(wholeCents(sale.totals?.tipCents), tenderTips)\n for (const tender of tenders) {\n salesByTender[tender.method] = (salesByTender[tender.method] ?? 0) + tender.amountCents\n if (tender.method === 'cash') cashSalesCents += tender.amountCents + tender.tipCents\n }\n }\n let refundsCents = 0\n for (const refund of input.refunds) {\n refundsCents += wholeCents(refund.refundedCents)\n for (const tender of refund.tenders ?? []) {\n if (!isTenderMethod(tender.method)) continue\n refundsByTender[tender.method] =\n (refundsByTender[tender.method] ?? 0) + wholeCents(tender.amountCents)\n }\n }\n const cash = posCashEventTotals(input.shift.cashEvents)\n const openingFloatCents = wholeCents(input.shift.openingFloatCents)\n return {\n orderCount,\n grossSalesCents,\n discountsCents,\n taxCents,\n tipsCents,\n salesByTender,\n refundCount: input.refunds.length,\n refundsCents,\n refundsByTender,\n netSalesCents: grossSalesCents - refundsCents,\n openingFloatCents,\n cashSalesCents,\n ...cash,\n expectedCashCents: posExpectedCashCents({ openingFloatCents, cashSalesCents, ...cash }),\n ...(input.truncated ? { truncated: true } : {}),\n }\n}\n\n/** counted − expected; positive is over, negative is short. */\nexport function posCashVarianceCents(countedCashCents: number, expectedCashCents: number): number {\n return Math.round(Number(countedCashCents) || 0) - Math.round(Number(expectedCashCents) || 0)\n}\n\n/** `$12.34`, `-$0.50` — the register's money format, store currency USD. */\nexport function posMoney(cents: number): string {\n const value = Math.round(Number(cents) || 0)\n return `${value < 0 ? '-' : ''}$${(Math.abs(value) / 100).toFixed(2)}`\n}\n\n/** One CSV cell, quoted when it needs to be and never read as a formula. */\nfunction csvCell(value: unknown): string {\n let cell = value == null ? '' : String(value)\n if (/^[=+\\-@\\t\\r]/.test(cell) && !/^-?\\d+(\\.\\d+)?$/.test(cell)) cell = `'${cell}`\n return /[\",\\r\\n]/.test(cell) ? `\"${cell.replace(/\"/g, '\"\"')}\"` : cell\n}\n\nexport { csvCell as posCsvCell }\n\nconst dollars = (cents: number | null | undefined): string =>\n cents == null ? '' : (Math.round(cents) / 100).toFixed(2)\n\n/** The shift history as a spreadsheet: one row per shift, money in dollars. */\nexport function posShiftsCsv(\n shifts: ReadonlyArray<PosShift & { id: string; registerName?: string }>,\n memberName: (uid: string) => string = (uid) => uid,\n): string {\n const header = [\n 'Shift',\n 'Register',\n 'Opened',\n 'Opened by',\n 'Closed',\n 'Closed by',\n 'Orders',\n 'Gross sales',\n 'Refunds',\n 'Net sales',\n 'Discounts',\n 'Tax',\n 'Tips',\n 'Cash sales',\n 'Card sales',\n 'Gift card sales',\n 'Room charges',\n 'Opening float',\n 'Paid in',\n 'Paid out',\n 'Safe drops',\n 'Cash refunds',\n 'Expected cash',\n 'Counted cash',\n 'Variance',\n ]\n const iso = (ms: number | null | undefined) => (ms ? new Date(ms).toISOString() : '')\n const rows = shifts.map((shift) => {\n const report = shift.report\n const card = report\n ? (report.salesByTender.card_present ?? 0) +\n (report.salesByTender.card_keyed ?? 0) +\n (report.salesByTender.card_link ?? 0)\n : undefined\n return [\n shift.id,\n shift.registerName ?? shift.registerId,\n iso(shift.openedAtMs),\n shift.openedByName ?? memberName(shift.openedBy),\n iso(shift.closedAtMs),\n shift.closedBy ? (shift.closedByName ?? memberName(shift.closedBy)) : '',\n report?.orderCount ?? '',\n dollars(report?.grossSalesCents),\n dollars(report?.refundsCents),\n dollars(report?.netSalesCents),\n dollars(report?.discountsCents),\n dollars(report?.taxCents),\n dollars(report?.tipsCents),\n dollars(report?.cashSalesCents),\n dollars(card),\n dollars(report ? (report.salesByTender.gift_card ?? 0) : undefined),\n dollars(report ? (report.salesByTender.folio ?? 0) : undefined),\n dollars(shift.openingFloatCents),\n dollars(report?.paidInCents),\n dollars(report?.paidOutCents),\n dollars(report?.dropsCents),\n dollars(report?.cashRefundsCents),\n dollars(shift.expectedCashCents ?? report?.expectedCashCents),\n dollars(shift.countedCashCents),\n dollars(shift.varianceCents),\n ]\n })\n return [header, ...rows].map((row) => row.map(csvCell).join(',')).join('\\r\\n')\n}\n\n/*==========================================\n * RETURNS AT THE REGISTER\n *=========================================*/\n\n/** One line picked for return: its index on the order and how many units. */\nexport interface PosReturnPick {\n index: number\n quantity: number\n}\n\n/** The order fields a return reads. */\nexport interface PosReturnSource extends PosTenderSource {\n lineItems?: Array<{ unitAmountCents?: number; quantity?: number; name?: string }> | null\n totals?: {\n totalCents?: number\n discountCents?: number\n taxCents?: number\n shippingCents?: number\n tipCents?: number\n } | null\n refundedCents?: number\n refundedLineItemIds?: number[]\n /** Units of each line already returned at a register, by line index. */\n returnedQuantities?: Record<string, number>\n /** Cents already refunded to each payment by a register return. */\n posPaymentRefunds?: Record<string, number>\n}\n\n/**\n * What each line is worth back, whole: its price less its share of the\n * order's discount, plus its share of the order's tax — the same\n * apportionment `orderLineRefundCents` uses for the discount, extended to the\n * tax a register sale charged on top. Shipping and tips are not a line's.\n */\nexport function posReturnLineValues(order: PosReturnSource): number[] {\n const lines = order.lineItems ?? []\n const gross = lines.map(\n (line) =>\n Math.max(0, Math.round(Number(line?.unitAmountCents ?? 0))) *\n Math.max(1, Math.round(Number(line?.quantity ?? 1))),\n )\n const discountShares = apportionCents(gross, wholeCents(order.totals?.discountCents))\n const net = gross.map((cents, index) => Math.max(0, cents - (discountShares[index] ?? 0)))\n const taxShares = apportionCents(net, wholeCents(order.totals?.taxCents))\n return net.map((cents, index) => cents + (taxShares[index] ?? 0))\n}\n\n/** Units of each line already returned, a line refunded whole counting as all of it. */\nexport function posReturnedQuantities(order: PosReturnSource): number[] {\n const lines = order.lineItems ?? []\n const wholeLines = new Set(order.refundedLineItemIds ?? [])\n return lines.map((line, index) => {\n const quantity = Math.max(1, Math.round(Number(line?.quantity ?? 1)))\n if (wholeLines.has(index)) return quantity\n const returned = Math.round(Number(order.returnedQuantities?.[String(index)] ?? 0))\n return Math.min(quantity, Math.max(0, Number.isFinite(returned) ? returned : 0))\n })\n}\n\nexport type PosReturnPlan =\n | {\n ok: true\n refundCents: number\n /** Cents per picked line, in the order picked. */\n lineCents: number[]\n /** The order's per-line returned quantities after this return. */\n returnedQuantities: Record<string, number>\n /** Lines this return finishes, for `refundedLineItemIds`. */\n completedLines: number[]\n }\n | { ok: false; error: string }\n\n/**\n * What a return of these picks refunds, to the cent.\n *\n * Each line's value is split across its units CUMULATIVELY: returning `k` of\n * `n` units already returned `r` refunds `round(V·(r+k)/n) − round(V·r/n)`,\n * so returning a line one unit at a time refunds exactly what returning it\n * whole would have, and the rounding never strands or invents a cent. The\n * sum is capped at what is left to refund on the order — a refund given\n * from the order dialog already took its share.\n *\n * `heldElsewhere` is, per line, the units an online return (the returns\n * flow) already holds or took back. They cap what the register may take, but\n * they are not written into `returnedQuantities`, which counts only what the\n * register itself took.\n */\nexport function planPosReturn(\n order: PosReturnSource,\n picks: readonly PosReturnPick[],\n heldElsewhere: readonly number[] = [],\n): PosReturnPlan {\n const lines = order.lineItems ?? []\n if (!picks.length) return { ok: false, error: 'Pick at least one item to return.' }\n const values = posReturnLineValues(order)\n const returned = posReturnedQuantities(order)\n const seen = new Set<number>()\n const lineCents: number[] = []\n const nextReturned: Record<string, number> = {}\n for (const [index, count] of returned.entries()) if (count > 0) nextReturned[String(index)] = count\n const completedLines: number[] = []\n for (const pick of picks) {\n const index = Number(pick.index)\n const quantity = Number(pick.quantity)\n if (!Number.isInteger(index) || index < 0 || index >= lines.length) {\n return { ok: false, error: `Line ${pick.index} is not on this order.` }\n }\n if (seen.has(index)) return { ok: false, error: 'Each line can be picked once.' }\n seen.add(index)\n if (!Number.isInteger(quantity) || quantity < 1) {\n return { ok: false, error: 'Return at least one of each line you pick.' }\n }\n const total = Math.max(1, Math.round(Number(lines[index]?.quantity ?? 1)))\n const already = returned[index] ?? 0\n const held = Math.max(0, Math.round(Number(heldElsewhere[index] ?? 0)))\n if (already + held + quantity > total) {\n const left = Math.max(0, total - already - held)\n return {\n ok: false,\n error:\n left > 0\n ? `Only ${left} of \"${lines[index]?.name ?? 'that item'}\" can still be returned.`\n : held > 0\n ? `\"${lines[index]?.name ?? 'That item'}\" is already in a return. Finish it under Returns.`\n : `\"${lines[index]?.name ?? 'That item'}\" has already been returned.`,\n }\n }\n const value = values[index] ?? 0\n lineCents.push(\n Math.round((value * (already + quantity)) / total) - Math.round((value * already) / total),\n )\n nextReturned[String(index)] = already + quantity\n if (already + quantity === total) completedLines.push(index)\n }\n const remaining = Math.max(\n 0,\n wholeCents(order.totals?.totalCents) - wholeCents(order.refundedCents),\n )\n const asked = lineCents.reduce((sum, cents) => sum + cents, 0)\n const refundCents = Math.min(asked, remaining)\n if (!(refundCents > 0)) return { ok: false, error: 'Nothing is left to refund on this order.' }\n return { ok: true, refundCents, lineCents, returnedQuantities: nextReturned, completedLines }\n}\n\n/** One slice of a refund, sent back to one of the sale's payments. */\nexport interface PosRefundAllocation {\n paymentId: string\n method: PosTenderMethod\n amountCents: number\n}\n\n/**\n * What each payment can still take back: what it put toward the sale, less\n * what register returns already sent to it. A refund given from the order\n * dialog refunds through Stripe without naming a payment, so whatever it\n * took that no payment accounts for comes off the Stripe payments first.\n */\nexport function posRefundableByTender(order: PosReturnSource): Array<PosOrderTender & { refundableCents: number }> {\n const tenders = posOrderTenders(order)\n const attributed = Object.values(order.posPaymentRefunds ?? {}).reduce(\n (sum, cents) => sum + wholeCents(cents),\n 0,\n )\n let unattributed = Math.max(0, wholeCents(order.refundedCents) - attributed)\n const ordered = [...tenders].sort(\n (a, b) => Number(POS_STRIPE_TENDERS.has(b.method)) - Number(POS_STRIPE_TENDERS.has(a.method)),\n )\n const refundable = new Map<string, number>()\n for (const tender of ordered) {\n let left = Math.max(0, tender.amountCents - wholeCents(order.posPaymentRefunds?.[tender.id]))\n if (POS_STRIPE_TENDERS.has(tender.method) && unattributed > 0) {\n const taken = Math.min(left, unattributed)\n left -= taken\n unattributed -= taken\n }\n refundable.set(tender.id, left)\n }\n return tenders.map((tender) => ({ ...tender, refundableCents: refundable.get(tender.id) ?? 0 }))\n}\n\n/**\n * The order a refund goes back in, when the cashier does not split it by\n * hand: the cards first, then store credit, then the room, and the drawer\n * LAST — so cash leaves the till only for what the customer paid in cash.\n */\nconst REFUND_ORDER: readonly PosTenderMethod[] = [\n 'card_present',\n 'card_keyed',\n 'card_link',\n 'gift_card',\n 'credit',\n 'folio',\n 'cash',\n]\n\nexport type PosRefundSplit =\n | { ok: true; allocations: PosRefundAllocation[] }\n | { ok: false; error: string }\n\n/**\n * Sends `amountCents` back to the sale's own payments.\n *\n * With no `requested` split, each payment takes what it can in\n * {@link REFUND_ORDER}. With one, every slice must name a payment of this\n * sale and fit what that payment can still take, and the slices must add up\n * to the refund exactly — a refund is never sent to a tender the sale was\n * not paid with.\n */\nexport function splitPosRefund(\n order: PosReturnSource,\n amountCents: number,\n requested?: ReadonlyArray<{ paymentId: string; amountCents: number }> | null,\n): PosRefundSplit {\n const amount = wholeCents(amountCents)\n const tenders = posRefundableByTender(order)\n if (!tenders.length) return { ok: false, error: 'This order has no payment to refund to.' }\n if (requested && requested.length) {\n const allocations: PosRefundAllocation[] = []\n const used = new Set<string>()\n for (const slice of requested) {\n const tender = tenders.find((candidate) => candidate.id === slice.paymentId)\n if (!tender) return { ok: false, error: 'That payment is not on this order.' }\n if (used.has(tender.id)) return { ok: false, error: 'Each payment can be named once.' }\n used.add(tender.id)\n const cents = Math.round(Number(slice.amountCents))\n if (!Number.isFinite(cents) || cents < 0) return { ok: false, error: 'Refund amounts must be positive.' }\n if (cents === 0) continue\n if (cents > tender.refundableCents) {\n return {\n ok: false,\n error: `${posTenderLabel(tender)} can take back at most ${posMoney(tender.refundableCents)}.`,\n }\n }\n allocations.push({ paymentId: tender.id, method: tender.method, amountCents: cents })\n }\n const total = allocations.reduce((sum, slice) => sum + slice.amountCents, 0)\n if (total !== amount) {\n return {\n ok: false,\n error: `The refund is ${posMoney(amount)}; the split adds up to ${posMoney(total)}.`,\n }\n }\n return { ok: true, allocations }\n }\n const ordered = [...tenders].sort(\n (a, b) => REFUND_ORDER.indexOf(a.method) - REFUND_ORDER.indexOf(b.method),\n )\n const allocations: PosRefundAllocation[] = []\n let left = amount\n for (const tender of ordered) {\n if (!(left > 0)) break\n const cents = Math.min(left, tender.refundableCents)\n if (!(cents > 0)) continue\n allocations.push({ paymentId: tender.id, method: tender.method, amountCents: cents })\n left -= cents\n }\n if (left > 0) {\n return {\n ok: false,\n error: `Only ${posMoney(amount - left)} can go back to this sale's payments.`,\n }\n }\n return { ok: true, allocations }\n}\n\n/** `hosts/{hostId}/registers/{registerId}/returns/{returnId}`. */\nexport interface PosRegisterReturn {\n hostId: string\n registerId: string\n orderId: string\n orderNumber?: number\n /** The shift the drawer was in when the return was rung, if one was open. */\n shiftId?: string\n lines: Array<{ index: number; quantity: number; name: string; refundCents: number }>\n refundedCents: number\n tenders: Array<PosRefundAllocation & { status: 'refunded' | 'failed'; refundId?: string; error?: string }>\n restocked: boolean\n locationId?: string\n /** The member at the register (by PIN or by sign-in). */\n cashierId: string\n /** The manager whose PIN allowed a refund above the cashier's limit. */\n approvedBy?: string\n reason?: string\n status: 'refunded' | 'partial'\n atMs: number\n}\n\n/*==========================================\n * STAFF PINS\n *=========================================*/\n\n/** How long a cashier PIN switch lasts before the register asks again. */\nexport const POS_CASHIER_ASSERTION_TTL_MS = 15 * 60 * 1000\n/** A manager's approval is for the one refund in front of them. */\nexport const POS_MANAGER_ASSERTION_TTL_MS = 2 * 60 * 1000\n/** Wrong PINs in a row before the member is locked out. */\nexport const POS_PIN_MAX_ATTEMPTS = 5\n/** How long a lockout lasts. */\nexport const POS_PIN_LOCKOUT_MS = 15 * 60 * 1000\n\n/**\n * Why a PIN cannot be used, or `null` when it can: 4 to 6 digits, and not\n * one a stranger tries first — every digit the same, or a straight run.\n */\nexport function posPinProblem(pin: unknown): string | null {\n const value = typeof pin === 'string' ? pin : ''\n if (!/^\\d{4,6}$/.test(value)) return 'A PIN is 4 to 6 digits.'\n if (/^(\\d)\\1+$/.test(value)) return 'Pick a PIN that is not one digit repeated.'\n const digits = [...value].map(Number)\n const step = (digits[1] ?? 0) - (digits[0] ?? 0)\n if (\n (step === 1 || step === -1) &&\n digits.every((digit, index) => index === 0 || digit - (digits[index - 1] ?? 0) === step)\n ) {\n return 'Pick a PIN that is not a straight run like 1234.'\n }\n return null\n}\n\n/*==========================================\n * THE THERMAL RECEIPT\n *=========================================*/\n\nexport interface PosReceiptLine {\n name: string\n variantLabel?: string\n quantity: number\n unitAmountCents: number\n lineCents: number\n}\n\nexport interface PosReceipt {\n storeName: string\n logoUrl?: string\n addressLines: string[]\n orderNumber: string\n /** The digits the barcode encodes and the register's return lookup reads. */\n barcodeValue: string\n dateLabel: string\n cashierName?: string\n registerName?: string\n customerName?: string\n lines: PosReceiptLine[]\n subtotalCents: number\n discountCents: number\n taxCents: number\n totalCents: number\n tipCents: number\n tenders: Array<{ label: string; amountCents: number }>\n changeCents: number\n refundedCents: number\n footer?: string\n returnPolicy?: string\n /** A gift receipt: the items and nothing about what they cost. */\n gift: boolean\n}\n\n/** The order fields a receipt prints. */\nexport interface PosReceiptOrder extends PosReturnSource {\n number?: number\n createdAtMs?: number\n customerName?: string | null\n lineItems?: Array<{\n name?: string\n variantLabel?: string\n unitAmountCents?: number\n quantity?: number\n }> | null\n}\n\n/**\n * The receipt for one sale, from the order alone plus what the store prints\n * on every receipt. The sale's lines, totals, tenders and change are the\n * receipt model's (`receiptDataFromOrder`, the one the cloud printers print\n * from), so a browser print and a cloud print never disagree; this adds the\n * logo, the address, the return policy and the gift receipt. A gift receipt\n * keeps the lines and the barcode — the recipient's way to return — and\n * drops every price, total and tender.\n */\nexport function buildPosReceipt(input: {\n orderId: string\n order: PosReceiptOrder\n store: {\n name: string\n logoUrl?: string\n address?: string\n footer?: string\n returnPolicy?: string\n }\n cashierName?: string\n registerName?: string\n gift?: boolean\n /** How the date prints; the register's own locale by default. */\n formatDate?: (ms: number) => string\n}): PosReceipt {\n const { order } = input\n const gift = input.gift === true\n const data = receiptDataFromOrder(input.orderId, order as unknown as HostOrder & Record<string, any>, {\n storeName: input.store.name,\n })\n const lines: PosReceiptLine[] = data.lines.map((line) => ({\n name: line.name,\n ...(line.detail ? { variantLabel: line.detail } : {}),\n quantity: line.quantity,\n unitAmountCents: gift ? 0 : line.unitCents,\n lineCents: gift ? 0 : line.totalCents,\n }))\n const number = Number(order.number)\n const digits = Number.isInteger(number) && number > 0 ? String(number) : ''\n const createdAtMs = Number(order.createdAtMs) || 0\n const formatDate =\n input.formatDate ?? ((ms: number) => (ms ? new Date(ms).toLocaleString() : ''))\n const money = (cents: number | undefined) => (gift ? 0 : wholeCents(cents))\n return {\n storeName: input.store.name,\n ...(input.store.logoUrl ? { logoUrl: input.store.logoUrl } : {}),\n addressLines: String(input.store.address ?? '')\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean),\n orderNumber: digits ? `#${digits}` : `#${input.orderId.slice(0, 8)}`,\n barcodeValue: digits || input.orderId,\n dateLabel: formatDate(createdAtMs),\n ...(input.cashierName ? { cashierName: input.cashierName } : {}),\n ...(input.registerName ? { registerName: input.registerName } : {}),\n ...(order.customerName ? { customerName: String(order.customerName) } : {}),\n lines,\n subtotalCents: money(data.subtotalCents),\n discountCents: money(data.discountCents),\n taxCents: money(data.taxCents),\n totalCents: money(data.totalCents),\n tipCents: money(data.tipCents),\n tenders: gift ? [] : (data.tenders ?? []),\n changeCents: money(data.changeCents),\n refundedCents: money(data.refundedCents),\n // A sale of card reader hardware prints the terms it is sold under\n // (AGL-4038, Terms 4.28), after the store's own footer.\n ...(withPosHardwareReceiptNotice(input.store.footer, order as Record<string, unknown>)\n ? { footer: withPosHardwareReceiptNotice(input.store.footer, order as Record<string, unknown>) }\n : {}),\n ...(input.store.returnPolicy ? { returnPolicy: input.store.returnPolicy } : {}),\n gift,\n }\n}\n\n/** One titled block of an X or Z report: what the screen, the browser print and a cloud printer all show. */\nexport interface PosShiftReportSection {\n section: string\n rows: Array<{ label: string; value: string; strong?: boolean }>\n}\n\n/** The rows of an X or Z report, in the order a manager reads them. */\nexport function posShiftReportRows(\n report: PosShiftReport,\n shift?: Pick<PosShift, 'countedCashCents' | 'varianceCents'>,\n): PosShiftReportSection[] {\n const tenders = POS_TENDER_METHODS.filter(\n (method) => (report.salesByTender[method] ?? 0) > 0 || (report.refundsByTender[method] ?? 0) > 0,\n )\n return [\n {\n section: 'Sales',\n rows: [\n { label: 'Orders', value: String(report.orderCount) },\n { label: 'Gross sales', value: posMoney(report.grossSalesCents) },\n { label: 'Discounts', value: posMoney(report.discountsCents) },\n { label: 'Tax', value: posMoney(report.taxCents) },\n { label: 'Tips', value: posMoney(report.tipsCents) },\n { label: `Refunds (${report.refundCount})`, value: `-${posMoney(report.refundsCents)}` },\n { label: 'Net sales', value: posMoney(report.netSalesCents), strong: true },\n ],\n },\n {\n section: 'By tender',\n rows: tenders.length\n ? tenders.map((method) => ({\n label: POS_TENDER_LABELS[method],\n value:\n posMoney(report.salesByTender[method] ?? 0) +\n ((report.refundsByTender[method] ?? 0) > 0\n ? ` (−${posMoney(report.refundsByTender[method] ?? 0)})`\n : ''),\n }))\n : [{ label: 'No sales yet', value: '' }],\n },\n {\n section: 'Cash drawer',\n rows: [\n { label: 'Starting cash', value: posMoney(report.openingFloatCents) },\n { label: 'Cash sales', value: posMoney(report.cashSalesCents) },\n { label: 'Paid in', value: posMoney(report.paidInCents) },\n { label: 'Paid out', value: `-${posMoney(report.paidOutCents)}` },\n { label: 'Safe drops', value: `-${posMoney(report.dropsCents)}` },\n { label: 'Cash refunds', value: `-${posMoney(report.cashRefundsCents)}` },\n { label: 'Expected in drawer', value: posMoney(report.expectedCashCents), strong: true },\n ...(shift?.countedCashCents != null\n ? [\n { label: 'Counted', value: posMoney(shift.countedCashCents) },\n {\n label: (shift.varianceCents ?? 0) < 0 ? 'Short' : (shift.varianceCents ?? 0) > 0 ? 'Over' : 'Balanced',\n value: posMoney(shift.varianceCents ?? 0),\n strong: true,\n },\n ]\n : []),\n ],\n },\n ]\n}\n\n/** A shift's X or Z report as the receipt printer prints it. */\nexport function posShiftPrintReport(input: {\n title: 'X REPORT' | 'Z REPORT'\n storeName: string\n registerName?: string\n report: PosShiftReport\n shift?: Pick<PosShift, 'countedCashCents' | 'varianceCents'>\n subtitle?: string\n}): PrintReport {\n return {\n title: input.title,\n storeName: input.storeName,\n ...(input.subtitle || input.registerName\n ? { subtitle: [input.registerName, input.subtitle].filter(Boolean).join(' - ') }\n : {}),\n sections: posShiftReportRows(input.report, input.shift),\n }\n}\n"],"names":["apportionCents","withPosHardwareReceiptNotice","orderPayments","receiptDataFromOrder","POS_TENDER_METHODS","POS_TENDER_LABELS","cash","card_present","card_keyed","card_link","gift_card","folio","credit","POS_STRIPE_TENDERS","Set","wholeCents","value","number","Math","round","Number","isFinite","isTenderMethod","includes","posOrderTenders","order","filter","payment","status","method","map","id","amountCents","tipCents","totals","paymentIntentId","giftCardId","reservationId","creditProviderId","creditReference","creditLabel","cardBrand","last4","cashTenderedCents","changeCents","posTenderLabel","tender","base","capitalize","charAt","toUpperCase","slice","POS_CASH_EVENT_LABELS","paid_in","paid_out","drop","refund","posCashEventTotals","events","sum","type","event","reduce","total","paidInCents","paidOutCents","dropsCents","cashRefundsCents","posExpectedCashCents","input","openingFloatCents","cashSalesCents","computePosShiftReport","salesByTender","refundsByTender","orderCount","grossSalesCents","discountsCents","taxCents","tipsCents","sale","sales","tenders","totalCents","discountCents","tenderTips","max","refundsCents","refunds","refundedCents","shift","cashEvents","refundCount","length","netSalesCents","expectedCashCents","truncated","posCashVarianceCents","countedCashCents","posMoney","cents","abs","toFixed","csvCell","cell","String","test","replace","posCsvCell","dollars","posShiftsCsv","shifts","memberName","uid","header","iso","ms","Date","toISOString","rows","report","card","undefined","registerName","registerId","openedAtMs","openedByName","openedBy","closedAtMs","closedBy","closedByName","varianceCents","row","join","posReturnLineValues","lines","lineItems","gross","line","unitAmountCents","quantity","discountShares","net","index","taxShares","posReturnedQuantities","wholeLines","refundedLineItemIds","has","returned","returnedQuantities","min","planPosReturn","picks","heldElsewhere","ok","error","values","seen","lineCents","nextReturned","count","entries","completedLines","pick","isInteger","add","already","held","left","name","push","remaining","asked","refundCents","posRefundableByTender","attributed","Object","posPaymentRefunds","unattributed","ordered","sort","a","b","refundable","Map","taken","set","refundableCents","get","REFUND_ORDER","splitPosRefund","requested","amount","allocations","used","find","candidate","paymentId","indexOf","POS_CASHIER_ASSERTION_TTL_MS","POS_MANAGER_ASSERTION_TTL_MS","POS_PIN_MAX_ATTEMPTS","POS_PIN_LOCKOUT_MS","posPinProblem","pin","digits","step","every","digit","buildPosReceipt","data","gift","orderId","storeName","store","detail","variantLabel","unitCents","createdAtMs","formatDate","toLocaleString","money","logoUrl","addressLines","address","split","trim","Boolean","orderNumber","barcodeValue","dateLabel","cashierName","customerName","subtotalCents","footer","returnPolicy","posShiftReportRows","section","label","strong","posShiftPrintReport","title","subtitle","sections"],"mappings":"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"}
@@ -222,7 +222,13 @@ export type PosDisplayMode = 'idle'
222
222
  /** The customer picks how they want their receipt. */
223
223
  | 'receipt'
224
224
  /** A card payment is waiting on the reader. */
225
- | 'processing' | 'thanks';
225
+ | 'processing' | 'thanks'
226
+ /**
227
+ * Another plugin's screen (AGL-4042), asked for through core's customer
228
+ * display seam (`plugin-customer-display`): the display opens that
229
+ * plugin's public page, which sends it back here when the customer is done.
230
+ */
231
+ | 'screen';
226
232
  export type PosReceiptChannel = 'email' | 'sms' | 'print' | 'none';
227
233
  export interface PosDisplayLine {
228
234
  name: string;
@@ -280,8 +286,28 @@ export interface PosDisplayState {
280
286
  processing?: {
281
287
  message: string;
282
288
  };
289
+ /** The plugin page a `screen` state opens, as core's seam shapes it. */
290
+ screen?: PosDisplayScreen;
291
+ /**
292
+ * The staff member (uid) who put {@link screen} on the display (AGL-4042),
293
+ * stamped by the server from the session that pushed it, never taken from
294
+ * the register's body. Core's display verifier names them to the screen's
295
+ * plugin, whose record of what the customer did there names who showed it.
296
+ * Never sent to the display.
297
+ */
298
+ screenShownBy?: string;
283
299
  response?: PosDisplayResponse;
284
300
  }
301
+ /**
302
+ * A plugin's screen on the display (AGL-4042): the shape of core's
303
+ * `CustomerDisplayScreen`, restated so this module imports nothing. The
304
+ * server checks it with core's own sanitizer before it is stored.
305
+ */
306
+ export interface PosDisplayScreen {
307
+ pluginId: string;
308
+ path: string;
309
+ params: Record<string, string>;
310
+ }
285
311
  /** Most lines a display state carries; a longer basket shows its newest. */
286
312
  export declare const POS_DISPLAY_MAX_LINES = 60;
287
313
  /** A pairing code lives this long before the register must show a new one. */
@@ -297,7 +323,14 @@ export declare function posDisplayPhone(value: unknown): string;
297
323
  * of anything the customer screen has no business holding. The register is
298
324
  * staff and trusted for intent, not for shape.
299
325
  */
300
- export declare function sanitizePosDisplayState(raw: unknown, nowMs: number): PosDisplayState;
326
+ export declare function sanitizePosDisplayState(raw: unknown, nowMs: number, options?: {
327
+ /**
328
+ * Checks a `screen` state's plugin page (core's
329
+ * `sanitizeCustomerDisplayScreen`). Without it, or when it refuses, a
330
+ * `screen` state is idle: nothing opens on the display unchecked.
331
+ */
332
+ screen?: (raw: unknown) => PosDisplayScreen | null;
333
+ }): PosDisplayState;
301
334
  /**
302
335
  * The customer's answer as the DISPLAY may send it, checked against the
303
336
  * prompt it claims to answer. Returns null when it answers nothing the
@@ -310,6 +343,6 @@ export declare function sanitizePosDisplayResponse(state: PosDisplayState | null
310
343
  * screen shows what comes next, so nothing a later customer could read off
311
344
  * an unattended tablet is ever sent to it.
312
345
  */
313
- export declare function posDisplayPublicState(state: PosDisplayState | null | undefined, nowMs: number): Omit<PosDisplayState, 'response'> & {
346
+ export declare function posDisplayPublicState(state: PosDisplayState | null | undefined, nowMs: number): Omit<PosDisplayState, 'response' | 'screenShownBy'> & {
314
347
  answered: boolean;
315
348
  };
@@ -277,7 +277,7 @@ const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
277
277
  * The display state as the REGISTER may send it: clamped, typed and stripped
278
278
  * of anything the customer screen has no business holding. The register is
279
279
  * staff and trusted for intent, not for shape.
280
- */ export function sanitizePosDisplayState(raw, nowMs) {
280
+ */ export function sanitizePosDisplayState(raw, nowMs, options = {}) {
281
281
  var _input_promptId;
282
282
  const input = raw && typeof raw === 'object' ? raw : {};
283
283
  const modes = [
@@ -286,15 +286,21 @@ const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
286
286
  'tip',
287
287
  'receipt',
288
288
  'processing',
289
- 'thanks'
289
+ 'thanks',
290
+ 'screen'
290
291
  ];
291
- const mode = modes.includes(input['mode']) ? input['mode'] : 'idle';
292
+ const asked = modes.includes(input['mode']) ? input['mode'] : 'idle';
293
+ const promptId = String((_input_promptId = input['promptId']) != null ? _input_promptId : '').slice(0, 64);
294
+ // A screen opens once per prompt, so one without a prompt, or one the
295
+ // checker refuses, opens nothing.
296
+ const screen = asked === 'screen' && promptId && options.screen ? options.screen(input['screen']) : null;
297
+ const mode = asked === 'screen' && !screen ? 'idle' : asked;
292
298
  const state = {
293
299
  mode,
294
300
  updatedAtMs: nowMs
295
301
  };
296
- const promptId = String((_input_promptId = input['promptId']) != null ? _input_promptId : '').slice(0, 64);
297
302
  if (promptId) state.promptId = promptId;
303
+ if (mode === 'screen' && screen) state.screen = screen;
298
304
  const cart = input['cart'];
299
305
  if (cart && typeof cart === 'object' && mode !== 'idle') {
300
306
  const lines = (Array.isArray(cart.lines) ? cart.lines : []).slice(-POS_DISPLAY_MAX_LINES).map((line)=>{
@@ -426,8 +432,10 @@ const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
426
432
  updatedAtMs: nowMs,
427
433
  answered: false
428
434
  };
429
- const { response } = state, rest = _object_without_properties_loose(state, [
430
- "response"
435
+ // Who showed a plugin's screen is the server's to know, not the display's.
436
+ const { response, screenShownBy: _shownBy } = state, rest = _object_without_properties_loose(state, [
437
+ "response",
438
+ "screenShownBy"
431
439
  ]);
432
440
  if (rest.mode === 'thanks' && nowMs - rest.updatedAtMs > POS_DISPLAY_THANKS_MS) {
433
441
  return {