@sixtyninecommerce/admin 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/README.md +4598 -128
  2. package/dist/catalog/assets.d.ts +120 -8
  3. package/dist/catalog/assets.js +98 -12
  4. package/dist/catalog/collections.d.ts +279 -14
  5. package/dist/catalog/collections.js +246 -15
  6. package/dist/catalog/index.d.ts +9 -2
  7. package/dist/catalog/index.js +4 -0
  8. package/dist/catalog/products.d.ts +318 -17
  9. package/dist/catalog/products.js +182 -14
  10. package/dist/catalog/properties.d.ts +102 -14
  11. package/dist/catalog/properties.js +13 -0
  12. package/dist/catalog/recommendations.d.ts +261 -0
  13. package/dist/catalog/recommendations.js +145 -0
  14. package/dist/catalog/reviews.d.ts +368 -0
  15. package/dist/catalog/reviews.js +318 -0
  16. package/dist/catalog/types.d.ts +17 -1
  17. package/dist/catalog/types.js +10 -0
  18. package/dist/catalog/variant-find.d.ts +136 -0
  19. package/dist/catalog/variant-find.js +239 -0
  20. package/dist/catalog/variants.d.ts +282 -25
  21. package/dist/catalog/variants.js +173 -25
  22. package/dist/catalog/visibility.d.ts +20 -5
  23. package/dist/catalog/visibility.js +19 -1
  24. package/dist/client.d.ts +116 -9
  25. package/dist/client.js +41 -7
  26. package/dist/content/assets.d.ts +286 -0
  27. package/dist/content/assets.js +181 -0
  28. package/dist/content/items.d.ts +269 -0
  29. package/dist/content/items.js +170 -0
  30. package/dist/content/types.d.ts +282 -0
  31. package/dist/content/types.js +100 -0
  32. package/dist/customers/age-verification.d.ts +66 -0
  33. package/dist/customers/age-verification.js +79 -0
  34. package/dist/customers/credit.d.ts +263 -0
  35. package/dist/customers/credit.js +244 -0
  36. package/dist/customers/delivery-preferences.d.ts +120 -0
  37. package/dist/customers/delivery-preferences.js +97 -0
  38. package/dist/customers/groups.d.ts +207 -0
  39. package/dist/customers/groups.js +438 -0
  40. package/dist/customers/index.d.ts +447 -37
  41. package/dist/customers/index.js +313 -40
  42. package/dist/customers/invitation-status.d.ts +57 -0
  43. package/dist/customers/invitation-status.js +21 -0
  44. package/dist/customers/notes.d.ts +67 -0
  45. package/dist/customers/notes.js +51 -0
  46. package/dist/customers/notification-recipients.d.ts +97 -0
  47. package/dist/customers/notification-recipients.js +84 -0
  48. package/dist/customers/saved-lists.d.ts +42 -0
  49. package/dist/customers/saved-lists.js +61 -0
  50. package/dist/customers/vat.d.ts +83 -0
  51. package/dist/customers/vat.js +46 -0
  52. package/dist/customers/wire.d.ts +20 -0
  53. package/dist/customers/wire.js +35 -0
  54. package/dist/documents/ar.d.ts +307 -0
  55. package/dist/documents/ar.js +254 -0
  56. package/dist/documents/index.d.ts +731 -21
  57. package/dist/documents/index.js +436 -24
  58. package/dist/documents/pdf.d.ts +2 -0
  59. package/dist/documents/pdf.js +11 -0
  60. package/dist/fulfillments/create.d.ts +167 -0
  61. package/dist/fulfillments/create.js +216 -0
  62. package/dist/fulfillments/index.d.ts +121 -10
  63. package/dist/fulfillments/index.js +120 -2
  64. package/dist/fulfillments/payment-policy.d.ts +64 -0
  65. package/dist/fulfillments/payment-policy.js +140 -0
  66. package/dist/fulfillments/warehouse.d.ts +724 -0
  67. package/dist/fulfillments/warehouse.js +914 -0
  68. package/dist/geo/index.d.ts +119 -0
  69. package/dist/geo/index.js +107 -0
  70. package/dist/index.d.ts +129 -30
  71. package/dist/index.js +47 -9
  72. package/dist/integrations/afas-actions.d.ts +234 -0
  73. package/dist/integrations/afas-actions.js +310 -0
  74. package/dist/integrations/afas-types.d.ts +483 -0
  75. package/dist/integrations/afas-types.js +5 -0
  76. package/dist/integrations/afas.d.ts +234 -0
  77. package/dist/integrations/afas.js +290 -0
  78. package/dist/integrations/connections.d.ts +103 -0
  79. package/dist/integrations/connections.js +55 -0
  80. package/dist/integrations/esp.d.ts +313 -0
  81. package/dist/integrations/esp.js +169 -0
  82. package/dist/integrations/exact-online-types.d.ts +423 -0
  83. package/dist/integrations/exact-online-types.js +6 -0
  84. package/dist/integrations/exact-online.d.ts +248 -0
  85. package/dist/integrations/exact-online.js +376 -0
  86. package/dist/integrations/index.d.ts +40 -0
  87. package/dist/integrations/index.js +24 -0
  88. package/dist/integrations/pipeline-keys.d.ts +13 -0
  89. package/dist/integrations/pipeline-keys.js +22 -0
  90. package/dist/integrations/pipelines.d.ts +114 -0
  91. package/dist/integrations/pipelines.js +46 -0
  92. package/dist/integrations/types.d.ts +322 -0
  93. package/dist/integrations/types.js +8 -0
  94. package/dist/jobs/bulk-action-run.d.ts +11 -2
  95. package/dist/jobs/bulk-action-run.js +4 -5
  96. package/dist/locations/index.d.ts +66 -0
  97. package/dist/locations/index.js +31 -0
  98. package/dist/meta/index.d.ts +162 -0
  99. package/dist/orders/bulk.d.ts +75 -0
  100. package/dist/orders/bulk.js +150 -0
  101. package/dist/orders/cancel-with-money.d.ts +227 -0
  102. package/dist/orders/cancel-with-money.js +153 -0
  103. package/dist/orders/commit-edit.d.ts +7 -1
  104. package/dist/orders/commit-edit.js +5 -1
  105. package/dist/orders/deposit-policy.d.ts +103 -0
  106. package/dist/orders/deposit-policy.js +202 -0
  107. package/dist/orders/drafts.d.ts +800 -0
  108. package/dist/orders/drafts.js +771 -0
  109. package/dist/orders/fields.d.ts +245 -0
  110. package/dist/orders/fields.js +188 -0
  111. package/dist/orders/get.d.ts +29 -19
  112. package/dist/orders/get.js +17 -8
  113. package/dist/orders/index.d.ts +125 -5
  114. package/dist/orders/index.js +35 -2
  115. package/dist/orders/lifecycle.d.ts +128 -0
  116. package/dist/orders/lifecycle.js +158 -0
  117. package/dist/orders/line-price-preview.d.ts +7 -2
  118. package/dist/orders/list.d.ts +222 -0
  119. package/dist/orders/list.js +377 -0
  120. package/dist/orders/manual-discounts.d.ts +11 -2
  121. package/dist/orders/manual-discounts.js +2 -0
  122. package/dist/orders/manual-pricing.d.ts +5 -0
  123. package/dist/orders/order-entry.d.ts +20 -7
  124. package/dist/orders/plan-edit.d.ts +1 -1
  125. package/dist/orders/plan-edit.js +4 -1
  126. package/dist/orders/settings.d.ts +201 -0
  127. package/dist/orders/settings.js +325 -0
  128. package/dist/orders/status.d.ts +159 -13
  129. package/dist/orders/status.js +21 -0
  130. package/dist/orders/surcharges.d.ts +8 -1
  131. package/dist/orders/surcharges.js +3 -2
  132. package/dist/payments/account-credit.d.ts +30 -0
  133. package/dist/payments/account-credit.js +19 -0
  134. package/dist/payments/ar.d.ts +292 -0
  135. package/dist/payments/ar.js +223 -0
  136. package/dist/payments/connected-account.d.ts +47 -0
  137. package/dist/payments/connected-account.js +61 -0
  138. package/dist/payments/credit-noted-fields.d.ts +12 -0
  139. package/dist/payments/credit-noted-fields.js +37 -0
  140. package/dist/payments/index.d.ts +263 -10
  141. package/dist/payments/index.js +133 -1
  142. package/dist/payments/methods.d.ts +332 -0
  143. package/dist/payments/methods.js +363 -0
  144. package/dist/payments/mollie-methods.d.ts +159 -0
  145. package/dist/payments/mollie-methods.js +141 -0
  146. package/dist/payments/payment-links.d.ts +180 -0
  147. package/dist/payments/payment-links.js +97 -0
  148. package/dist/payments/provider-keys.d.ts +150 -0
  149. package/dist/payments/provider-keys.js +118 -0
  150. package/dist/payments/providers.d.ts +86 -11
  151. package/dist/payments/providers.js +29 -0
  152. package/dist/payments/requests.d.ts +144 -0
  153. package/dist/payments/requests.js +92 -0
  154. package/dist/payments/store-credit-fields.d.ts +15 -0
  155. package/dist/payments/store-credit-fields.js +51 -0
  156. package/dist/pickups/index.d.ts +104 -0
  157. package/dist/pickups/index.js +105 -0
  158. package/dist/platform/channels.d.ts +132 -0
  159. package/dist/platform/channels.js +128 -0
  160. package/dist/platform/geo.d.ts +123 -0
  161. package/dist/platform/geo.js +144 -0
  162. package/dist/platform/tax.d.ts +154 -0
  163. package/dist/platform/tax.js +139 -0
  164. package/dist/pos/anomalies.d.ts +158 -0
  165. package/dist/pos/anomalies.js +64 -0
  166. package/dist/pos/assisted-selling.d.ts +79 -0
  167. package/dist/pos/assisted-selling.js +38 -0
  168. package/dist/pos/exchanges.d.ts +103 -0
  169. package/dist/pos/exchanges.js +22 -0
  170. package/dist/pos/gift-cards.d.ts +135 -0
  171. package/dist/pos/gift-cards.js +47 -0
  172. package/dist/pos/index.d.ts +2125 -32
  173. package/dist/pos/index.js +742 -4
  174. package/dist/pos/no-receipt.d.ts +94 -0
  175. package/dist/pos/no-receipt.js +25 -0
  176. package/dist/pos/offline-sales.d.ts +187 -0
  177. package/dist/pos/offline-sales.js +116 -0
  178. package/dist/pos/pay-by-link.d.ts +143 -0
  179. package/dist/pos/pay-by-link.js +57 -0
  180. package/dist/pos/quick-keys.d.ts +103 -0
  181. package/dist/pos/quick-keys.js +45 -0
  182. package/dist/pos/reports.d.ts +360 -0
  183. package/dist/pos/reports.js +62 -0
  184. package/dist/pos/returns.d.ts +217 -0
  185. package/dist/pos/returns.js +53 -0
  186. package/dist/pricing/bulk-coupons.d.ts +139 -0
  187. package/dist/pricing/bulk-coupons.js +112 -0
  188. package/dist/pricing/index.d.ts +177 -4
  189. package/dist/pricing/index.js +176 -1
  190. package/dist/pricing/price-lists.d.ts +604 -0
  191. package/dist/pricing/price-lists.js +600 -0
  192. package/dist/pricing/vouchers.d.ts +103 -0
  193. package/dist/pricing/vouchers.js +69 -0
  194. package/dist/purchasing/alerts.d.ts +89 -0
  195. package/dist/purchasing/alerts.js +62 -0
  196. package/dist/purchasing/cost.d.ts +110 -0
  197. package/dist/purchasing/cost.js +86 -0
  198. package/dist/purchasing/index.d.ts +36 -0
  199. package/dist/purchasing/index.js +16 -0
  200. package/dist/purchasing/purchase-orders.d.ts +548 -0
  201. package/dist/purchasing/purchase-orders.js +491 -0
  202. package/dist/purchasing/replenishment.d.ts +281 -0
  203. package/dist/purchasing/replenishment.js +240 -0
  204. package/dist/purchasing/settings.d.ts +152 -0
  205. package/dist/purchasing/settings.js +181 -0
  206. package/dist/purchasing/suppliers.d.ts +476 -0
  207. package/dist/purchasing/suppliers.js +438 -0
  208. package/dist/quotes/index.d.ts +501 -0
  209. package/dist/quotes/index.js +439 -0
  210. package/dist/reports/index.d.ts +71 -8
  211. package/dist/reports/index.js +74 -11
  212. package/dist/returns/index.d.ts +818 -0
  213. package/dist/returns/index.js +844 -0
  214. package/dist/search/index.d.ts +174 -0
  215. package/dist/search/index.js +125 -0
  216. package/dist/shipping/definitions.d.ts +29 -0
  217. package/dist/shipping/definitions.js +47 -0
  218. package/dist/shipping/fulfillment-profiles.d.ts +174 -0
  219. package/dist/shipping/fulfillment-profiles.js +104 -0
  220. package/dist/shipping/hendriks.d.ts +97 -0
  221. package/dist/shipping/hendriks.js +50 -0
  222. package/dist/shipping/index.d.ts +48 -0
  223. package/dist/shipping/index.js +25 -0
  224. package/dist/shipping/methods.d.ts +198 -0
  225. package/dist/shipping/methods.js +240 -0
  226. package/dist/shipping/myparcel.d.ts +254 -0
  227. package/dist/shipping/myparcel.js +178 -0
  228. package/dist/shipping/parcel-count-suggestion.d.ts +2 -0
  229. package/dist/shipping/parcel-rule.d.ts +6 -5
  230. package/dist/shipping/parcel-rule.js +21 -23
  231. package/dist/shipping/rate-tables.d.ts +179 -0
  232. package/dist/shipping/rate-tables.js +184 -0
  233. package/dist/stock/index.d.ts +10 -3
  234. package/dist/stock/index.js +3 -0
  235. package/dist/stock/locations.d.ts +144 -0
  236. package/dist/stock/locations.js +168 -0
  237. package/dist/stock/transfers.d.ts +216 -43
  238. package/dist/stock/transfers.js +140 -13
  239. package/dist/stored-value/index.d.ts +214 -4
  240. package/dist/stored-value/index.js +152 -0
  241. package/dist/subscriptions/index.d.ts +682 -0
  242. package/dist/subscriptions/index.js +815 -0
  243. package/dist/tax/index.d.ts +76 -1
  244. package/dist/tax/index.js +50 -0
  245. package/dist/tenant/email-style.d.ts +102 -0
  246. package/dist/tenant/email-style.js +72 -0
  247. package/dist/tenant/email-templates.d.ts +66 -0
  248. package/dist/tenant/email-templates.js +54 -0
  249. package/dist/tenant/notifications.d.ts +23 -17
  250. package/dist/tenant/settings-sources.d.ts +1 -1
  251. package/dist/tenant/time-zone.d.ts +17 -0
  252. package/dist/tenant/time-zone.js +11 -0
  253. package/dist/types.d.ts +51 -4
  254. package/dist/users/index.d.ts +3 -0
  255. package/dist/users/index.js +2 -0
  256. package/dist/users/warehouses.d.ts +50 -0
  257. package/dist/users/warehouses.js +51 -0
  258. package/package.json +2 -2
@@ -1,5 +1,15 @@
1
1
  import { type Page, type Transport } from '@sixtyninecommerce/core';
2
- import type { Call } from '../types.js';
2
+ import type { Call, ListOptions } from '../types.js';
3
+ import { type PosAnomaliesModule } from './anomalies.js';
4
+ import { type PosAssistedSellingModule } from './assisted-selling.js';
5
+ import { type PosExchangesModule } from './exchanges.js';
6
+ import { type PosGiftCardsModule } from './gift-cards.js';
7
+ import { type PosNoReceiptModule } from './no-receipt.js';
8
+ import { type PosDeviceOfflineSalesToReview, type PosOfflineCashSales, type PosOfflineCashSalesInput, type PosOfflineSalesModule } from './offline-sales.js';
9
+ import { type PosPayByLinkModule } from './pay-by-link.js';
10
+ import { type PosQuickKeysModule } from './quick-keys.js';
11
+ import { type PosReportsModule } from './reports.js';
12
+ import { type PosReturnsModule } from './returns.js';
3
13
  /**
4
14
  * Point of sale on a machine principal (spec §8.8): a vertical's own backend
5
15
  * runs the till — register sessions, cash, tenders, the sale, refunds, X and Z —
@@ -29,7 +39,8 @@ import type { Call } from '../types.js';
29
39
  * / `registerRef`)
30
40
  * — the platform records those refs on each payment only when it vouches for
31
41
  * the credential; they are attribution, never authorization. For a principal
32
- * the CREDENTIAL is the manager gate for discounts and refunds.
42
+ * the CREDENTIAL is the manager gate for discounts and refunds, and for a
43
+ * drawer's paid-out, no-sale and float adjustment.
33
44
  *
34
45
  * ## Money
35
46
  *
@@ -55,17 +66,92 @@ import type { Call } from '../types.js';
55
66
  * - the tenders take money on such a cart (once it is placed, more money is
56
67
  * `POS_ORDER_NOT_PAYABLE`) or on an order the till did not open while it can
57
68
  * still take payment (see {@link PosTendersModule.card});
58
- * - `refunds.create` refunds a payment of a till's sale.
69
+ * - `refunds.create` refunds a payment of a till's sale (money only);
70
+ * - `returns.quote` / `returns.create` / `returns.void` take a sale's items back (or void it) and
71
+ * refund them to the sale's own payments (engine sprint 20);
72
+ * - `exchanges.quote` / `exchanges.create` take a sale's items back and carry their value to an
73
+ * open till cart as its last tender (engine sprint 21).
74
+ *
75
+ * ## Setting the till up
76
+ *
77
+ * `settings` and `terminals` are the store's own setup, for a back-office user
78
+ * or its tooling, not for a till: `settings.get` reads the POS settings, with the
79
+ * till's Mollie API key only ever as `hasMollieKey` and its mask;
80
+ * `settings.setMollieApiKey` / `removeMollieApiKey` write the key (it is never
81
+ * readable again, and a store that is not live takes only a `test_` key);
82
+ * `terminals.list` asks Mollie, server-side with the stored key, which card
83
+ * terminals that key reaches (the id a device is assigned);
84
+ * `settings.setCashRoundingMode` chooses how the cash that settles a sale is
85
+ * rounded, between shifts only; and `settings.readiness` says what the tills
86
+ * still need before they take cash and card payments, judged by the engine from
87
+ * the store's own records. `quickKeys.get` / `quickKeys.set` read and replace the
88
+ * store's quick keys, the favourite-product buttons on every till's sell screen.
89
+ *
90
+ * ## A store's days
91
+ *
92
+ * `days` is a location's business days for a back office: `days.get` one day with its drawers
93
+ * and totals, `days.list` a window of days, `days.close` once every drawer of the day is closed
94
+ * (no drawer opens on it after), `days.reopen` with a reason (engine sprint 26e).
95
+ *
96
+ * ## Reports
97
+ *
98
+ * `reports` is the back office's figures, computed by the engine: `reports.summary` by business
99
+ * day (reconciled to the Z reports), `tenders`, `locations`, `hours` and `cashiers`, each its own
100
+ * document over `posReport` (engine sprint 28). `anomalies` is the store's anomaly flags: the
101
+ * rules (off until the store turns them on), the flags each location's ended business day raised,
102
+ * their acknowledgement with a note, and a day scanned on demand (engine row 43).
103
+ *
104
+ * ## The staff
105
+ *
106
+ * `staff` is the store's cashiers and managers as the back office manages them:
107
+ * name, role, active, and each one's own till language (`locale`). Creating one
108
+ * sets its first PIN; the PIN is never read back.
109
+ *
110
+ * ## Offline cash sales
111
+ *
112
+ * `settings.offlineCashSales` / `setOfflineCashSales` are the store's switch for cash sales a
113
+ * till makes while offline (off by default) and its limits; `offlineSales` is the manager's queue
114
+ * of the ones the engine could not record as rung (engine sprint 45). The till's replay is its
115
+ * own door: no method here sends one.
59
116
  */
60
117
  export interface PosModule {
61
118
  registers: PosRegistersModule;
62
119
  sessions: PosSessionsModule;
63
120
  cash: PosCashModule;
121
+ /** The store's till sales for a back office (engine sprint 27). */
122
+ orders: PosOrdersModule;
123
+ /** A location's business days: read, list, close and reopen (engine sprint 26). */
124
+ days: PosDaysModule;
125
+ /** The back office's reports, every figure computed by the engine (engine sprint 28). */
126
+ reports: PosReportsModule;
127
+ /** The store's anomaly flags and their rules (engine row 43). Off until the store turns them on. */
128
+ anomalies: PosAnomaliesModule;
64
129
  sale: PosSaleModule;
65
130
  tenders: PosTendersModule;
66
131
  refunds: PosRefundsModule;
132
+ /** Till returns and voids: goods back to the till, money to the sale's tenders (engine sprint 20). */
133
+ returns: PosReturnsModule;
134
+ /** Till exchanges: a sale's items back, their value to an open cart (engine sprint 21). */
135
+ exchanges: PosExchangesModule;
136
+ /** Returns without a receipt: the store's rules and the quote (engine sprint 21). */
137
+ noReceipt: PosNoReceiptModule;
67
138
  devices: PosDevicesModule;
68
139
  receiptNumbering: PosReceiptNumberingModule;
140
+ settings: PosSettingsModule;
141
+ terminals: PosTerminalsModule;
142
+ staff: PosStaffModule;
143
+ quickKeys: PosQuickKeysModule;
144
+ /** Upsell prompts and assisted search at the till (engine sprint C4/44). */
145
+ assistedSelling: PosAssistedSellingModule;
146
+ /** Pay by link at the till: a link and QR code for part or all of a sale (engine C5). */
147
+ payByLink: PosPayByLinkModule;
148
+ /** The offline sales a manager must look at, and marking them handled (engine sprint 45). */
149
+ offlineSales: PosOfflineSalesModule;
150
+ /**
151
+ * Gift cards at the till (engine C6): a card's balance by its code, paying by code, and a
152
+ * sale whose codes the till hands over (their codes in the completion's first answer only).
153
+ */
154
+ giftCards: PosGiftCardsModule;
69
155
  }
70
156
  /**
71
157
  * A money call: the key is REQUIRED, not optional. The server claims it before
@@ -92,35 +178,102 @@ export interface PosRegister {
92
178
  createdAt: string;
93
179
  updatedAt: string;
94
180
  }
181
+ /**
182
+ * The store's registers: the logical tills a drawer session, its Z numbers and a device's cash
183
+ * belong to, each standing at one stock location for good.
184
+ */
95
185
  export interface PosRegistersModule {
96
186
  /**
97
- * The store's registers. A machine principal sees only the registers at its
98
- * own verified location — the ids it may open a session on.
187
+ * The store's registers, newest first, whole (one page). A machine principal sees only the
188
+ * registers at its own verified location — the ids it may open a session on — and a
189
+ * location-restricted credential only those at its locations.
190
+ *
191
+ * @effect read
99
192
  */
100
193
  list(options?: Call): Promise<Page<PosRegister>>;
101
- /** One register, or null (also for another location's register, to a principal). */
194
+ /**
195
+ * One register, or null when the store has none by that id (another store's reads the same;
196
+ * to a principal, also another location's, and to a location-restricted credential one
197
+ * outside its locations).
198
+ *
199
+ * @effect read
200
+ */
102
201
  get(id: string, options?: Call): Promise<PosRegister | null>;
103
- /** Needs `ManagePosDevices` (or `UpdateSettings`). */
202
+ /**
203
+ * Add an active register at one of the store's stock locations; its location never changes.
204
+ * Needs `ManagePosDevices` (or `UpdateSettings`). A location outside a restricted credential's
205
+ * is refused `LOCATION_NOT_ALLOWED` (`PermissionDeniedError`), one the store does not have
206
+ * `POS_LOCATION_NOT_FOUND` (`NotFoundError`; an engine before W10-62 answers it uncoded), and an
207
+ * organization workspace `ORGANIZATION_WORKSPACE_NOT_A_STORE`. All before anything is written.
208
+ *
209
+ * @effect write
210
+ */
104
211
  create(input: {
105
212
  name: string;
106
213
  stockLocationId: string;
107
214
  }, options?: Call): Promise<PosRegister>;
108
- /** Needs `ManagePosDevices` (or `UpdateSettings`). */
215
+ /**
216
+ * Rename a register, or retire it with `status: 'inactive'` (and bring it back with
217
+ * `'active'`). Only an active register opens a drawer (`POS_REGISTER_INACTIVE` to a new one, and
218
+ * from W10-62 to a device being given it); a drawer already open on it can still be counted and
219
+ * closed. Its sessions and Z numbers stay. Needs `ManagePosDevices` (or `UpdateSettings`).
220
+ * Refused `POS_REGISTER_NOT_FOUND` (`NotFoundError`) for a register the store does not have, and
221
+ * `LOCATION_NOT_ALLOWED` (`PermissionDeniedError`) for one standing outside a restricted
222
+ * credential's locations (both coded from W10-62; an older engine answers the first uncoded and
223
+ * does not check the second).
224
+ *
225
+ * @effect write
226
+ */
109
227
  update(id: string, input: {
110
228
  name?: string;
111
229
  status?: string;
112
230
  }, options?: Call): Promise<PosRegister>;
113
231
  }
232
+ /**
233
+ * A register session's tender totals, integer minor units of the drawer's
234
+ * currency (the store's default), from the SETTLED payments and refunds of the
235
+ * session's orders: a card payment still waiting on the terminal is not counted.
236
+ * Orders in a currency other than the store's default are left out.
237
+ */
114
238
  export interface PosSessionTotals {
115
- /** Cash taken in sales, minor units. */
239
+ /** Settled payments on the till's cash method. */
116
240
  cash: number;
117
- /** Card and other tenders are reconciled from payments, not the drawer: always 0 here. */
241
+ /** Settled payments on the till's card terminal method. */
118
242
  card: number;
243
+ /** Settled payments on any other method (manual tenders). */
119
244
  other: number;
245
+ /**
246
+ * All settled refunds, on every tender (`cashRefunds + cardRefunds +
247
+ * otherRefunds` of {@link PosStoredSessionTotals}).
248
+ */
120
249
  refunds: number;
250
+ /** `cash + card + other - refunds`. */
121
251
  net: number;
252
+ /** Completed sales: the session's orders given a receipt number. */
122
253
  saleCount: number;
123
254
  }
255
+ /** A session's stored totals (the Z): the X-report figures plus the refunds split by tender. */
256
+ export interface PosStoredSessionTotals extends PosSessionTotals {
257
+ /** Settled refunds on cash payments. Absent on older engines. */
258
+ cashRefunds?: number;
259
+ /** Settled refunds on card terminal payments. Absent on older engines. */
260
+ cardRefunds?: number;
261
+ /** Settled refunds on payments of any other method. Absent on older engines. */
262
+ otherRefunds?: number;
263
+ /**
264
+ * Signed cash rounding the drawer kept (+) or gave up (−), from its ledger; not in `net`. On a
265
+ * store that rounds cash (`cashRoundingMode`), cash into the drawer from sales is
266
+ * `cash - cashRefunds + cashRounding`. Absent on older engines.
267
+ */
268
+ cashRounding?: number;
269
+ /**
270
+ * Of which gift cards sold (engine C6): the face value and count of the cards the session's
271
+ * completed sales issued, a memo already inside the tenders (a liability, not sales). Absent on
272
+ * a Z closed before C6 and on older engines: read it as 0.
273
+ */
274
+ giftCardsSold?: number;
275
+ giftCardsSoldCount?: number;
276
+ }
124
277
  /** A register session: one drawer, from its opening float to its Z. */
125
278
  export interface PosRegisterSession {
126
279
  id: string;
@@ -136,10 +289,105 @@ export interface PosRegisterSession {
136
289
  countedCash: number | null;
137
290
  /** `countedCash - expectedCash`; negative is short. Null while open. */
138
291
  cashOverShort: number | null;
139
- totals: PosSessionTotals | null;
292
+ totals: PosStoredSessionTotals | null;
140
293
  openedAt: string;
141
294
  closedAt: string | null;
295
+ /**
296
+ * The close's details (engine sprint 25b), read by `sessions.get` and `sessions.list`; absent
297
+ * from the other session calls, and null while open and for sessions closed before 25b. Who
298
+ * closed it (null for a machine principal without a staff token).
299
+ */
300
+ closedByStaffId?: string | null;
301
+ /** Whether the store counted blind when it closed. */
302
+ blindCount?: boolean | null;
303
+ /** The store's variance threshold when it closed (minor units); null for none. */
304
+ varianceThreshold?: number | null;
305
+ /**
306
+ * What became of the variance: `not_required` (within the threshold), `approved` (a manager, or
307
+ * a machine credential, approved it at the close) or `pending` (a manager still has to). More may
308
+ * come: show an unknown value as it is.
309
+ */
310
+ varianceApproval?: PosVarianceApproval | (string & {}) | null;
311
+ /** The manager who approved it; null when none needed to, a machine credential did, or pending. */
312
+ varianceApprovedByStaffId?: string | null;
313
+ varianceApprovedAt?: string | null;
314
+ /**
315
+ * A `pending` close approved afterwards in the back office (engine sprint 27): the person's
316
+ * user id. Read by `sessions.approval` and `sessions.approveClose`; absent elsewhere.
317
+ */
318
+ varianceApprovedByUserId?: string | null;
319
+ /** That person's name as the store's administrators hold it now. Same documents as above. */
320
+ varianceApprovedByUserName?: string | null;
321
+ /** The machine credential that approved it afterwards (`api_token:<id>` / `app_installation:<id>`). */
322
+ varianceApprovedByCredential?: string | null;
323
+ /** Why the variance was accepted afterwards. Same documents as above. */
324
+ varianceApprovalNote?: string | null;
325
+ /**
326
+ * The Z's identity (engine sprint 26), read by `sessions.record` and `sessions.records`; absent
327
+ * from the other session calls. The store's business day it opened in (`YYYY-MM-DD`, its own
328
+ * day start in its location's zone; null for a drawer opened before 26 and not closed since).
329
+ */
330
+ businessDay?: string | null;
331
+ /** The stock location it was opened at, and that location's zone then (null before 26). */
332
+ stockLocationId?: string | null;
333
+ timeZone?: string | null;
334
+ /** The register's Z number, 1, 2, 3… in close order; null while open and for drawers closed before 26. */
335
+ zNumber?: number | null;
336
+ /**
337
+ * How it closed: `till` (its tablet, or a machine credential), `back_office` (a person, named
338
+ * in `closedByUserId`) or `auto` (closed without a count, left open). More may come: show an
339
+ * unknown value as it is. Null while open and before 26.
340
+ */
341
+ closeSource?: PosCloseSource | (string & {}) | null;
342
+ /** The person who closed it in the back office (their user id); null otherwise. */
343
+ closedByUserId?: string | null;
344
+ /** That person's name as the store's administrators hold it now. Read by `sessions.record` only. */
345
+ closedByUserName?: string | null;
346
+ /**
347
+ * A drawer closed WITHOUT a count, and counted later (engine sprint 26b), read by
348
+ * `sessions.record`, `sessions.records`, `sessions.closeUncounted` and `sessions.count`; absent
349
+ * elsewhere. Why it closed automatically (`after_closing_time` or `idle`; null for every other
350
+ * close). More may come: show an unknown value as it is.
351
+ */
352
+ autoCloseReason?: PosAutoCloseReason | (string & {}) | null;
353
+ /** Why a person closed it without a count (`sessions.closeUncounted`'s note); null otherwise. */
354
+ closeNote?: string | null;
355
+ /** When its cash was counted after a close without a count (`sessions.count`); null otherwise. */
356
+ countedAt?: string | null;
357
+ /** The person who counted it afterwards (their user id); null for a machine credential. */
358
+ countedByUserId?: string | null;
359
+ /** That person's name as the store's administrators hold it now. Not read by `records`. */
360
+ countedByUserName?: string | null;
361
+ /** The counter's note; null when none was given. */
362
+ countNote?: string | null;
142
363
  }
364
+ /** Why a drawer was closed automatically, without a count (engine sprint 26b). More may come. */
365
+ export type PosAutoCloseReason = 'after_closing_time' | 'idle';
366
+ /** How a drawer closed (engine sprint 26). More may come. */
367
+ export type PosCloseSource = 'till' | 'back_office' | 'auto';
368
+ /**
369
+ * What became of a closed drawer's variance, with who approved it after the close (engine sprint
370
+ * 27, `sessions.approval`). Approved at the close: `varianceApprovedByStaffId` (a manager) or
371
+ * nobody named (a machine credential); approved afterwards: `varianceApprovedByUserId` (a person)
372
+ * or `varianceApprovedByCredential`, with the note.
373
+ */
374
+ export interface PosSessionApproval {
375
+ sessionId: string;
376
+ varianceApproval: PosVarianceApproval | (string & {}) | null;
377
+ varianceThreshold: number | null;
378
+ varianceApprovedByStaffId: string | null;
379
+ varianceApprovedAt: string | null;
380
+ varianceApprovedByUserId: string | null;
381
+ varianceApprovedByUserName: string | null;
382
+ varianceApprovedByCredential: string | null;
383
+ varianceApprovalNote: string | null;
384
+ }
385
+ /**
386
+ * What became of a closed drawer's variance (engine sprint 25b): within the threshold, approved,
387
+ * or waiting for a manager; or (engine sprint 26b) `uncounted`, closed without a count, so there
388
+ * is no variance yet: count it with `sessions.count` (never approved as it is).
389
+ */
390
+ export type PosVarianceApproval = 'not_required' | 'approved' | 'pending' | 'uncounted';
143
391
  /** A mid-shift snapshot. Reading it changes nothing. */
144
392
  export interface PosXReport {
145
393
  sessionId: string;
@@ -164,12 +412,16 @@ export interface PosSessionsModule {
164
412
  /**
165
413
  * Open a drawer. Refusals: `POS_REGISTER_REQUIRED`, `POS_REGISTER_NOT_FOUND`,
166
414
  * `POS_REGISTER_INACTIVE`, `POS_LOCATION_MISMATCH`, `POS_DEVICE_NOT_ALLOWED`,
167
- * and an already-open session on that register.
415
+ * `POS_DEVICE_NOT_FOUND`, `POS_DEVICE_NO_REGISTER`, and `POS_SESSION_ALREADY_OPEN` for a
416
+ * session already open on that register (`extensions.sessionId` names it; engine 25a, an
417
+ * uncoded error before).
168
418
  */
169
419
  open(input: OpenPosSessionInput, options?: PosCall): Promise<PosRegisterSession>;
170
420
  /**
171
421
  * Close it — this IS the Z report: expected cash from the ledger, your count,
172
- * the variance and the totals are stored on the session and returned.
422
+ * the variance and the totals are stored on the session and returned. A session already
423
+ * closed is `POS_SESSION_CLOSED`, an id that is no session of the store
424
+ * `POS_SESSION_NOT_FOUND` (engine 25a; uncoded errors before).
173
425
  */
174
426
  close(input: {
175
427
  sessionId: string;
@@ -178,13 +430,213 @@ export interface PosSessionsModule {
178
430
  }, options?: PosCall): Promise<PosRegisterSession>;
179
431
  /** The X report: the drawer so far, read-only. */
180
432
  xReport(sessionId: string, options?: Call): Promise<PosXReport>;
433
+ /**
434
+ * One session with its close's details (engine sprint 25b): who closed it, whether the store
435
+ * counted blind, its variance threshold then and what became of the variance (`pending`: a
436
+ * manager still has to approve it). Null for no session of the store. A till read, like
437
+ * `zReport`: any staff member of the store (or a `pos` token) may call it, and a machine
438
+ * principal reads a session at its verified location. An engine before 25b refuses the
439
+ * document at validation; `zReport` reads the session without these fields on every engine.
440
+ */
441
+ get(sessionId: string, options?: Call): Promise<PosRegisterSession | null>;
442
+ /**
443
+ * The drawer session open on a device now, or null when none is (an id that is no device of the
444
+ * store reads the same). Any staff member of the store may read it; a paired till reads its own
445
+ * device only (`POS_DEVICE_MISMATCH`), and a machine credential, which has no device, is refused
446
+ * `POS_DEVICE_NOT_ALLOWED`: read its session with `get`.
447
+ *
448
+ * @effect read
449
+ */
450
+ openForDevice(deviceId: string, options?: Call): Promise<PosRegisterSession | null>;
451
+ /**
452
+ * The store's register sessions, newest opened first, each with its close's details (as
453
+ * {@link PosSessionsModule.get}: who closed it, blind or not, the threshold then and what became
454
+ * of its variance, so a close still `pending` a manager can be found). `limit` is at most 100
455
+ * (50 when omitted); `after` is the previous page's cursor. Filters narrow it on the server.
456
+ * Needs `UpdateSettings` or `ManagePosDevices`; a paired till lists only the sessions its own
457
+ * device opened, a location-restricted credential only the drawers of registers at its
458
+ * locations, and a machine principal is `FORBIDDEN`. An engine before 25b refuses the document
459
+ * at validation.
460
+ *
461
+ * @effect read
462
+ */
463
+ list(options?: PosSessionListOptions): Promise<Page<PosRegisterSession>>;
181
464
  /**
182
465
  * The stored Z of a CLOSED session (the session as `close` left it). On a
183
466
  * session that is still open the Z fields are null — close it first.
184
467
  */
185
468
  zReport(sessionId: string, options?: Call): Promise<PosRegisterSession | null>;
469
+ /**
470
+ * A drawer session's cash ledger, newest first, with the WHOLE session's
471
+ * summary by kind (engine sprint 25a). Each row is its effect on the drawer
472
+ * (positive in, negative out) and the expected cash right after it; the
473
+ * summary's `expectedCash` is the X report's. `take` is at most 100 (50 when
474
+ * omitted); `skip` pages back in time. Read-only.
475
+ *
476
+ * A machine principal reads a session at its verified location; staff need
477
+ * `UpdateSettings` or `ManagePosDevices` (else `FORBIDDEN`). Another store's
478
+ * session, or none, is `POS_SESSION_NOT_FOUND`. An engine before 25a refuses
479
+ * the document at validation.
480
+ */
481
+ movements(sessionId: string, options?: Call & {
482
+ skip?: number;
483
+ take?: number;
484
+ }): Promise<PosDrawerMovementList>;
485
+ /**
486
+ * A session's variance approval with who approved it after the close (engine sprint 27): see
487
+ * {@link PosSessionApproval}. Null for no session of the store. Its own document, so `get`,
488
+ * `list` and `movements` keep working on an engine before 27, which refuses only this one at
489
+ * validation (`GRAPHQL_VALIDATION_FAILED`).
490
+ */
491
+ approval(sessionId: string, options?: Call): Promise<PosSessionApproval | null>;
492
+ /**
493
+ * Approve, after the close, a variance still waiting for a manager (`varianceApproval`
494
+ * `pending`, engine sprint 27): it becomes `approved` with who approved it, when and the note.
495
+ * The close's figures (expected, counted, variance, totals, the threshold then) never change.
496
+ * Idempotent by state: approving a session already approved answers it unchanged and writes
497
+ * nothing, so a lost answer is safe to retry and a second manager sees the first's approval.
498
+ * Refusals: `POS_SESSION_APPROVAL_NOTE_INVALID` (the note: 1 to 500 characters once trimmed,
499
+ * line breaks allowed; the refusal names the field `note`, `error.details[0].field`, and its
500
+ * `extensions.reason` is `required`, `too_long` or `control_character`), `POS_SESSION_CLOSE_NOT_PENDING` (open, within
501
+ * the threshold, closed before the store had cash controls; `extensions.varianceApproval`),
502
+ * `POS_SESSION_NOT_FOUND`. Needs `UpdateSettings` or `ManagePosDevices`; a `pos` token holding
503
+ * only `OperatePos` is `FORBIDDEN`. An engine before 27 refuses the document at validation.
504
+ */
505
+ approveClose(sessionId: string, input: {
506
+ note: string;
507
+ }, options?: Call): Promise<PosRegisterSession>;
508
+ /**
509
+ * One session's Z RECORD (engine sprint 26): everything `get` and `approval` read, plus the
510
+ * business day it opened in, its location and zone, the register's Z number, how it closed
511
+ * (`closeSource`) and who closed it in the back office, by name. Null for no session of the
512
+ * store. Its own document, so `get`, `list` and every other session call keep working on an
513
+ * engine before 26, which refuses only this one at validation (`GRAPHQL_VALIDATION_FAILED`).
514
+ */
515
+ record(sessionId: string, options?: Call): Promise<PosRegisterSession | null>;
516
+ /**
517
+ * The store's register sessions with their Z record (engine sprint 26), paged and filtered as
518
+ * {@link PosSessionsModule.list}, so a sessions list stays one read: the close's details, who
519
+ * approved it afterwards (by id and credential; the names are per session, read them with
520
+ * `record`), the business day, Z number and close source. Needs `UpdateSettings` or
521
+ * `ManagePosDevices`. An engine before 26 refuses the document at validation: fall back to
522
+ * `list`.
523
+ */
524
+ records(options?: PosSessionListOptions): Promise<Page<PosRegisterSession>>;
525
+ /**
526
+ * Close an OPEN drawer without a count, from the back office (engine sprint 26b): a till left
527
+ * open. Its Z is written as at any close (expected cash from the ledger, tender totals, the
528
+ * register's Z number, the business day, the store's threshold then) with no counted cash and
529
+ * `varianceApproval` `uncounted`; `closeSource` is `back_office`, `closeNote` the note, and the
530
+ * till finds the drawer closed at its next drawer call. Answers the session as `record` reads
531
+ * it. Idempotent by state: closing a drawer this way again answers it unchanged and writes
532
+ * nothing, so a lost answer is safe to retry. Refusals: `POS_CLOSE_NOTE_INVALID` (the note: 1 to
533
+ * 500 characters once trimmed; `extensions.reason` `required`, `too_long` or
534
+ * `control_character`), `POS_SESSION_NOT_FOUND`, `POS_SESSION_CLOSED` (closed another way: at
535
+ * the till, counted, or automatically), `POS_SESSION_SALE_IN_PROGRESS` (a payment is in flight
536
+ * on one of its carts; `extensions.orderCodes`, at most 10: finish or cancel it at the till
537
+ * first), `LOCATION_NOT_ALLOWED` (a credential restricted to other locations). Needs
538
+ * `UpdateSettings` or `ManagePosDevices`; a `pos` token holding only `OperatePos` is
539
+ * `FORBIDDEN`. An engine before 26 refuses the document at validation
540
+ * (`GRAPHQL_VALIDATION_FAILED`).
541
+ */
542
+ closeUncounted(sessionId: string, input: {
543
+ note: string;
544
+ }, options?: Call): Promise<PosRegisterSession>;
545
+ /**
546
+ * Record the count of a drawer closed without one (engine sprint 26b), in minor units of the
547
+ * drawer's currency. Fills `countedCash`, `closingCounts` and `cashOverShort` against the
548
+ * expected cash STORED at its close; `varianceApproval` becomes `not_required` within the
549
+ * threshold stored at its close, or `pending` above it (approve it with `approveClose`): the
550
+ * count never approves. The ledger, expected cash, totals and Z number never change. Idempotent
551
+ * by state: the same count again answers the session unchanged and writes nothing; other
552
+ * figures are refused. Refusals: `POS_SESSION_COUNT_INVALID` (`countedCash` a whole number from
553
+ * 0 to 100000000; `closingCounts` at most 50 denominations, each a whole count of 0 or more;
554
+ * `extensions.field` and `reason`), `POS_CLOSE_NOTE_INVALID` (the optional note: at most 500
555
+ * characters once trimmed), `POS_SESSION_NOT_FOUND`, `POS_SESSION_NOT_UNCOUNTED` (open, counted
556
+ * already with other figures, or not closed without a count; `extensions.status` and
557
+ * `varianceApproval`), `LOCATION_NOT_ALLOWED`. Needs `UpdateSettings` or `ManagePosDevices`. An
558
+ * engine before 26 refuses the document at validation (`GRAPHQL_VALIDATION_FAILED`).
559
+ */
560
+ count(sessionId: string, input: {
561
+ countedCash: number;
562
+ closingCounts?: Record<string, number>;
563
+ note?: string;
564
+ }, options?: Call): Promise<PosRegisterSession>;
565
+ }
566
+ /** `sessions.list`'s page and filters; every filter is optional and narrows on the server. */
567
+ export interface PosSessionListOptions extends ListOptions {
568
+ status?: 'open' | 'closed';
569
+ registerId?: string;
570
+ deviceId?: string;
571
+ /** The staff member who OPENED it. */
572
+ staffId?: string;
573
+ /** ISO instants bounding `openedAt`, both inclusive. */
574
+ openedAfter?: string;
575
+ openedBefore?: string;
186
576
  }
187
- export type PosCashMovementType = 'sale' | 'refund' | 'paid_in' | 'paid_out' | 'no_sale' | 'float_adjust';
577
+ /**
578
+ * One row of a drawer session's ledger as the drawer felt it. `type` is a
579
+ * string: besides the {@link PosCashMovementType}s it may be `cash_rounding`
580
+ * (the engine's rounding row), and a newer engine may add one; show an unknown
581
+ * type by its amount.
582
+ */
583
+ export interface PosDrawerMovement {
584
+ id: string;
585
+ type: string;
586
+ /** Its effect on the drawer, minor units: positive in, negative out, 0 for a no-sale. */
587
+ amount: number;
588
+ /** The expected cash right after this row: the opening float plus every row up to it. */
589
+ balanceAfter: number;
590
+ reason: string | null;
591
+ /** Who recorded it; null for a machine credential's row. */
592
+ staffId: string | null;
593
+ staffName: string | null;
594
+ /** The manager who approved it (a paid-out, no-sale, float adjustment or safe drop). */
595
+ approvedByStaffId: string | null;
596
+ approvedByStaffName: string | null;
597
+ /** The sale or refunded sale it belongs to. */
598
+ orderId: string | null;
599
+ orderCode: string | null;
600
+ receiptNumber: string | null;
601
+ createdAt: string;
602
+ }
603
+ /** A drawer session's ledger by kind: what makes up its expected cash (minor units). */
604
+ export interface PosDrawerSummary {
605
+ openingFloat: number;
606
+ /** Cash taken for sales in this drawer. */
607
+ cashSales: number;
608
+ /** Cash paid out of this drawer for refunds, whichever session sold them (negative). */
609
+ cashRefunds: number;
610
+ /** Signed cash rounding the drawer kept (+) or gave up (−). */
611
+ cashRounding: number;
612
+ paidIn: number;
613
+ /** Negative. */
614
+ paidOut: number;
615
+ /** Cash moved to the safe (negative). */
616
+ safeDrops: number;
617
+ /** Signed. */
618
+ floatAdjustments: number;
619
+ noSaleCount: number;
620
+ /** The opening float plus every row: the X report's expected cash. */
621
+ expectedCash: number;
622
+ movementCount: number;
623
+ }
624
+ /** A page of a drawer session's ledger, newest first, and the whole session's summary. */
625
+ export interface PosDrawerMovementList {
626
+ items: PosDrawerMovement[];
627
+ totalItems: number;
628
+ summary: PosDrawerSummary;
629
+ }
630
+ export type PosCashMovementType = 'sale' | 'refund' | 'paid_in' | 'paid_out' | 'no_sale' | 'float_adjust'
631
+ /** Cash taken from the drawer to the safe mid-shift (engine sprint 25a). */
632
+ | 'safe_drop';
633
+ /**
634
+ * The movement types `cash.record` takes: the five a person records (a safe
635
+ * drop since engine sprint 25a). A `sale` or `refund` movement is the engine's
636
+ * own, written when a sale or a refund settles in cash, so it is a
637
+ * {@link PosCashMovementType} you read back, never one you send.
638
+ */
639
+ export type PosRecordableCashMovementType = 'paid_in' | 'paid_out' | 'no_sale' | 'float_adjust' | 'safe_drop';
188
640
  export interface PosCashMovement {
189
641
  id: string;
190
642
  sessionId: string;
@@ -198,21 +650,401 @@ export interface PosCashMovement {
198
650
  export interface PosCashModule {
199
651
  /**
200
652
  * Record a drawer movement that is not a sale — paid in, paid out, a no-sale
201
- * open. Sales and refunds record their own.
653
+ * open. Sales and refunds record their own, so `type` takes only the four
654
+ * movement types a person records ({@link PosRecordableCashMovementType}); a
655
+ * caller that sends `sale` or `refund` anyway (from JavaScript, past the
656
+ * type) is refused `POS_CASH_MOVEMENT_TYPE_NOT_ALLOWED` (a permission
657
+ * refusal, whoever calls) and nothing is recorded. A `paid_out`, `no_sale`
658
+ * or `float_adjust` needs a manager: on a paired till a manager's PIN
659
+ * session, else `POS_MANAGER_REQUIRED`; for this principal the credential is
660
+ * that authority.
661
+ *
662
+ * For `paid_in` and `paid_out`, `amount` is the MAGNITUDE in minor units, 0
663
+ * or more: a paid-out of 10.00 is `1000`. The engine applies the sign: it
664
+ * records a paid-in as cash in and a paid-out as cash out (the movement it
665
+ * answers carries `-1000`). A `no_sale` carries no amount: send `0`. A
666
+ * negative amount, or a no-sale with any amount but `0`, is refused
667
+ * `POS_CASH_MOVEMENT_AMOUNT_INVALID` and nothing is recorded. `amount` is a
668
+ * GraphQL `Int`, so a fractional one never reaches the engine: the API
669
+ * refuses it as invalid input before anything runs. A `float_adjust` amount
670
+ * stays signed.
202
671
  *
203
672
  * The drawer holds the store's default currency. A movement naming the
204
673
  * `orderId` of an order in another currency is refused
205
674
  * `CASH_TENDER_CURRENCY_NOT_SUPPORTED` and nothing is recorded. An `orderId`
206
675
  * that is not an order of this store (another store's, or none at all) is
207
676
  * refused `ENTITY_NOT_FOUND`, and nothing is recorded.
677
+ *
678
+ * Engine sprint 25a: a `safe_drop` (cash to the safe) is a magnitude like a
679
+ * paid-out and needs a manager. A `float_adjust` needs an amount other than
680
+ * `0` (`POS_CASH_MOVEMENT_AMOUNT_INVALID`) and a reason
681
+ * (`POS_CASH_MOVEMENT_REASON_REQUIRED`). A movement on a closed session is
682
+ * `POS_SESSION_CLOSED`. With `options.idempotencyKey` (1 to 200
683
+ * characters, minted per movement) the movement is recorded at most once: a
684
+ * retry under the same key answers the movement already recorded, the same
685
+ * key for a different movement is `IDEMPOTENCY_CONFLICT`. The key is sent
686
+ * only when given, so a call without one works on an engine before 25a,
687
+ * which refuses the field.
208
688
  */
209
689
  record(input: {
210
690
  sessionId: string;
211
- type: PosCashMovementType;
691
+ type: PosRecordableCashMovementType;
212
692
  amount: number;
213
693
  reason?: string;
214
694
  orderId?: string;
215
695
  }, options?: PosCall): Promise<PosCashMovement>;
696
+ /**
697
+ * The store's drawer movements across every session and register, newest first, for a back
698
+ * office (engine sprint 27): each row's drawer effect (positive in, negative out, 0 for a
699
+ * no-sale), its session, register and till, who recorded and approved it, its order and the
700
+ * till's key it was recorded under (`idempotencyKey`, null for a row sent without one and for
701
+ * rows before 27), so a "may have gone through" on a till can be matched to one row. No
702
+ * running balance: `sessions.movements` has a session's. `fromDay`/`toDay` are the STORE's
703
+ * calendar days (`YYYY-MM-DD`, inclusive, both today when omitted, at most 31 days apart);
704
+ * `types` keeps only those ledger types (an unknown one is refused); `staffId` matches who
705
+ * recorded OR approved. `limit` is at most 100 (50 when omitted); `after` is the previous page's
706
+ * cursor. Refused `POS_LIST_RANGE_INVALID` (`extensions.reason`). Needs `UpdateSettings` or
707
+ * `ManagePosDevices`; a location-restricted credential reads the drawers at its locations
708
+ * only. An engine before 27 refuses the document at validation.
709
+ *
710
+ * @effect read
711
+ */
712
+ list(options?: PosCashMovementListOptions): Promise<Page<PosStoreCashMovement>>;
713
+ }
714
+ /** `cash.list`'s page and filters (engine sprint 27). */
715
+ export interface PosCashMovementListOptions extends ListOptions {
716
+ /** `YYYY-MM-DD` in the store's zone, inclusive. */
717
+ fromDay?: string;
718
+ toDay?: string;
719
+ registerId?: string;
720
+ sessionId?: string;
721
+ /** Only these ledger types (`sale`, `refund`, `cash_rounding`, `paid_in`, …); every type when omitted or empty. */
722
+ types?: readonly string[];
723
+ /** Recorded or approved by this staff member. */
724
+ staffId?: string;
725
+ }
726
+ /** One drawer ledger row as the store-wide list answers it (engine sprint 27). */
727
+ export interface PosStoreCashMovement {
728
+ id: string;
729
+ sessionId: string;
730
+ registerId: string;
731
+ registerName: string | null;
732
+ /** The till whose drawer it is; null for a machine credential's session. */
733
+ deviceId: string | null;
734
+ deviceLabel: string | null;
735
+ /** A ledger type; a newer engine may add one: show an unknown type by its amount. */
736
+ type: PosCashMovementType | 'cash_rounding' | (string & {});
737
+ /** Its effect on the drawer, minor units: positive in, negative out, 0 for a no-sale. */
738
+ amount: number;
739
+ reason: string | null;
740
+ staffId: string | null;
741
+ staffName: string | null;
742
+ approvedByStaffId: string | null;
743
+ approvedByStaffName: string | null;
744
+ orderId: string | null;
745
+ orderCode: string | null;
746
+ receiptNumber: string | null;
747
+ /** The till's key it was recorded under; null without one and for rows before engine 27. */
748
+ idempotencyKey: string | null;
749
+ createdAt: string;
750
+ }
751
+ /** The tender a till sale's settled payments were taken in. */
752
+ export type PosTenderKind = 'cash' | 'card' | 'other';
753
+ /** A completed till sale as the back office's list answers it (engine sprint 27). Money in minor units of `currencyCode`. */
754
+ export interface PosOrderSummary {
755
+ orderId: string;
756
+ orderCode: string;
757
+ receiptNumber: string;
758
+ placedAt: string | null;
759
+ state: string;
760
+ currencyCode: string;
761
+ totalWithTax: number;
762
+ totalQuantity: number;
763
+ /** Refunds that returned money or are on their way (Settled or Pending), over every payment. */
764
+ refundedTotal: number;
765
+ /** The tenders its settled payments were taken in, each once: cash, then card, then other. */
766
+ tenderKinds: PosTenderKind[];
767
+ /** `walk_in`, `customer` or `none`; more may come. */
768
+ customerKind: string;
769
+ /** The named customer's name; null for the walk-in and when none is attached. Customer data. */
770
+ customerName: string | null;
771
+ registerId: string | null;
772
+ registerName: string | null;
773
+ /** The drawer session it was rung up under; null when none. */
774
+ sessionId: string | null;
775
+ /** The paired till that sold it; null for a machine credential's sale. */
776
+ deviceId: string | null;
777
+ deviceLabel: string | null;
778
+ /** The cashier who completed it; null for a machine credential's sale. */
779
+ staffId: string | null;
780
+ staffName: string | null;
781
+ }
782
+ /** `orders.list`'s page and filters (engine sprint 27). */
783
+ export interface PosOrderListOptions extends ListOptions {
784
+ /** `YYYY-MM-DD` in the store's zone, inclusive. */
785
+ fromDay?: string;
786
+ toDay?: string;
787
+ registerId?: string;
788
+ sessionId?: string;
789
+ deviceId?: string;
790
+ /** The cashier who completed the sale. */
791
+ staffId?: string;
792
+ /** Sales with a settled payment in this tender; a split sale is listed under each. */
793
+ tender?: PosTenderKind;
794
+ /** 2 to 100 characters: an order code prefix, a receipt number suffix, or a named customer's name or email. */
795
+ term?: string;
796
+ }
797
+ /** One payment of a till sale, with its refund position (engine sprint 19). */
798
+ export interface PosTillSalePayment {
799
+ paymentId: string;
800
+ kind: PosTenderKind;
801
+ method: string;
802
+ state: string;
803
+ amount: number;
804
+ /** Refunds that returned money or are on their way (Settled or Pending). */
805
+ refunded: number;
806
+ /** Refunds with no confirmed outcome, held back until reconciled. */
807
+ refundUnknown: number;
808
+ /**
809
+ * What the till may still refund; 0 unless the payment is Settled, and 0 on an invoiced sale,
810
+ * which the till's guard refuses (`REFUND_REQUIRES_CREDIT_NOTE`): refund that through the
811
+ * invoice's correction.
812
+ */
813
+ refundable: number;
814
+ }
815
+ /**
816
+ * An in-person ID check a till recorded on a sale in a store with a minimum age (engine
817
+ * user decision L1): the cashier confirmed they saw the buyer's ID. Who and where are the till's
818
+ * own session and its cashier's PIN sign-in, never something a request named.
819
+ */
820
+ export interface PosTillSaleIdCheck {
821
+ id: string;
822
+ /** When the cashier confirmed it (ISO 8601, the server's clock). */
823
+ checkedAt: string;
824
+ staffId: string;
825
+ /** The cashier's name now; null when the store no longer has the staff row. */
826
+ staffName: string | null;
827
+ /** The paired till it was confirmed on, and that till's stock location. */
828
+ deviceId: string;
829
+ deviceLabel: string | null;
830
+ stockLocationId: string;
831
+ /** The store's minimum age when it was confirmed. */
832
+ minimumAge: number;
833
+ }
834
+ /** A till sale as the order page's "Till sale" card reads it (`orders.get`, engine sprint 19's read). */
835
+ export interface PosTillSale {
836
+ orderId: string;
837
+ orderCode: string;
838
+ orderState: string;
839
+ receiptNumber: string | null;
840
+ placedAt: string | null;
841
+ customerKind: string;
842
+ deviceId: string | null;
843
+ deviceLabel: string | null;
844
+ registerId: string | null;
845
+ registerName: string | null;
846
+ sessionId: string | null;
847
+ staffId: string | null;
848
+ staffName: string | null;
849
+ /** Every payment, oldest first, failed and cancelled ones included. */
850
+ payments: PosTillSalePayment[];
851
+ /**
852
+ * The in-person ID check standing for the sale (engine user decision L1): "ID checked by
853
+ * `staffName` at `checkedAt`". Null when none was recorded, or the one recorded was voided when
854
+ * the sale was held and resumed.
855
+ */
856
+ idCheck: PosTillSaleIdCheck | null;
857
+ }
858
+ export interface PosOrdersModule {
859
+ /**
860
+ * The store's completed till sales for a back office, newest first, every register and every
861
+ * kind of till (engine sprint 27, `posOrders`). `fromDay`/`toDay` are the STORE's calendar
862
+ * days (`YYYY-MM-DD`, inclusive, both today when omitted, at most 31 days apart); `registerId`,
863
+ * `sessionId`, `deviceId`, `staffId`, `tender` and `term` narrow it on the server, each sent
864
+ * only when given. `limit` is at most 100 (50 when omitted); `after` is the previous page's
865
+ * cursor. Refused `POS_LIST_RANGE_INVALID` (`extensions.reason`: `day_format`, `day_order`,
866
+ * `span_too_long`, `term_too_long`). Needs `UpdateSettings` or `ManagePosDevices` AND
867
+ * `ReadOrder` (else `FORBIDDEN`): the rows name customers. A location-restricted credential
868
+ * lists the sales of its locations only. An engine before 27 refuses the document at
869
+ * validation.
870
+ *
871
+ * @effect read
872
+ */
873
+ list(options?: PosOrderListOptions): Promise<Page<PosOrderSummary>>;
874
+ /**
875
+ * One till sale with its receipt number, till, register, drawer session, cashier and per
876
+ * payment what was refunded and may still be (engine sprint 19's `posTillOrder`). An order no
877
+ * till sold is refused `POS_ORDER_UNSTAMPED`: call it only when `sale.tillDetails` says
878
+ * `isPosOrder`. Another store's order, or none, is `ENTITY_NOT_FOUND`. Needs `ReadOrder`.
879
+ * A sale a machine credential rang up (no paired till on it) answers only that credential at
880
+ * its own location: any other caller, a back office included, is refused
881
+ * `POS_PRINCIPAL_REQUIRED`. `idCheck` is the cashier's in-person ID check of the sale
882
+ * (engine user decision L1); an engine before it is read with the sale's other fields only, and
883
+ * answers `idCheck: null`.
884
+ *
885
+ * @effect read
886
+ */
887
+ get(orderId: string, options?: Call): Promise<PosTillSale>;
888
+ }
889
+ /** A store day's state (engine sprint 26). More may come: a reader shows an unknown one as it is. */
890
+ export type PosStoreDayStatus = 'open' | 'closed' | 'reopened';
891
+ /**
892
+ * A store day's money, rolled up from its drawers' Zs (engine sprint 26): integer minor units of
893
+ * the store's default currency. Over the day's CLOSED drawers: their floats, expected cash and
894
+ * tender totals; the counted cash and the variance over the COUNTED ones only.
895
+ */
896
+ export interface PosStoreDayTotals {
897
+ currencyCode: string;
898
+ /** The Zs rolled up: the day's closed drawers. */
899
+ sessionCount: number;
900
+ /** Drawers closed without a count and not counted since. */
901
+ uncountedCount: number;
902
+ openingFloat: number;
903
+ expectedCash: number;
904
+ /** Over the counted drawers only. */
905
+ countedCash: number;
906
+ /** Over the counted drawers only: negative short, positive over. */
907
+ cashOverShort: number;
908
+ cash: number;
909
+ card: number;
910
+ other: number;
911
+ refunds: number;
912
+ net: number;
913
+ saleCount: number;
914
+ cashRefunds: number;
915
+ cardRefunds: number;
916
+ otherRefunds: number;
917
+ cashRounding: number;
918
+ }
919
+ /** One drawer of a store day, as its Z says (engine sprint 26). */
920
+ export interface PosStoreDaySession {
921
+ sessionId: string;
922
+ registerId: string;
923
+ /** The register's name now; null when it is gone. */
924
+ registerName: string | null;
925
+ /** The register's Z number; null while open and for drawers closed before sprint 26. */
926
+ zNumber: number | null;
927
+ status: 'open' | 'closed';
928
+ /** How it closed; null while open. */
929
+ closeSource: PosCloseSource | null;
930
+ openedAt: string;
931
+ closedAt: string | null;
932
+ openingFloat: number;
933
+ expectedCash: number | null;
934
+ /** Null while open and for a drawer closed without a count. */
935
+ countedCash: number | null;
936
+ cashOverShort: number | null;
937
+ varianceApproval: PosVarianceApproval | null;
938
+ /** The stored Z's tender totals; null while open. */
939
+ totals: PosStoredSessionTotals | null;
940
+ }
941
+ /**
942
+ * A store's business day at one stock location, as `days.list` reads it (engine sprint 26):
943
+ * everything but its drawers and the closer's and reopener's names, which `days.get` reads.
944
+ */
945
+ export interface PosStoreDaySummary {
946
+ /** Null for a day no drawer opened on and nobody closed (it has no record yet). */
947
+ id: string | null;
948
+ stockLocationId: string;
949
+ /** `YYYY-MM-DD`: the store's business day (it starts at the store's day start, not midnight). */
950
+ businessDay: string;
951
+ /** The IANA zone the day is counted in. */
952
+ timeZone: string;
953
+ /** The day's window: from its start to the next day's start (23, 24 or 25 hours). */
954
+ startsAt: string;
955
+ endsAt: string;
956
+ status: PosStoreDayStatus;
957
+ /** True: `totals` is the roll-up stored at the close (refreshed by a later count); false: computed now. */
958
+ totalsFinal: boolean;
959
+ totals: PosStoreDayTotals;
960
+ /** Drawers of the day still open: the day does not close while there is one. */
961
+ openSessionCount: number;
962
+ /** Drawers whose variance waits for a manager (`sessions.approveClose`), read now. */
963
+ pendingCount: number;
964
+ /** Drawers closed without a count and not counted since (`sessions.count`), read now. */
965
+ uncountedCount: number;
966
+ closedAt: string | null;
967
+ /** The person who closed it last (a User id); null for a machine credential and before. */
968
+ closedByUserId: string | null;
969
+ /** The machine credential that closed it last (`api_token:<id>` / `app_installation:<id>`). */
970
+ closedByCredential: string | null;
971
+ closeNote: string | null;
972
+ /** How many times it was closed: 0 before its first close, 2 after a reopen and a close again. */
973
+ closeCount: number;
974
+ reopenedAt: string | null;
975
+ reopenedByUserId: string | null;
976
+ reopenNote: string | null;
977
+ }
978
+ /** A store's business day with its drawers and names, as `days.get`, `close` and `reopen` read it. */
979
+ export interface PosStoreDay extends PosStoreDaySummary {
980
+ /** The day's drawers, by register name, then Z number. */
981
+ sessions: PosStoreDaySession[];
982
+ /** The closer's name as the store's administrators hold it now; null when unknown or not a person. */
983
+ closedByUserName: string | null;
984
+ reopenedByUserName: string | null;
985
+ }
986
+ /**
987
+ * A location's business days, closed and reopened in the back office (engine sprint 26e). A day
988
+ * is the store's business day at ONE stock location (each location's own zone, the store's day
989
+ * start); its drawers are the ones that opened in it. Every call needs `UpdateSettings` or
990
+ * `ManagePosDevices` (a `pos` token holding only `OperatePos` is `FORBIDDEN`); a credential
991
+ * restricted to other locations is refused `LOCATION_NOT_ALLOWED`. Each is its own document: an
992
+ * engine before 26 refuses only these, at validation (`GRAPHQL_VALIDATION_FAILED`).
993
+ */
994
+ export interface PosDaysModule {
995
+ /**
996
+ * One business day at a location, with its drawers (by register name, then Z number), its
997
+ * totals (the roll-up stored at its close when `totalsFinal`, else computed now from the
998
+ * drawers' Zs), its open, pending and uncounted drawers counted now, and who closed or reopened
999
+ * it, by name. Any valid day answers, one with no record as `open` with `id` null. Refused
1000
+ * `POS_STORE_DAY_INVALID` (`extensions.reason`: `day_format`, or `location_unknown` for a
1001
+ * location where no register, day or drawer of the store stands).
1002
+ */
1003
+ get(input: {
1004
+ stockLocationId: string;
1005
+ businessDay: string;
1006
+ }, options?: Call): Promise<PosStoreDay>;
1007
+ /**
1008
+ * A location's business days from `fromDay` to `toDay` (`YYYY-MM-DD`, inclusive; both the
1009
+ * business day today when omitted; at most 31 days apart), newest first: the days with a drawer
1010
+ * or a record only, each with its totals and counts, never its drawers or names (read them with
1011
+ * `get`). Returned whole. Refused `POS_LIST_RANGE_INVALID` (`extensions.reason`: `day_format`,
1012
+ * `day_order`, `span_too_long`) and `POS_STORE_DAY_INVALID` (`location_unknown`).
1013
+ */
1014
+ list(input: {
1015
+ stockLocationId: string;
1016
+ fromDay?: string;
1017
+ toDay?: string;
1018
+ }, options?: Call): Promise<Page<PosStoreDaySummary>>;
1019
+ /**
1020
+ * Close a business day at a location: every drawer of the day must be closed; drawers closed
1021
+ * without a count or waiting for a manager are not blocking (the day lists them). Stores the
1022
+ * day's totals and who closed it, with the optional note; from then on no drawer opens on that
1023
+ * day (a till is refused `POS_STORE_DAY_CLOSED`). Idempotent by state: closing a closed day
1024
+ * answers it unchanged and writes nothing, so a lost answer is safe to retry. Refusals:
1025
+ * `POS_STORE_DAY_SESSIONS_OPEN` (`extensions.sessionIds`, `registerIds`: close them at the
1026
+ * till or with `sessions.closeUncounted` first), `POS_STORE_DAY_INVALID` (`extensions.reason`:
1027
+ * `day_format`, `future`, `location_unknown`), `POS_CLOSE_NOTE_INVALID` (at most 500
1028
+ * characters once trimmed). A later `sessions.count` of one of its drawers refreshes the stored
1029
+ * totals.
1030
+ */
1031
+ close(input: {
1032
+ stockLocationId: string;
1033
+ businessDay: string;
1034
+ note?: string;
1035
+ }, options?: Call): Promise<PosStoreDay>;
1036
+ /**
1037
+ * Reopen a CLOSED business day, with a reason (1 to 500 characters once trimmed), so drawers
1038
+ * open on it again; its stored totals stay until it is closed again (`closeCount` + 1).
1039
+ * Refusals: `POS_STORE_DAY_NOT_CLOSED` (`extensions.status`: `open`, or `reopened` already),
1040
+ * `POS_CLOSE_NOTE_INVALID`, `POS_STORE_DAY_INVALID` (`day_format`). Needs the store's `pos`
1041
+ * grant (a lapsed store closes its days but never reopens one).
1042
+ */
1043
+ reopen(input: {
1044
+ stockLocationId: string;
1045
+ businessDay: string;
1046
+ note: string;
1047
+ }, options?: Call): Promise<PosStoreDay>;
216
1048
  }
217
1049
  /** A till cart — a draft order — as far as this module projects it. */
218
1050
  export interface PosCart {
@@ -234,7 +1066,23 @@ export interface PosCart {
234
1066
  quantity: number;
235
1067
  productVariantId: string;
236
1068
  linePriceWithTax: number;
1069
+ /**
1070
+ * A custom item's name (sprint 16b), null on a catalogue line. Present on carts answered by
1071
+ * {@link PosSaleModule.addCustomItem}; absent on the others, which do not select it.
1072
+ */
1073
+ customItemName?: string | null;
1074
+ /**
1075
+ * The line's note (sprint 16c), null when it has none. Present on carts answered by
1076
+ * {@link PosSaleModule.setOrderNote} and {@link PosSaleModule.setLineNote}; absent on the
1077
+ * others, which do not select it.
1078
+ */
1079
+ note?: string | null;
237
1080
  }>;
1081
+ /**
1082
+ * The sale's note (sprint 16c), null when it has none. Present on carts answered by the note
1083
+ * methods only, as the lines' `note`.
1084
+ */
1085
+ note?: string | null;
238
1086
  surcharges: Array<{
239
1087
  description: string;
240
1088
  sku: string;
@@ -243,6 +1091,32 @@ export interface PosCart {
243
1091
  taxRate: number;
244
1092
  }>;
245
1093
  }
1094
+ /**
1095
+ * What a till wrote on a sale, for a back office reading the order (sprint 16d): the sale's note
1096
+ * and, per line, its custom item name and its note. Every order answers it; one the till did not
1097
+ * sell has `isPosOrder: false` and nothing else set.
1098
+ */
1099
+ export interface PosTillSaleDetails {
1100
+ orderId: string;
1101
+ /** The order was sold at a till. */
1102
+ isPosOrder: boolean;
1103
+ /** The sale's note, null when it has none. May name a customer: customer data. */
1104
+ note: string | null;
1105
+ /** Every line of the order, in the order's own order. */
1106
+ lines: Array<{
1107
+ id: string;
1108
+ /** A custom item's name, null on a catalogue line: the till's name for what it sold. */
1109
+ customItemName: string | null;
1110
+ /** The line's note, null when it has none. Customer data, as the sale's note. */
1111
+ note: string | null;
1112
+ }>;
1113
+ /**
1114
+ * Present (`true`) when the caller's customer-data level blanked a field of this answer: an
1115
+ * app installation below `customerData: full` reads the notes as null, which is then not "no
1116
+ * note".
1117
+ */
1118
+ redacted?: true;
1119
+ }
246
1120
  export interface CompletedPosSale {
247
1121
  orderId: string;
248
1122
  orderCode: string;
@@ -315,6 +1189,89 @@ export interface PosSaleModule {
315
1189
  orderId: string;
316
1190
  couponCode: string;
317
1191
  }, options?: Call): Promise<PosCart>;
1192
+ /**
1193
+ * Add a custom item (sprint 16b): a line you name and price, sold on one of the store's custom
1194
+ * item tax categories (`settings.customItemPolicy().taxCategories`). The unit price is in minor
1195
+ * units of the cart's currency on the ORDER's price basis: its first line's, else the store's
1196
+ * (`amountsIncludeTax`: gross on an inclusive store). The two differ only on an inclusive store's
1197
+ * cart taxed in another zone (an attached customer from a tax-exclusive country), whose lines are
1198
+ * net. The engine states it on the line and core taxes it from the category in the order's zone,
1199
+ * so you never compute tax. Only in the store's default currency, at least 1, at
1200
+ * most the store's `maxUnitPrice`; quantity 1 to 999 (1 when omitted); a name of 1 to 80
1201
+ * characters on one line, printed on the receipt and invoice.
1202
+ *
1203
+ * Above the store's `cashierLimit` a manager approves it. A machine principal's credential IS
1204
+ * the manager (a person minted it), so a `pos` token is never asked. A paired till's cashier
1205
+ * passes a manager's single-use `approvalToken` (a `posStaffLogin` with purpose `APPROVAL`),
1206
+ * which the engine spends only when the item is added. The price of a custom line is fixed:
1207
+ * correct it by removing the line and adding the item again.
1208
+ *
1209
+ * Refusals: `POS_CUSTOM_ITEM_INVALID` (`field`), `POS_CUSTOM_ITEMS_DISABLED` (`reason`: `store`,
1210
+ * or `host` for an engine that cannot), `POS_CUSTOM_ITEM_CURRENCY_UNSUPPORTED`,
1211
+ * `POS_CUSTOM_ITEM_TAX_CATEGORY_UNAVAILABLE` (`reason`: `not_listed` or `no_rate`),
1212
+ * `POS_CUSTOM_ITEM_PRICE_ABOVE_MAX` (`maxUnitPrice`), `POS_MANAGER_REQUIRED`
1213
+ * (`customItemLimit`, `unitPrice`), and the cart doors' own (`POS_ORDER_NOT_EDITABLE`, …). Takes
1214
+ * `options.idempotencyKey` (required: a fresh UUIDv7 per item): a retry answers the cart as it is
1215
+ * now, never a second line.
1216
+ */
1217
+ addCustomItem(input: {
1218
+ orderId: string;
1219
+ name: string;
1220
+ unitPrice: number;
1221
+ taxCategoryId: string;
1222
+ quantity?: number;
1223
+ }, options: PosMoneyCall & {
1224
+ staffToken?: string;
1225
+ approvalToken?: string;
1226
+ }): Promise<PosCart>;
1227
+ /**
1228
+ * Set or remove the sale's note (sprint 16c): one line printed on the receipt, at most 280
1229
+ * characters; `null` or a blank string removes it. Any staff member (a paired till's cashier
1230
+ * passes `staffToken`; a `pos` token needs none), on an open till cart opened at your location,
1231
+ * a cart readied for payment included: a note changes no money. A cashier may type a customer's
1232
+ * name into it, so treat it as customer data: the engine never writes the text to its audit
1233
+ * trail. Refused `POS_NOTE_INVALID` (`field`, `maxLength`: too long, or a line break or other
1234
+ * control character), `POS_CART_HELD`, and the cart doors' own (`POS_ORDER_NOT_EDITABLE`, …).
1235
+ * Takes `options.idempotencyKey` (required): a retry answers the cart as it is now. The cart it
1236
+ * answers carries `note` and each line's `note` and `customItemName`.
1237
+ */
1238
+ setOrderNote(input: {
1239
+ orderId: string;
1240
+ note: string | null;
1241
+ }, options: PosMoneyCall & {
1242
+ staffToken?: string;
1243
+ }): Promise<PosCart>;
1244
+ /**
1245
+ * Set or remove one line's note (sprint 16c): printed under the line, at most 140 characters;
1246
+ * the rules of {@link PosSaleModule.setOrderNote}. A line that is not on the cart is
1247
+ * `POS_ORDER_LINE_NOT_FOUND`. A line with a note is never merged with a later add of the same
1248
+ * variant: that add is a line of its own.
1249
+ */
1250
+ setLineNote(input: {
1251
+ orderId: string;
1252
+ lineId: string;
1253
+ note: string | null;
1254
+ }, options: PosMoneyCall & {
1255
+ staffToken?: string;
1256
+ }): Promise<PosCart>;
1257
+ /**
1258
+ * Clear the sale (sprint 16c): the unpaid till draft is DELETED with its lines, discounts,
1259
+ * coupons, notes and the attached customer, so the till is free for the next customer. Never
1260
+ * cancelled (no cancellation email). Any staff member, no manager. Refused
1261
+ * `POS_CART_NOT_CLEARABLE` with `reason` `readied` (it started taking payment), `payment` (it has
1262
+ * a payment record of any state: finish it, or refund it) or `open_key` (a payment on the store
1263
+ * may still be in progress: wait and try again); `POS_CART_HELD` (resume it first); and the cart
1264
+ * doors' own (`POS_ORDER_NOT_EDITABLE` for a placed order, …). Answers the deleted sale's id and
1265
+ * code. Takes `options.idempotencyKey` (required). A retry after the clear succeeded (its answer
1266
+ * lost) finds no order, `ENTITY_NOT_FOUND`: re-read the order (`orders.get(orderId)`), and a
1267
+ * sale that is no longer there was cleared.
1268
+ */
1269
+ clearCart(orderId: string, options: PosMoneyCall & {
1270
+ staffToken?: string;
1271
+ }): Promise<{
1272
+ orderId: string;
1273
+ orderCode: string;
1274
+ }>;
318
1275
  /**
319
1276
  * Finalise a fully paid sale: settles the order, debits your location's
320
1277
  * stock through its fulfillment profile (none at that location is
@@ -323,6 +1280,207 @@ export interface PosSaleModule {
323
1280
  complete(orderId: string, options: PosMoneyCall & {
324
1281
  staffToken?: string;
325
1282
  }): Promise<CompletedPosSale>;
1283
+ /**
1284
+ * What the till wrote on an order (sprint 16d), for a back office showing it: the sale's note,
1285
+ * and each line's custom item name and note. Reads any order of the store, sold at a till or
1286
+ * not (`isPosOrder`); null when the store holds no order with that id. Needs `ReadOrder`, like
1287
+ * `orders.get`. Its own read rather than a block of `orders.get`, because an engine before
1288
+ * sprint 16c has none of these fields: there it is refused `GRAPHQL_VALIDATION_FAILED`, and an
1289
+ * order page that reads it beside `orders.get` keeps working.
1290
+ */
1291
+ tillDetails(orderId: string, options?: Call): Promise<PosTillSaleDetails | null>;
1292
+ /**
1293
+ * A completed till sale's receipt (engine sprint 22): ONE structured document, money in minor
1294
+ * units of `currencyCode`, every row core's own figure, so it adds up in both tax displays
1295
+ * (`subtotal` + `adjustments` [+ `taxes` when `EXCLUSIVE`] = `total`, the billable total). It
1296
+ * carries no words of its own: label the rows and lay them out yourself, by their `kind` (each
1297
+ * row kind, adjustment kind and tender kind is one label in your own vocabulary). `kind` is
1298
+ * `SALE` today; read an unknown one as a sale. Who may read it is the till's
1299
+ * sale read rule: a paired till any till sale of the store, a `pos` API token a sale of its
1300
+ * verified location, staff with `ReadOrder`. Refusals: `POS_RECEIPT_NOT_AVAILABLE` (the sale is
1301
+ * not completed), `POS_ORDER_UNSTAMPED` (no till opened the order), `ENTITY_NOT_FOUND`. Below
1302
+ * the `full` customer-data level the notes are withheld (`redacted: true`). An engine before 22
1303
+ * refuses the document at validation.
1304
+ */
1305
+ receipt(orderId: string, options?: Call): Promise<PosReceipt & {
1306
+ redacted?: true;
1307
+ }>;
1308
+ /**
1309
+ * Email a completed till sale's receipt through the store's own email (engine sprint 22c): the
1310
+ * POS Receipt notification's template, gateway, styles and logo, logged under Settings, Emails,
1311
+ * Deliveries. To `emailAddress` alone (no configured CC/BCC), or, omitted, to the sale's
1312
+ * customer (never the till's walk-in). Once per `options.idempotencyKey` (required; a retry
1313
+ * answers the first answer and sends nothing); a paired till signs with `staffToken`. The engine
1314
+ * keeps no address: the answer says where it came from (`source`: `typed`/`customer`) and how
1315
+ * many receipt emails the sale had in 24 hours. Refusals: `POS_RECEIPT_EMAIL_INVALID`,
1316
+ * `POS_RECEIPT_EMAIL_NO_ADDRESS`, `POS_RECEIPT_EMAIL_LIMIT` (`limit` sale or till,
1317
+ * `retryAfterSeconds`: 5 per sale a day, 30 per till an hour by default),
1318
+ * `POS_RECEIPT_EMAIL_UNAVAILABLE` (`reason` disabled or not_installed),
1319
+ * `POS_RECEIPT_NOT_AVAILABLE`, `IDEMPOTENCY_CONFLICT`. An engine before 22c refuses the document
1320
+ * at validation.
1321
+ */
1322
+ emailReceipt(input: {
1323
+ orderId: string;
1324
+ emailAddress?: string | null;
1325
+ }, options: PosMoneyCall & {
1326
+ staffToken?: string;
1327
+ }): Promise<PosEmailReceiptResult>;
1328
+ /**
1329
+ * A completed till sale's digital receipt and prints, for an order page (engine sprint 23):
1330
+ * whether the platform serves receipt pages (`available`) and the store has them on (`enabled`),
1331
+ * how long a new link lives, the RECEIPT then the GIFT link's state (`url` only while `ACTIVE`)
1332
+ * and how many copies and gift receipts were printed through `printReceipt`. Who may read it:
1333
+ * `receipt`'s rule. Refusals as `receipt`. An engine before 23 refuses the document at
1334
+ * validation.
1335
+ */
1336
+ receiptSharing(orderId: string, options?: Call): Promise<PosReceiptSharing>;
1337
+ /**
1338
+ * The sale's live link of `variant`, created when there is none or it expired (engine sprint
1339
+ * 23); a live one is answered unchanged (state-driven: no key). Anyone holding the URL can open
1340
+ * the page (the receipt without the customer, the cashier or notes; the gift receipt without a
1341
+ * price). Needs `UpdateOrder`. Refused `POS_RECEIPT_LINK_UNAVAILABLE` (`reason`:
1342
+ * `not_configured`, the platform serves no receipt pages; `disabled`, the store has digital
1343
+ * receipts off), `POS_RECEIPT_NOT_AVAILABLE`, `POS_ORDER_UNSTAMPED`.
1344
+ */
1345
+ issueReceiptLink(orderId: string, variant: PosReceiptVariant, options?: Call): Promise<PosReceiptLinkStatus>;
1346
+ /**
1347
+ * Withdraw the sale's live link of `variant` (engine sprint 23): its page stops answering at
1348
+ * once and a printed QR is dead; a new link is a new token. A sale with no live link answers its
1349
+ * status and changes nothing. Needs `UpdateOrder`; allowed without the `pos` entitlement (it only
1350
+ * removes access).
1351
+ */
1352
+ revokeReceiptLink(orderId: string, variant: PosReceiptVariant, options?: Call): Promise<PosReceiptLinkStatus>;
1353
+ /**
1354
+ * Print a receipt or a gift receipt again (engine sprint 23): the engine numbers the print and
1355
+ * answers the document to print. A `RECEIPT` print is always a copy (`receipt.copy`: its number
1356
+ * and when it was printed; lay out "COPY"); a `GIFT` print is the gift original the first time
1357
+ * and a copy from the second on, and its `giftReceipt` has no money at all. Once per
1358
+ * `options.idempotencyKey` (minted here when omitted: send your own to retry the same print and
1359
+ * get the same number back); a paired till signs with `staffToken`, staff in the back office
1360
+ * print as themselves. Refused `POS_RECEIPT_NOT_AVAILABLE`, `POS_ORDER_UNSTAMPED`,
1361
+ * `IDEMPOTENCY_CONFLICT`.
1362
+ */
1363
+ printReceipt(input: {
1364
+ orderId: string;
1365
+ variant: PosReceiptVariant;
1366
+ }, options?: Call & {
1367
+ idempotencyKey?: string;
1368
+ staffToken?: string;
1369
+ }): Promise<PosPrintReceiptResult>;
1370
+ /**
1371
+ * A completed till sale's gift receipt (engine sprint 23): the same sale without a single price,
1372
+ * with its live GIFT link. A read: nothing is printed or counted (print one with `printReceipt`).
1373
+ */
1374
+ giftReceipt(orderId: string, options?: Call): Promise<PosGiftReceipt>;
1375
+ }
1376
+ /** Which receipt a link or a print is for (engine sprint 23). */
1377
+ export type PosReceiptVariant = 'RECEIPT' | 'GIFT';
1378
+ /** A live public link to a receipt (engine sprint 23). */
1379
+ export interface PosReceiptLink {
1380
+ variant: PosReceiptVariant;
1381
+ url: string;
1382
+ issuedAt: string;
1383
+ expiresAt: string;
1384
+ }
1385
+ /** This print is a copy (engine sprint 23): lay out "COPY" with its number and instant. */
1386
+ export interface PosReceiptCopy {
1387
+ /** 1 for the first copy. */
1388
+ number: number;
1389
+ printedAt: string;
1390
+ }
1391
+ /** Where a sale's link stands (engine sprint 23). `url` only while `ACTIVE`. */
1392
+ export interface PosReceiptLinkStatus {
1393
+ variant: PosReceiptVariant;
1394
+ /** `ACTIVE`, `EXPIRED`, `REVOKED` or `NONE`; read an unknown one as not active. */
1395
+ state: string;
1396
+ url: string | null;
1397
+ issuedAt: string | null;
1398
+ expiresAt: string | null;
1399
+ revokedAt: string | null;
1400
+ /** `staff` or `erasure`; null unless `REVOKED`. */
1401
+ revokeReason: string | null;
1402
+ }
1403
+ /** A till sale's digital receipt and prints (engine sprint 23). */
1404
+ export interface PosReceiptSharing {
1405
+ /** The platform serves receipt pages (a public base URL is configured). */
1406
+ available: boolean;
1407
+ /** The store has digital receipts switched on. */
1408
+ enabled: boolean;
1409
+ /** How long a new link stays valid, in days. */
1410
+ ttlDays: number;
1411
+ /** The RECEIPT link, then the GIFT link. */
1412
+ links: PosReceiptLinkStatus[];
1413
+ /** Copies of the receipt printed through `printReceipt`. */
1414
+ receiptCopies: number;
1415
+ /** Gift receipts printed through `printReceipt` (the first is the gift original). */
1416
+ giftPrints: number;
1417
+ }
1418
+ /** A gift receipt line (engine sprint 23): what was bought, never its price. */
1419
+ export interface PosGiftReceiptLine {
1420
+ orderLineId: string;
1421
+ name: string;
1422
+ sku: string | null;
1423
+ quantity: number;
1424
+ }
1425
+ /** A gift receipt (engine sprint 23): no money field at all. */
1426
+ export interface PosGiftReceipt {
1427
+ orderId: string;
1428
+ orderCode: string;
1429
+ receiptNumber: string;
1430
+ issuedAt: string;
1431
+ language: string;
1432
+ locale: string;
1433
+ timeZone: string;
1434
+ /** The store's name, address, phone and extra lines (no VAT or registration number). */
1435
+ header: PosReceiptIdentity & {
1436
+ extraLines: string[];
1437
+ };
1438
+ registerName: string | null;
1439
+ lines: PosGiftReceiptLine[];
1440
+ footerLines: string[];
1441
+ thankYou: boolean;
1442
+ scanCode: string;
1443
+ link: PosReceiptLink | null;
1444
+ copy: PosReceiptCopy | null;
1445
+ }
1446
+ /** One print through `printReceipt` (engine sprint 23): exactly one of the two documents. */
1447
+ export interface PosPrintReceiptResult {
1448
+ orderId: string;
1449
+ variant: PosReceiptVariant;
1450
+ /** 1, 2, … per order and variant. */
1451
+ printNumber: number;
1452
+ /** True for every RECEIPT print and every GIFT print after the first. */
1453
+ copy: boolean;
1454
+ receipt: (PosReceipt & {
1455
+ link: PosReceiptLink | null;
1456
+ copy: PosReceiptCopy | null;
1457
+ }) | null;
1458
+ giftReceipt: PosGiftReceipt | null;
1459
+ }
1460
+ /** The store's digital receipts (engine sprint 23). */
1461
+ export interface PosDigitalReceiptSettings {
1462
+ /** Digital receipts are on: a link is minted at completion and its QR printed. */
1463
+ publicLink: boolean;
1464
+ /** The platform serves receipt pages; false = `publicLink` cannot be switched on. */
1465
+ publicLinkAvailable: boolean;
1466
+ }
1467
+ /** The receipt account claim (engine C3/32). */
1468
+ export interface PosReceiptAccountClaimSettings {
1469
+ /**
1470
+ * Shoppers may add a receipt to their webshop account from its page: the page links to the
1471
+ * store's storefront at `/account/claim-receipt`. Inert while digital receipts are off.
1472
+ */
1473
+ accountClaim: boolean;
1474
+ /** Digital receipts are on and the store has a storefront address: it can be switched on. */
1475
+ accountClaimAvailable: boolean;
1476
+ }
1477
+ /** A queued receipt email (engine sprint 22c). Never the address. */
1478
+ export interface PosEmailReceiptResult {
1479
+ orderId: string;
1480
+ /** `typed` or `customer`. */
1481
+ source: string;
1482
+ /** Receipt emails accepted for the sale in the last 24 hours, this one included. */
1483
+ sentForSale: number;
326
1484
  }
327
1485
  export interface PosTenderResult {
328
1486
  orderId: string;
@@ -330,7 +1488,13 @@ export interface PosTenderResult {
330
1488
  /** True once settled payments cover the order total. */
331
1489
  covered: boolean;
332
1490
  outstanding: number;
333
- /** Cash only: `tendered - amount`, floored at zero. */
1491
+ /**
1492
+ * Cash only. The tender that clears the balance on a store that rounds cash
1493
+ * (`cashRoundingMode`) is due rounded (12.33 → 12.35 on `nearest_05`), and change is
1494
+ * `tendered - rounded due`. Otherwise `tendered - amount`. Floored at zero. The difference
1495
+ * from the exact amount is recorded as the drawer's cash rounding; the payment stays the exact
1496
+ * `amount`.
1497
+ */
334
1498
  change: number;
335
1499
  }
336
1500
  export interface PosTendersModule {
@@ -351,6 +1515,16 @@ export interface PosTendersModule {
351
1515
  * {@link PosTendersModule.card} or {@link PosTendersModule.manual} instead:
352
1516
  * neither touches the drawer, so this rule does not apply to them.
353
1517
  *
1518
+ * On a store that rounds cash (`cashRoundingMode` `nearest_05` / `nearest_10`), only the
1519
+ * tender that clears the balance is rounded: its `amount` is due rounded to the store's
1520
+ * increment, and `change` is measured from that rounded due. Such a tender may hand over the
1521
+ * exact amount or the rounded one (1 and 2 cent coins stay legal tender), and `tendered` is 0
1522
+ * when the rounded due is 0 (a 0.02 balance on `nearest_05`). A partial tender
1523
+ * (one that leaves a balance) is never rounded and must hand over at least its `amount`, or it
1524
+ * is refused (`Only the cash tender that clears the balance is rounded`) and nothing is
1525
+ * taken. The payment is always the exact `amount`; the difference is the drawer's cash
1526
+ * rounding, reported on the session's stored totals.
1527
+ *
354
1528
  * The first tender of a sale asks the apps the store installed
355
1529
  * (`order.validate`) before anything is taken: a refusal is `HOOK_REJECTED`
356
1530
  * (`HookRejectedError`, with the app's `customerMessage`) or
@@ -458,7 +1632,15 @@ export interface PosRefundsModule {
458
1632
  * Hand money back against one payment of the order, never more than the order
459
1633
  * took (`REFUND_EXCEEDS_SETTLED`). Refusals that mean NO money moved:
460
1634
  * `REFUND_METHOD_UNAVAILABLE` (that payment's method is disabled or gone),
461
- * `REFUND_REFUSED` (the gateway said no, with its reason) — retry is safe.
1635
+ * `REFUND_REFUSED` (the gateway said no, with its reason) — retry is safe —
1636
+ * and `LIVE_CONNECTION_REFUSED`: a store that is not live holds a till
1637
+ * Mollie key that is not a `test_` key, so no card refund is asked of Mollie
1638
+ * until that key is replaced by a test key (`settings.setMollieApiKey`) or
1639
+ * removed; `settings.readiness()` reads `KEY_LIVE_ON_TEST_STORE` meanwhile.
1640
+ * `REFUND_REQUIRES_CREDIT_NOTE` (409): the sale has a live invoice, so its
1641
+ * refund goes back through the invoice's correction in the back office
1642
+ * (`documents.commitCorrection`, the invoice named by
1643
+ * `payments.refundCreditNoteRequirement`), never at the till.
462
1644
  *
463
1645
  * `IDEMPOTENCY_OUTCOME_UNKNOWN` is neither: the card refund reached the
464
1646
  * payment provider and then failed (no answer, a timeout, a provider error),
@@ -482,6 +1664,12 @@ export interface PosRefundsModule {
482
1664
  * `CASH_TENDER_CURRENCY_NOT_SUPPORTED` before anything moves. Refund that
483
1665
  * payment from the order in the back office instead.
484
1666
  *
1667
+ * On a store that rounds cash (`cashRoundingMode`), a refund of a CASH payment pays out the
1668
+ * `amount` cash-rounded like a sale (12.33 refunded on `nearest_05` pays out 12.35), and the
1669
+ * difference is recorded on the drawer as its cash rounding; the refund itself stays the exact
1670
+ * `amount`. The engine answers the payout as `cashPaidOut`, which this SDK version does not
1671
+ * read, so older engines keep answering: work it out with the same rounding when you need it.
1672
+ *
485
1673
  * The order must be a till's sale made at your location, and the payment one
486
1674
  * of ITS payments: an order no till opened is `POS_ORDER_UNSTAMPED`, a payment
487
1675
  * of another order `USER_INPUT_ERROR`, another store's order `ENTITY_NOT_FOUND`.
@@ -502,26 +1690,288 @@ export interface PosDevice {
502
1690
  label: string;
503
1691
  status: 'active' | 'revoked';
504
1692
  paired: boolean;
505
- /** Recorded server-side every time the tablet authenticates. */
1693
+ /** Stamped when the tablet signs in (`authenticate`) and, from engine sprint 35, at each heartbeat. */
506
1694
  lastSeenAt: string | null;
1695
+ /**
1696
+ * The Mollie card terminal (`term_…`) its card tenders go to (`devices.assignTerminal`); null
1697
+ * while none is assigned. A display holds none.
1698
+ */
1699
+ mollieTerminalId: string | null;
1700
+ createdAt: string;
1701
+ updatedAt: string;
1702
+ /**
1703
+ * The device's health columns (engine sprint 35), read by `devices.fleet`, `devices.lock` and
1704
+ * `devices.unlock`; absent from `list` and `revoke`, which keep answering an older engine. When
1705
+ * the till last sent a heartbeat; null for an app build that sends none.
1706
+ */
1707
+ heartbeatAt?: string | null;
1708
+ /** When a manager locked it (`devices.lock`); null while unlocked. */
1709
+ lockedAt?: string | null;
1710
+ /** Since when the till has been silent with a drawer open; null otherwise. */
1711
+ silentSince?: string | null;
1712
+ /**
1713
+ * What the device is (engine sprint 39): a `till` sells, a `display` shows the shopper the sale
1714
+ * of its register. Chosen at `create`, never changed. Read by `fleet`, `lock`, `unlock` and a
1715
+ * `create` that names a kind; absent elsewhere, where it is a till. More may come: treat an
1716
+ * unknown kind as neither.
1717
+ */
1718
+ kind?: PosDeviceKind | (string & {});
1719
+ }
1720
+ /** A device's kind (engine sprint 39). */
1721
+ export type PosDeviceKind = 'till' | 'display';
1722
+ /** The kinds a device is created as (engine sprint 39), in the engine's order. */
1723
+ export declare const POS_DEVICE_KINDS: readonly PosDeviceKind[];
1724
+ /** A one-time pairing code (`devices.pair`) and when it stops working (ISO-8601). */
1725
+ export interface PosPairingCode {
1726
+ code: string;
1727
+ expiresAt: string;
1728
+ }
1729
+ /** A new device (`devices.create`). */
1730
+ export interface PosDeviceCreateInput {
1731
+ label: string;
1732
+ /** The stock location it sells from (a till) or stands at (a display). */
1733
+ stockLocationId: string;
1734
+ /** The register it works at. A display shows the sale of this register's open drawer. */
1735
+ registerId?: string | null;
1736
+ /** `till` when omitted (engine sprint 39); never changes. */
1737
+ kind?: PosDeviceKind;
1738
+ }
1739
+ /**
1740
+ * A device's health as the engine judges it now (engine sprint 35): `online` (heard within 2
1741
+ * minutes), `quiet` (2 to 15), `silent` (longer, with a drawer open), `idle` (longer, no drawer
1742
+ * open), `unknown` (never sent a heartbeat: an app build before 35), and `locked`, `unpaired` or
1743
+ * `revoked`, which take precedence. More may come: show an unknown status as it is.
1744
+ */
1745
+ export type PosDeviceHealthStatus = 'online' | 'quiet' | 'silent' | 'idle' | 'unknown' | 'locked' | 'unpaired' | 'revoked';
1746
+ export interface PosDeviceHealth {
1747
+ status: PosDeviceHealthStatus | (string & {});
1748
+ /** The last heartbeat the engine stored; null when it never sent one. */
1749
+ lastHeardAt: string | null;
1750
+ silentSince: string | null;
1751
+ }
1752
+ /**
1753
+ * What a till said in its last heartbeat (engine sprint 35). Every value is the till's own claim,
1754
+ * null when it did not say. The closed values (`platform`, `connection`, `printer`) may grow: show
1755
+ * an unknown one as it is.
1756
+ */
1757
+ export interface PosDeviceHeartbeatReport {
1758
+ appVersion: string | null;
1759
+ buildNumber: string | null;
1760
+ runtimeVersion: string | null;
1761
+ updateId: string | null;
1762
+ updateChannel: string | null;
1763
+ platform: 'ios' | 'android' | 'other' | (string & {}) | null;
1764
+ /** `online` or `degraded`: a till that is offline sends nothing. */
1765
+ connection: 'online' | 'degraded' | (string & {}) | null;
1766
+ outboxPending: number | null;
1767
+ offlineSalesPending: number | null;
1768
+ offlineSalesRefused: number | null;
1769
+ printer: 'none' | 'ready' | 'unreachable' | 'unknown' | (string & {}) | null;
1770
+ reportedAt: string;
1771
+ }
1772
+ /** The drawer a till has open (engine sprint 35). */
1773
+ export interface PosDeviceOpenDrawer {
1774
+ sessionId: string;
1775
+ registerId: string;
1776
+ openedAt: string;
1777
+ /** The cashier who opened it, as the store names them now; null for a machine principal. */
1778
+ openedByStaffName: string | null;
1779
+ }
1780
+ /**
1781
+ * One device of the store with its health (engine sprint 35, `devices.fleet`). How many of its
1782
+ * offline sales wait for a manager (engine sprint 45) is its own read,
1783
+ * `devices.offlineSalesToReview`, so this row answers an engine before 45.
1784
+ */
1785
+ export interface PosDeviceFleetRow {
1786
+ device: PosDevice;
1787
+ health: PosDeviceHealth;
1788
+ /** Null until the till sends its first heartbeat. */
1789
+ report: PosDeviceHeartbeatReport | null;
1790
+ openDrawer: PosDeviceOpenDrawer | null;
1791
+ /** Who locked it, as the store's administrators name them now; null when unknown or not a person. */
1792
+ lockedByUserName: string | null;
507
1793
  }
508
- /** Paired tablets. Every method needs `ManagePosDevices` (or `UpdateSettings`). */
1794
+ /**
1795
+ * The store's tills and customer displays. Every method needs `ManagePosDevices` or
1796
+ * `UpdateSettings` (either one). A `deviceId` that is not one of this store's devices (missing, or
1797
+ * another store's) is refused `POS_DEVICE_NOT_FOUND` (`NotFoundError`); `get` and `heartbeat`
1798
+ * answer null instead.
1799
+ */
509
1800
  export interface PosDevicesModule {
1801
+ /**
1802
+ * The store's devices, newest first, whole (one page); a location-restricted credential sees
1803
+ * the devices at its locations only. Their health is `fleet`'s.
1804
+ *
1805
+ * @effect read
1806
+ */
510
1807
  list(options?: Call): Promise<Page<PosDevice>>;
511
1808
  /**
512
- * A one-time pairing code the tablet redeems; it expires. Needs a human session: an API token
513
- * is refused (`PermissionDeniedError` `TOKEN_CREDENTIAL_NOT_ALLOWED`), because the paired
514
- * device's session would outlive the token.
1809
+ * One device of the store, or null when the store has none by that id (another store's reads
1810
+ * the same, and so does, to a location-restricted credential, a device at another location).
1811
+ * Its kind and health are `fleet`'s.
1812
+ *
1813
+ * @effect read
1814
+ */
1815
+ get(deviceId: string, options?: Call): Promise<PosDevice | null>;
1816
+ /**
1817
+ * Add a device to the store; pair it afterwards with `pair`. Without `kind` it is a till, and
1818
+ * the call works against any engine. `kind: 'display'` adds a customer display (engine sprint
1819
+ * 39), which shows the shopper the sale of its register's open drawer: give it the register
1820
+ * (or assign one later), since a display without one shows nothing. A display takes no card
1821
+ * terminal (`POS_DEVICE_KIND_NOT_ALLOWED` on assigning one). A kind outside `POS_DEVICE_KINDS`
1822
+ * is refused before anything is sent (`ValidationError`, code `POS_DEVICE_KIND_INVALID`, the
1823
+ * engine's own code for it), and an engine before 39 fails the document's validation. Needs a
1824
+ * human session like `pair`: an API token is refused `TOKEN_CREDENTIAL_NOT_ALLOWED`.
1825
+ *
1826
+ * Adding a device first sets the store's POS up where it is not yet (its payment methods,
1827
+ * in-store shipping method, till role and fulfilment profile; idempotent). A location outside a
1828
+ * restricted credential's is refused `LOCATION_NOT_ALLOWED` (`PermissionDeniedError`) before
1829
+ * anything is written, and so is a caller that does not hold every permission the till will
1830
+ * carry (`POS_DEVICE_CEILING_NOT_ALLOWED`). A `registerId` is judged as
1831
+ * {@link PosDevicesModule.assignRegister} judges it, against the new device's location, before
1832
+ * the device is written.
1833
+ *
1834
+ * @effect write
1835
+ */
1836
+ create(input: PosDeviceCreateInput, options?: Call): Promise<PosDevice>;
1837
+ /**
1838
+ * Move a device to another of the store's stock locations: a till then sells from it and
1839
+ * reserves its stock. Its register moves WITH it (engine `pos-device-writes-validate`): a
1840
+ * device holding a register moves only with `options.registerId`, an active register at the new
1841
+ * location (judged as {@link PosDevicesModule.assignRegister} judges one), unless its register
1842
+ * already stands there; otherwise it is refused `POS_LOCATION_MISMATCH` (`BusinessRuleError`,
1843
+ * `reason` `device_register_elsewhere`) and nothing changes, so its drawer never stays behind at
1844
+ * the old location. A device with no register moves without one.
1845
+ *
1846
+ * Refused before anything changes: `POS_DEVICE_NOT_FOUND` (`NotFoundError`, another store's
1847
+ * reads the same), `LOCATION_NOT_ALLOWED` (`PermissionDeniedError`: the device's own location or
1848
+ * the new one outside a restricted credential's), `POS_DEVICE_REVOKED` (`BusinessRuleError`),
1849
+ * `POS_LOCATION_NOT_FOUND` (`NotFoundError`, a location the store does not have). An older
1850
+ * engine keeps the device's register as it was, answers an unknown location as a server fault,
1851
+ * and refuses a call that names `registerId` at validation (`GRAPHQL_VALIDATION_FAILED`, or a
1852
+ * 400 the transport reports as `BAD_REQUEST`); without it the document is the one every engine
1853
+ * serves.
1854
+ *
1855
+ * @effect write
1856
+ */
1857
+ assignLocation(deviceId: string, stockLocationId: string, options?: {
1858
+ registerId?: string;
1859
+ } & Call): Promise<PosDevice>;
1860
+ /**
1861
+ * The register the device's drawer sessions open on (a display shows that register's sale):
1862
+ * one of `registers.list()` that is active and stands at the device's `stockLocationId`. From
1863
+ * engine W10-62 anything else is refused before the device changes: a register the store does
1864
+ * not have `POS_REGISTER_NOT_FOUND` (`NotFoundError`, another store's reads the same), one at
1865
+ * another location `POS_LOCATION_MISMATCH` (`BusinessRuleError`; move the device there first,
1866
+ * or pick a register at its location), a retired one `POS_REGISTER_INACTIVE`
1867
+ * (`BusinessRuleError`). An older engine stores any id as sent. From engine
1868
+ * `pos-device-writes-validate` the device is judged first, as
1869
+ * {@link PosDevicesModule.assignLocation} judges it (`POS_DEVICE_NOT_FOUND`,
1870
+ * `LOCATION_NOT_ALLOWED` for a device at a location outside a restricted credential's,
1871
+ * `POS_DEVICE_REVOKED`).
1872
+ *
1873
+ * @effect write
1874
+ */
1875
+ assignRegister(deviceId: string, registerId: string, options?: Call): Promise<PosDevice>;
1876
+ /**
1877
+ * The Mollie card terminal (`term_…`, one of `terminals.list()`) the device's card tenders go
1878
+ * to. The engine does not ask Mollie about it, and one terminal may be assigned to several
1879
+ * devices. A display takes none: `POS_DEVICE_KIND_NOT_ALLOWED` (`PermissionDeniedError`).
1880
+ *
1881
+ * From engine `pos-device-writes-validate` the id is stored trimmed, and one that is empty,
1882
+ * longer than 100 characters or not one word is refused `POS_MOLLIE_TERMINAL_ID_INVALID`
1883
+ * (`ValidationError`, `reason` `empty` | `too_long` | `not_one_word`); the device is judged as
1884
+ * {@link PosDevicesModule.assignRegister} judges it. An older engine stores any text as sent.
1885
+ * Take a terminal off a device with {@link PosDevicesModule.clearTerminal}.
1886
+ *
1887
+ * @effect write
1888
+ */
1889
+ assignTerminal(deviceId: string, terminalId: string, options?: Call): Promise<PosDevice>;
1890
+ /**
1891
+ * Take the device's own card terminal off it (engine `pos-device-writes-validate`): its card
1892
+ * tenders then go to the one reader assigned to its stock location (`terminals`, Settings →
1893
+ * Payments), and are refused when the location has none or several. Clearing a device with none
1894
+ * answers it unchanged. Refused `POS_DEVICE_NOT_FOUND` (`NotFoundError`), `LOCATION_NOT_ALLOWED`
1895
+ * (`PermissionDeniedError`, a device at a location outside a restricted credential's) and
1896
+ * `POS_DEVICE_REVOKED` (`BusinessRuleError`). An older engine fails the document's validation
1897
+ * (`GRAPHQL_VALIDATION_FAILED`, or a 400 the transport reports as `BAD_REQUEST`).
1898
+ *
1899
+ * @effect write
1900
+ */
1901
+ clearTerminal(deviceId: string, options?: Call): Promise<PosDevice>;
1902
+ /**
1903
+ * The store's devices with their health, version and open drawer (engine sprint 35), grouped by
1904
+ * health status with the newest heartbeat first, whole (one page). `stockLocationId` keeps one
1905
+ * location's; a location-restricted caller sees its own locations only. The engine judges the
1906
+ * health at the time of the read: ask again for a fresh view. An engine before 35 fails the
1907
+ * document's validation (`GRAPHQL_VALIDATION_FAILED`, or a 400 the transport reports as
1908
+ * `BAD_REQUEST`); `list` keeps working there.
1909
+ *
1910
+ * @effect read
1911
+ */
1912
+ fleet(options?: {
1913
+ stockLocationId?: string;
1914
+ } & Call): Promise<Page<PosDeviceFleetRow>>;
1915
+ /**
1916
+ * How many of each device's offline sales wait for a manager (engine sprint 45, the fleet's
1917
+ * `offlineSalesToReview`: `needs_review` or `refused`, not yet handled), one row per device
1918
+ * `fleet` lists, whole (one page). Its own document, so `fleet` keeps answering an engine
1919
+ * before 45, which fails this one alone at validation (`GRAPHQL_VALIDATION_FAILED`, or a 400
1920
+ * the transport reports as `BAD_REQUEST`). The sales themselves: `offlineSales.list`.
1921
+ *
1922
+ * @effect read
1923
+ */
1924
+ offlineSalesToReview(options?: {
1925
+ stockLocationId?: string;
1926
+ } & Call): Promise<Page<PosDeviceOfflineSalesToReview>>;
1927
+ /**
1928
+ * Lock a device (engine sprint 35): every call of its session is refused `POS_DEVICE_LOCKED`
1929
+ * except its heartbeat, its cashiers' PIN sessions end, and nobody signs in on it until
1930
+ * `unlock`. Its pairing, its open drawer and the sale on its screen stay, and a card already on
1931
+ * the terminal still settles; the sale is completed after the unlock. The lock is never refused
1932
+ * for money in flight. Locking a locked device answers it unchanged. Refused `POS_DEVICE_REVOKED`
1933
+ * (`BusinessRuleError`) and `LOCATION_NOT_ALLOWED`. A store without its `pos` grant can still
1934
+ * lock a lost till.
1935
+ *
1936
+ * @effect write
1937
+ */
1938
+ lock(deviceId: string, options?: Call): Promise<PosDevice>;
1939
+ /**
1940
+ * Unlock a locked device (engine sprint 35); an unlocked one answers unchanged.
1941
+ *
1942
+ * @effect write
1943
+ */
1944
+ unlock(deviceId: string, options?: Call): Promise<PosDevice>;
1945
+ /**
1946
+ * A one-time pairing code the tablet redeems; it expires. A new code replaces any the device
1947
+ * still had. Needs a human session: an API token is refused (`PermissionDeniedError`
1948
+ * `TOKEN_CREDENTIAL_NOT_ALLOWED`), because the paired device's session would outlive the token.
1949
+ * A revoked device is refused `POS_DEVICE_REVOKED` (`BusinessRuleError`): revoke retires a
1950
+ * device for good, so add a new device to use that tablet again. A device its till unpaired is
1951
+ * still `active` and is paired again here. Refused `LOCATION_NOT_ALLOWED` at a location outside
1952
+ * a restricted credential's, and `POS_DEVICE_CEILING_NOT_ALLOWED` to a caller that does not
1953
+ * hold every permission the till will carry.
1954
+ *
1955
+ * @effect write
1956
+ */
1957
+ pair(deviceId: string, options?: Call): Promise<PosPairingCode>;
1958
+ /**
1959
+ * Retire the device for good: its token stops working at once, its tablet's sessions end, and
1960
+ * it can never be paired again (add a new device to use that tablet). There is no undo.
1961
+ * Revoking a revoked device answers it as it is. From engine `pos-device-writes-validate` a
1962
+ * device at a location outside a restricted credential's is refused `LOCATION_NOT_ALLOWED`
1963
+ * (`PermissionDeniedError`).
1964
+ *
1965
+ * @effect destructive
515
1966
  */
516
- pair(deviceId: string, options?: Call): Promise<{
517
- code: string;
518
- expiresAt: string;
519
- }>;
520
1967
  revoke(deviceId: string, options?: Call): Promise<PosDevice>;
521
1968
  /**
522
- * The device's last sign of life. There is no heartbeat WRITE for an SDK to
523
- * send: the server stamps `lastSeenAt` on every authenticated tablet request,
524
- * so this reads it.
1969
+ * The device's `lastSeenAt`: when its tablet last signed in (`authenticate`) and, from engine
1970
+ * sprint 35, when it last sent a heartbeat. It is not stamped on every request. A paired till
1971
+ * reports its health every minute through its own session, a door no SDK sends; read that report
1972
+ * with `fleet` (`health`, `report`, `device.heartbeatAt`). Null as `get` answers null.
1973
+ *
1974
+ * @effect read
525
1975
  */
526
1976
  heartbeat(deviceId: string, options?: Call): Promise<{
527
1977
  lastSeenAt: string | null;
@@ -538,6 +1988,574 @@ export interface PosReceiptNumberingModule {
538
1988
  get(options?: Call): Promise<PosReceiptNumbering>;
539
1989
  set(input: Partial<PosReceiptNumbering>, options?: Call): Promise<PosReceiptNumbering>;
540
1990
  }
1991
+ /** A store's POS settings as the setup surfaces read them. The Mollie key itself is never returned. */
1992
+ export interface PosSettings {
1993
+ /** Whether the store's tills may open sessions and take payments. */
1994
+ enabled: boolean;
1995
+ /** The till's cash payment method; null = the engine's default `pos-cash`. */
1996
+ cashPaymentMethodCode: string | null;
1997
+ /** The till's card (terminal) payment method; null = the engine's default `pos-mollie-terminal`. */
1998
+ cardPaymentMethodCode: string | null;
1999
+ inStoreShippingMethodId: string | null;
2000
+ /** Pre-fills a new device's location; the engine never reads it otherwise. */
2001
+ defaultStockLocationId: string | null;
2002
+ /** `none`, `nearest_05` or `nearest_10`; a till treats any other stored value as `none`. */
2003
+ cashRoundingMode: string;
2004
+ /** A Mollie API key is stored for the till. */
2005
+ hasMollieKey: boolean;
2006
+ /**
2007
+ * The stored key masked (`live_••••k6rW`: its mode and last four), or null: when none is stored,
2008
+ * when the engine can no longer decrypt it, and for a caller without `UpdateSettings` or
2009
+ * `ManagePosDevices` (a `pos` API token included), whatever is stored. Read `hasMollieKey` for
2010
+ * whether a key is stored.
2011
+ */
2012
+ maskedMollieApiKey: string | null;
2013
+ }
2014
+ /** A Mollie terminal the store's till key reaches, as Mollie reports it now. */
2015
+ export interface PosMollieTerminal {
2016
+ /** `term_…`: what a device is assigned. */
2017
+ terminalId: string;
2018
+ /** The name the merchant gave it in Mollie, or its id when it has none. */
2019
+ description: string;
2020
+ /** `pending` (not activated yet), `active` or `inactive`. */
2021
+ status: string;
2022
+ brand: string | null;
2023
+ model: string | null;
2024
+ serialNumber: string | null;
2025
+ currency: string | null;
2026
+ }
2027
+ /** One thing the store's tills need before they take cash and card payments. */
2028
+ export interface PosSetupCheck {
2029
+ /** `pos_enabled`, `cash_method`, `card_method`, `mollie_key`, `card_device`, `in_store_shipping`, `default_location`, `staff`, `fulfillment_profile`; more may come. */
2030
+ check: string;
2031
+ ok: boolean;
2032
+ /** False for a check the tills can trade without. */
2033
+ required: boolean;
2034
+ /** A code saying why it is not ok; null when ok. */
2035
+ reason: string | null;
2036
+ }
2037
+ /** What the store's tills still need: `ready` when every required check is ok. */
2038
+ export interface PosSetupReadiness {
2039
+ ready: boolean;
2040
+ checks: PosSetupCheck[];
2041
+ }
2042
+ /**
2043
+ * How a store rounds the cash that settles a sale: not at all, or to the nearest 5 or 10 minor units
2044
+ * of its currency (`nearest_05`: 12.33 is paid as 12.35 and 12.32 as 12.30).
2045
+ */
2046
+ export type PosCashRoundingMode = 'none' | 'nearest_05' | 'nearest_10';
2047
+ /** A tax category a custom item may use, with its rate in the store's own tax zone. */
2048
+ export interface PosCustomItemTaxCategory {
2049
+ id: string;
2050
+ name: string;
2051
+ /** Percent in the store's default tax zone; null when that zone has none for it (unusable). */
2052
+ taxRate: number | null;
2053
+ }
2054
+ /** A store's rules for custom items (sprint 16b). Money in minor units of `currencyCode`. */
2055
+ export interface PosCustomItemPolicy {
2056
+ /** The store sells custom items; off until it turns them on. */
2057
+ enabled: boolean;
2058
+ /** False when the engine cannot sell custom items at all. */
2059
+ available: boolean;
2060
+ /** The categories a custom item may use, in the store's order. */
2061
+ taxCategories: PosCustomItemTaxCategory[];
2062
+ /** Every category the store could list, for a settings form. */
2063
+ taxCategoryChoices: PosCustomItemTaxCategory[];
2064
+ /** The highest unit price; 0 until set. */
2065
+ maxUnitPrice: number;
2066
+ /** The highest unit price a cashier sells without a manager; 0: a manager approves each one. */
2067
+ cashierLimit: number;
2068
+ /** The amounts include tax (the store's price basis). */
2069
+ amountsIncludeTax: boolean;
2070
+ /** The store's default currency: custom items are sold only in it. */
2071
+ currencyCode: string;
2072
+ }
2073
+ /** What `setCustomItemPolicy` changes: an omitted field keeps its value; `taxCategoryIds` replaces the list. */
2074
+ export interface PosCustomItemPolicyInput {
2075
+ enabled?: boolean;
2076
+ taxCategoryIds?: string[];
2077
+ maxUnitPrice?: number;
2078
+ cashierLimit?: number;
2079
+ }
2080
+ /** Needs `UpdateSettings` to write; `get` needs any session of the store. */
2081
+ export interface PosSettingsModule {
2082
+ /** The store's POS settings, or null when POS was never set up. */
2083
+ get(options?: Call): Promise<PosSettings | null>;
2084
+ /**
2085
+ * Store the till's Mollie API key (encrypted at rest; never readable again). The key is trimmed;
2086
+ * an empty one is refused here (`TypeError`) — remove it with `removeMollieApiKey`. Sending the
2087
+ * masked value back keeps the stored key. Refusals: `LIVE_CONNECTION_REFUSED` (a store that is not
2088
+ * live takes only a `test_` key), `SECRET_ARG_MASK_INVALID`, `APP_SECRET_ARG_NOT_ALLOWED` (an app
2089
+ * installation), `ORGANIZATION_WORKSPACE_NOT_A_STORE`, `POS_ENCRYPTION_NOT_CONFIGURED` (the engine
2090
+ * cannot store a card key yet: its operator must configure it; a non-retryable 500, nothing
2091
+ * stored, and `settings.readiness()` reports it as the `mollie_key` reason
2092
+ * `ENCRYPTION_NOT_CONFIGURED`). Replacing it does not move payments already
2093
+ * taken: a card payment or refund of a payment made under a key of ANOTHER Mollie account can no
2094
+ * longer be read or refunded through the till.
2095
+ */
2096
+ setMollieApiKey(apiKey: string, options?: Call): Promise<PosSettings>;
2097
+ /** Remove the stored key: card payments and card refunds at the till stop until one is set again. */
2098
+ removeMollieApiKey(options?: Call): Promise<PosSettings>;
2099
+ /**
2100
+ * Set how the cash that settles a sale is rounded (`nearest_05`: 12.33 is paid as 12.35). Only the
2101
+ * cash tender that clears the balance is rounded, and the customer may still pay the exact amount;
2102
+ * card payments and the order total are never rounded, and the difference is recorded on the
2103
+ * drawer as cash rounding. Sends the mode alone. Refusals: `POS_CASH_ROUNDING_MODE_INVALID` (not
2104
+ * one of the three), `POS_CASH_ROUNDING_SESSION_OPEN` (a register session of the store is open:
2105
+ * close it on the till first; the message says how many are open). Setting the stored mode again
2106
+ * is never refused. Needs `UpdateSettings`. An engine older than these checks stores the mode
2107
+ * without them.
2108
+ */
2109
+ setCashRoundingMode(mode: PosCashRoundingMode, options?: Call): Promise<PosSettings>;
2110
+ /**
2111
+ * What the tills still need (no provider is asked). Needs `UpdateSettings` or `ManagePosDevices`.
2112
+ * The tills judged are the POS app's paired devices: `card_device` counts an active, paired
2113
+ * device on a register that reaches a terminal. A till your own backend runs with a `pos` API token (no device)
2114
+ * is not judged, so a store with no paired device reads `NO_ACTIVE_DEVICE` and not `ready`.
2115
+ */
2116
+ readiness(options?: Call): Promise<PosSetupReadiness>;
2117
+ /**
2118
+ * The store's cash controls at the till's close (engine sprint 25b): whether the till counts
2119
+ * blind, and the variance threshold (minor units of the drawer's currency) above which a close
2120
+ * needs a manager's approval, at the close or later. Null when POS was never set up; the engine
2121
+ * then closes with its defaults (blind off, threshold 0: every variance needs a manager). Any
2122
+ * session of the store reads it. An engine before 25b refuses the document at validation.
2123
+ */
2124
+ cashControls(options?: Call): Promise<PosCashControls | null>;
2125
+ /**
2126
+ * Set the store's cash controls; they apply from the next close, open drawers included.
2127
+ * `varianceThreshold`: whole minor units from 0 to 100000000, `null` for never, omitted to keep
2128
+ * the stored one (0 makes every variance need a manager). Refusals: `POS_CASH_CONTROLS_INVALID`
2129
+ * (out of range), `ORGANIZATION_WORKSPACE_NOT_A_STORE`. Needs `UpdateSettings`. An engine
2130
+ * before 25b refuses the document at validation.
2131
+ */
2132
+ setCashControls(input: PosCashControlsInput, options?: Call): Promise<PosCashControls>;
2133
+ /**
2134
+ * The store's business day and the automatic close of forgotten drawers (engine sprint 26): when
2135
+ * its day starts and when it closes (`HH:MM` on each location's wall clock), and after how many
2136
+ * minutes a drawer left open is closed without a count. Null when POS was never set up; the
2137
+ * engine then runs with its defaults (00:00, no closing time, 120 minutes after it, 24 hours
2138
+ * idle). Any session of the store reads it. An engine before 26 refuses the document at
2139
+ * validation.
2140
+ */
2141
+ dayControls(options?: Call): Promise<PosDayControls | null>;
2142
+ /**
2143
+ * Set the store's day controls, all at once (engine sprint 26). A new day start applies to
2144
+ * drawers opened after it: an open drawer keeps the business day it was stamped with. An omitted
2145
+ * or null `closingTime` is no closing time (no closing-time auto-close); an omitted
2146
+ * `autoCloseIdleMinutes` keeps the stored one, `null` switches the idle close off. Refused
2147
+ * `POS_DAY_CONTROLS_INVALID` (a `ValidationError`; `error.details[0].field` names the control,
2148
+ * `extensions.reason` is `time_format`, `day_start_out_of_range`, `after_closing_out_of_range`
2149
+ * or `idle_out_of_range`): times are `HH:MM`, the day starts 00:00 to 12:00, the grace is 30 to
2150
+ * 1440 minutes, the idle time 120 to 10080. Also `ORGANIZATION_WORKSPACE_NOT_A_STORE`. Needs
2151
+ * `UpdateSettings`; setting what is stored writes nothing.
2152
+ */
2153
+ setDayControls(input: PosDayControlsInput, options?: Call): Promise<PosDayControls>;
2154
+ /** The store's custom item rules (sprint 16b), with every category it could list. Any staff session. */
2155
+ customItemPolicy(options?: Call): Promise<PosCustomItemPolicy>;
2156
+ /**
2157
+ * Change the store's custom item rules (sprint 16b); needs `UpdateSettings`. Refused
2158
+ * `POS_CUSTOM_ITEM_POLICY_INVALID` (`field`; `taxCategoryId` for a category that does not exist or
2159
+ * has no rate in the store's tax zone): at most 20 categories, each once; amounts 0 to
2160
+ * 2147483647; turning it on needs a category and a `maxUnitPrice` of at least 1. A change that
2161
+ * changes nothing writes nothing.
2162
+ */
2163
+ setCustomItemPolicy(input: PosCustomItemPolicyInput, options?: Call): Promise<PosCustomItemPolicy>;
2164
+ /**
2165
+ * The store's receipt settings (engine sprint 22): which of the store's details print at the top
2166
+ * (`identity` is what the platform holds, edited under the store's details, never here), its
2167
+ * extra header and footer lines, and how tax shows. `configured: false` for a store that never
2168
+ * saved them: its receipt prints as before. Null when POS was never set up. Any staff session
2169
+ * of the store reads it. An engine before 22 refuses the document at validation.
2170
+ */
2171
+ receipt(options?: Call): Promise<PosReceiptSettings | null>;
2172
+ /**
2173
+ * Change the store's receipt settings; an omitted field keeps its value. `footerLines: null`
2174
+ * prints the receipt's own thank-you line, `[]` no footer. Refusals:
2175
+ * `POS_RECEIPT_SETTINGS_INVALID` with `field` (`headerLines`, `footerLines`, `taxDisplay`: more
2176
+ * than 4 lines, a line over 48 characters or holding a tab or a line break),
2177
+ * `ORGANIZATION_WORKSPACE_NOT_A_STORE`. A change that changes nothing writes nothing. Needs
2178
+ * `UpdateSettings`. An engine before 22 refuses the document at validation.
2179
+ */
2180
+ setReceipt(input: PosReceiptSettingsInput, options?: Call): Promise<PosReceiptSettings>;
2181
+ /**
2182
+ * A sample sale's receipt with these settings over the stored ones (nothing is written), for a
2183
+ * preview, laid out as you lay out `sale.receipt`. Refused `POS_RECEIPT_SETTINGS_INVALID` as the save
2184
+ * would be. Needs `UpdateSettings` or `ManagePosDevices`. An engine before 22 refuses the
2185
+ * document at validation.
2186
+ */
2187
+ previewReceipt(input?: PosReceiptSettingsInput, options?: Call): Promise<PosReceipt>;
2188
+ /**
2189
+ * The store's digital receipts (engine sprint 23): on or off, and whether the platform serves
2190
+ * receipt pages at all. Its own read, so `receipt()` keeps working on an engine before 23 (this
2191
+ * one is refused there at validation). Null when POS was never set up. Switch it with
2192
+ * `setReceipt({ publicLink })`.
2193
+ */
2194
+ digitalReceipts(options?: Call): Promise<PosDigitalReceiptSettings | null>;
2195
+ /**
2196
+ * The receipt account claim (engine C3/32): on or off, and whether it can be switched on (digital
2197
+ * receipts on and a storefront address). Its own read, so `digitalReceipts()` keeps working on
2198
+ * an engine before C3 (this one is refused there at validation). Null when POS was never set
2199
+ * up. Switch it with `setReceipt({ accountClaim })`.
2200
+ */
2201
+ receiptAccountClaim(options?: Call): Promise<PosReceiptAccountClaimSettings | null>;
2202
+ /**
2203
+ * The store's offline cash sales (engine sprint 45): whether its tills may keep selling for cash
2204
+ * while offline (off until a manager turns it on), the three limits, and whether the store can
2205
+ * sell offline now (`ready`; `notReadyReasons` says why not: `prices_exclude_tax`,
2206
+ * `automatic_promotions`, `no_cash_method`, `pos_disabled`, more may come). A till sells offline
2207
+ * only on a store that is switched on AND ready. Null when POS was never set up (the defaults
2208
+ * apply: off). Any staff session of the store reads it. Its own document: an engine before 45
2209
+ * refuses it at validation, and every other settings read keeps working.
2210
+ */
2211
+ offlineCashSales(options?: Call): Promise<PosOfflineCashSales | null>;
2212
+ /**
2213
+ * Set the store's offline cash sales, every field at once, each within
2214
+ * `POS_OFFLINE_CASH_SALES_LIMITS` (the sale amount in minor units of the store's default
2215
+ * currency). Switching on is allowed on a store that is not ready: its tills sell offline once it
2216
+ * is. Refused `POS_OFFLINE_POLICY_INVALID` (`ValidationError`; `details[0].field` names the
2217
+ * limit, `extensions.min`/`max` its bounds) and `ORGANIZATION_WORKSPACE_NOT_A_STORE`. Needs
2218
+ * `UpdateSettings`. An engine before 45 refuses the document at validation.
2219
+ */
2220
+ setOfflineCashSales(input: PosOfflineCashSalesInput, options?: Call): Promise<PosOfflineCashSales>;
2221
+ }
2222
+ /** How tax shows on a receipt (engine sprint 22). */
2223
+ export type PosReceiptTaxDisplay = 'INCLUSIVE' | 'EXCLUSIVE';
2224
+ /** The store's details as the platform holds them (what a receipt's header may print). */
2225
+ export interface PosReceiptIdentity {
2226
+ storeName: string | null;
2227
+ addressLines: string[];
2228
+ phone: string | null;
2229
+ vatNumber: string | null;
2230
+ registrationNumber: string | null;
2231
+ }
2232
+ /** The store's receipt settings (engine sprint 22). */
2233
+ export interface PosReceiptSettings {
2234
+ /** False for a store that never saved them: its receipt prints as before. */
2235
+ configured: boolean;
2236
+ showStoreName: boolean;
2237
+ showAddress: boolean;
2238
+ showPhone: boolean;
2239
+ /** The VAT number and the registration number. */
2240
+ showVatNumber: boolean;
2241
+ /** At most 4 lines of at most 48 characters under the store's details. */
2242
+ headerLines: string[];
2243
+ /** At most 4 lines of at most 48 characters; null = the receipt's own thank-you line. */
2244
+ footerLines: string[] | null;
2245
+ /** The stored choice, else the store's price basis. */
2246
+ taxDisplay: PosReceiptTaxDisplay;
2247
+ identity: PosReceiptIdentity;
2248
+ }
2249
+ /** What `setReceipt` / `previewReceipt` change: an omitted field keeps its value. */
2250
+ export interface PosReceiptSettingsInput {
2251
+ showStoreName?: boolean;
2252
+ showAddress?: boolean;
2253
+ showPhone?: boolean;
2254
+ showVatNumber?: boolean;
2255
+ headerLines?: string[];
2256
+ /** null = the receipt's own thank-you line; [] = no footer. */
2257
+ footerLines?: string[] | null;
2258
+ taxDisplay?: PosReceiptTaxDisplay;
2259
+ /**
2260
+ * Digital receipts on or off (engine sprint 23; send it only to change it: an engine before 23
2261
+ * refuses the field). Switching on where the platform serves no receipt pages is refused
2262
+ * `POS_RECEIPT_LINK_UNAVAILABLE` (`reason: not_configured`).
2263
+ */
2264
+ publicLink?: boolean;
2265
+ /**
2266
+ * The receipt account claim on or off (engine C3/32; send it only to change it: an engine before
2267
+ * C3 refuses the field). Switching on without digital receipts or a storefront address is refused
2268
+ * `POS_RECEIPT_LINK_UNAVAILABLE` (`reason: no_storefront`).
2269
+ */
2270
+ accountClaim?: boolean;
2271
+ }
2272
+ /** A completed till sale's receipt document (engine sprint 22). Money in minor units. */
2273
+ export interface PosReceipt {
2274
+ /** `SALE` today; read an unknown kind as a sale. */
2275
+ kind: string;
2276
+ orderId: string;
2277
+ orderCode: string;
2278
+ receiptNumber: string;
2279
+ /** When the sale was placed (ISO). */
2280
+ issuedAt: string;
2281
+ /** The receipt's language: the store's when the till speaks it, else `en`. */
2282
+ language: string;
2283
+ /** BCP 47, for money and dates (`nl-NL`). */
2284
+ locale: string;
2285
+ /** IANA zone `issuedAt` is shown in. */
2286
+ timeZone: string;
2287
+ currencyCode: string;
2288
+ taxDisplay: PosReceiptTaxDisplay;
2289
+ header: PosReceiptIdentity & {
2290
+ extraLines: string[];
2291
+ };
2292
+ cashierName: string | null;
2293
+ registerName: string | null;
2294
+ lines: PosReceiptLine[];
2295
+ /** The lines at list price plus their own discount rows. */
2296
+ subtotal: number;
2297
+ adjustments: PosReceiptAdjustment[];
2298
+ taxes: PosReceiptTax[];
2299
+ /** The sale's billable total: what was paid. */
2300
+ total: number;
2301
+ tenders: PosReceiptTender[];
2302
+ changeDue: number;
2303
+ refunds: PosReceiptRefund[];
2304
+ orderNote: string | null;
2305
+ /** Where the sale's ship lines go (engine C3); null for a take-now sale. Absent before C3. */
2306
+ delivery?: PosReceiptDelivery | null;
2307
+ footerLines: string[];
2308
+ /** The receipt's own thank-you line prints. */
2309
+ thankYou: boolean;
2310
+ /** The order code, printed as a Code 128 barcode. */
2311
+ scanCode: string;
2312
+ }
2313
+ export interface PosReceiptLine {
2314
+ orderLineId: string;
2315
+ name: string;
2316
+ /** Null for a custom item. */
2317
+ sku: string | null;
2318
+ quantity: number;
2319
+ unitPrice: number;
2320
+ amount: number;
2321
+ /** Percent. */
2322
+ taxRate: number;
2323
+ discounts: Array<{
2324
+ kind: 'PROMOTION' | 'TILL';
2325
+ description: string | null;
2326
+ amount: number;
2327
+ }>;
2328
+ note: string | null;
2329
+ /** Shipped to the customer: printed "To be delivered" (engine C3). Absent before C3. */
2330
+ ships?: boolean;
2331
+ }
2332
+ /** Where a sale's ship lines go (engine C3): the customer's delivery address, never a phone. */
2333
+ export interface PosReceiptDelivery {
2334
+ name: string | null;
2335
+ addressLines: string[];
2336
+ /** The delivery method's name in the receipt language. */
2337
+ methodName: string | null;
2338
+ }
2339
+ export interface PosReceiptAdjustment {
2340
+ kind: 'PROMOTION' | 'TILL_DISCOUNT' | 'SURCHARGE' | 'SHIPPING' | 'ROUNDING';
2341
+ description: string | null;
2342
+ amount: number;
2343
+ }
2344
+ export interface PosReceiptTax {
2345
+ description: string;
2346
+ rate: number;
2347
+ base: number;
2348
+ amount: number;
2349
+ }
2350
+ export interface PosReceiptTender {
2351
+ kind: 'cash' | 'card' | 'other';
2352
+ /**
2353
+ * An exchange's carried credit (engine C3): label it from the receipt's own words, never
2354
+ * `methodName`. Absent from an older engine's answer.
2355
+ */
2356
+ exchange?: boolean;
2357
+ /** The payment method's name in the receipt language. */
2358
+ methodName: string | null;
2359
+ amount: number;
2360
+ /** Cash only. */
2361
+ tendered: number | null;
2362
+ /** Cash only: + the drawer kept more than the amount. */
2363
+ cashRounding: number | null;
2364
+ /** Cash only. */
2365
+ change: number | null;
2366
+ }
2367
+ export interface PosReceiptRefund {
2368
+ kind: 'cash' | 'card' | 'other';
2369
+ /** A refund of an exchange's carried credit (engine C3). */
2370
+ exchange?: boolean;
2371
+ methodName: string | null;
2372
+ /** Positive: the money returned. */
2373
+ amount: number;
2374
+ refundedAt: string;
2375
+ }
2376
+ /** A store's cash controls at the till's close (engine sprint 25b). */
2377
+ export interface PosCashControls {
2378
+ /** The cashier counts the drawer without seeing the expected cash; the variance shows after. */
2379
+ blindCount: boolean;
2380
+ /** A variance above this (minor units) needs a manager; null for never. */
2381
+ varianceThreshold: number | null;
2382
+ }
2383
+ export interface PosCashControlsInput {
2384
+ blindCount: boolean;
2385
+ /** Omitted keeps the stored threshold; null sets "never". */
2386
+ varianceThreshold?: number | null;
2387
+ }
2388
+ /** A store's business day and the auto-close of forgotten drawers (engine sprint 26). */
2389
+ export interface PosDayControls {
2390
+ /** When a business day begins, `HH:MM` (00:00 to 12:00): a drawer opened earlier is the day before's. */
2391
+ businessDayStartsAt: string;
2392
+ /** When the store closes, `HH:MM`; at or before the day start it is on the next calendar day. Null: none. */
2393
+ closingTime: string | null;
2394
+ /** A drawer still open this many minutes after the closing time is closed without a count. */
2395
+ autoCloseAfterClosingMinutes: number;
2396
+ /** A drawer idle this many minutes is closed without a count; null for never. */
2397
+ autoCloseIdleMinutes: number | null;
2398
+ }
2399
+ export interface PosDayControlsInput {
2400
+ businessDayStartsAt: string;
2401
+ /** Omitted or null: no closing time. */
2402
+ closingTime?: string | null;
2403
+ autoCloseAfterClosingMinutes: number;
2404
+ /** Omitted keeps the stored idle time; null switches the idle close off. */
2405
+ autoCloseIdleMinutes?: number | null;
2406
+ }
2407
+ /** Needs `UpdateSettings` or `ManagePosDevices`. */
2408
+ export interface PosTerminalsModule {
2409
+ /**
2410
+ * The Mollie terminals the store's till key reaches, read from Mollie now (at most 250; the whole
2411
+ * list in one page). Refusals, each carrying `.code`: POS_MOLLIE_KEY_INVALID (Mollie refused the
2412
+ * key; a `ValidationError`), POS_MOLLIE_KEY_MISSING, POS_MOLLIE_KEY_UNREADABLE,
2413
+ * POS_MOLLIE_UNREACHABLE (try again) and POS_MOLLIE_REQUEST_REFUSED (each a `BusinessRuleError`),
2414
+ * and POS_ENCRYPTION_NOT_CONFIGURED (the engine cannot store or read a card key yet: its
2415
+ * operator must configure it; a non-retryable 500, Mollie not asked). Branch on the code.
2416
+ */
2417
+ list(options?: Call): Promise<Page<PosMollieTerminal>>;
2418
+ }
2419
+ /**
2420
+ * The languages a staff member's own till language may be (`en`, `nl`, `de`, `fr`); the engine's
2421
+ * list, which a value outside it is refused against. The till speaks a language only once its
2422
+ * catalogue is released; until then it falls back to the store's language.
2423
+ */
2424
+ export declare const POS_STAFF_LOCALES: readonly ["en", "nl", "de", "fr"];
2425
+ export type PosStaffLocale = (typeof POS_STAFF_LOCALES)[number];
2426
+ export type PosStaffRole = 'cashier' | 'manager';
2427
+ /** A cashier or manager of the store, as the back office manages them. */
2428
+ export interface PosStaffMember {
2429
+ id: string;
2430
+ name: string;
2431
+ /** A manager can approve what a cashier may not do alone (a discount, a refund, a paid-out). */
2432
+ role: PosStaffRole;
2433
+ /** An inactive staff member cannot sign in on a till. */
2434
+ active: boolean;
2435
+ /** The back-office administrator this staff member is linked to, if any. */
2436
+ administratorId: string | null;
2437
+ /**
2438
+ * Their own till language, or null to follow the store's. A string, not narrowed to
2439
+ * {@link PosStaffLocale}, so a language a newer engine adds never fails a read.
2440
+ */
2441
+ locale: string | null;
2442
+ createdAt: string;
2443
+ updatedAt: string;
2444
+ }
2445
+ export interface PosStaffCreateInput {
2446
+ name: string;
2447
+ /** The first PIN, which the cashier signs in with on the till. Never readable again. */
2448
+ pin: string;
2449
+ /** `cashier` when omitted. */
2450
+ role?: PosStaffRole;
2451
+ /** Their own till language; omitted or null follows the store's. */
2452
+ locale?: PosStaffLocale | null;
2453
+ }
2454
+ export interface PosStaffUpdateInput {
2455
+ name?: string;
2456
+ role?: PosStaffRole;
2457
+ active?: boolean;
2458
+ /** Their own till language; null follows the store's; omitted leaves it as it is. */
2459
+ locale?: PosStaffLocale | null;
2460
+ }
2461
+ /**
2462
+ * The till actions a store may let a cashier do without a manager's approval (engine sprint 18). A
2463
+ * manager may do all of them, whatever is stored. Closing a drawer above the store's variance
2464
+ * threshold is not one: it stays a manager's.
2465
+ */
2466
+ export declare const POS_STAFF_GRANTS: readonly ["manual_price", "discount", "custom_item_over_limit", "refund", "discard_held_sale", "paid_out", "no_sale", "safe_drop", "float_adjust", "return_items", "void_sale", "no_receipt_return", "online_return"];
2467
+ export type PosStaffGrant = (typeof POS_STAFF_GRANTS)[number];
2468
+ /** What one staff member may do at a till without a manager, as the store stored it. */
2469
+ export interface PosStaffGrants {
2470
+ id: string;
2471
+ role: PosStaffRole;
2472
+ /**
2473
+ * The stored grants, as strings: a grant a newer engine adds never fails a read. A manager may do
2474
+ * everything whatever this says (the list is kept, unused, while they are a manager).
2475
+ */
2476
+ grants: string[];
2477
+ }
2478
+ /**
2479
+ * The store's staff. Every method needs `UpdateSettings` or `ManagePosDevices`.
2480
+ *
2481
+ * `locale` is checked before anything is sent: a value outside {@link POS_STAFF_LOCALES} (`nl_BE`,
2482
+ * `es`) is refused `POS_LOCALE_UNSUPPORTED` as a `ValidationError` (`details[0].field` is
2483
+ * `locale`); the engine's own refusal of that code arrives as the same class (400), by core's code
2484
+ * table. It is trimmed and lower-cased like the engine does (`' NL '` is `nl`), and an empty one
2485
+ * follows the store, as null does. A language the till has not released yet is accepted: the till
2486
+ * uses the store's language until it ships.
2487
+ *
2488
+ * Every staff document names `locale`, so an engine older than the staff language refuses each
2489
+ * call (`GRAPHQL_VALIDATION_FAILED`, or `BAD_REQUEST` over HTTP 400) before running it.
2490
+ */
2491
+ export interface PosStaffModule {
2492
+ /**
2493
+ * Every staff member of the store, inactive ones included, oldest first; returned whole.
2494
+ *
2495
+ * @effect read
2496
+ */
2497
+ list(options?: Call): Promise<Page<PosStaffMember>>;
2498
+ /**
2499
+ * One staff member, or null when the id is not one of this store's.
2500
+ *
2501
+ * @effect read
2502
+ */
2503
+ get(id: string, options?: Call): Promise<PosStaffMember | null>;
2504
+ /**
2505
+ * A new staff member, active, with their first PIN (the engine checks its format, as
2506
+ * {@link PosStaffModule.setPin} says). On an organization workspace refused
2507
+ * `ORGANIZATION_WORKSPACE_NOT_A_STORE`.
2508
+ *
2509
+ * @effect write
2510
+ */
2511
+ create(input: PosStaffCreateInput, options?: Call): Promise<PosStaffMember>;
2512
+ /**
2513
+ * Change what `input` names; a field left out is left as it is. `active: false` is how a staff
2514
+ * member leaves: they can no longer sign in on a till and a shift they have open stops working,
2515
+ * while every sale, drawer and approval they made stays theirs; `active: true` brings them back
2516
+ * (refused `POS_STAFF_NAME_TAKEN` while an active member has the name). There is no delete.
2517
+ * Refused `POS_STAFF_NOT_FOUND` (`NotFoundError`, 404) for an id that is not this store's.
2518
+ *
2519
+ * @effect write
2520
+ */
2521
+ update(id: string, input: PosStaffUpdateInput, options?: Call): Promise<PosStaffMember>;
2522
+ /**
2523
+ * Replace a staff member's PIN. The PIN is 4 to 8 digits, neither one digit repeated (`1111`)
2524
+ * nor a run (`1234`, `9876`); anything else is refused `POS_PIN_FORMAT_INVALID`
2525
+ * (`ValidationError`, 400, the engine's sentence naming the rule, never the PIN) before
2526
+ * anything is read. A new PIN also clears the member's wrong-PIN count, which is how a locked
2527
+ * member is unlocked (the till's own count is left). The PIN is never read back, and this SDK
2528
+ * never puts it in an error or a log. Refused `POS_STAFF_NOT_FOUND` (`NotFoundError`, 404) for an
2529
+ * id that is not this store's. Needs `UpdateSettings` or `ManagePosDevices`.
2530
+ *
2531
+ * @effect write
2532
+ */
2533
+ setPin(id: string, pin: string, options?: Call): Promise<void>;
2534
+ /**
2535
+ * What one staff member may do without a manager (engine sprint 18), or null when the id is not
2536
+ * one of this store's. An engine older than sprint 18 refuses the document
2537
+ * (`GRAPHQL_VALIDATION_FAILED`, or `BAD_REQUEST` over HTTP 400).
2538
+ *
2539
+ * @effect read
2540
+ */
2541
+ grants(id: string, options?: Call): Promise<PosStaffGrants | null>;
2542
+ /**
2543
+ * Every staff member's grants, inactive ones included; returned whole (engine sprint 18).
2544
+ *
2545
+ * @effect read
2546
+ */
2547
+ listGrants(options?: Call): Promise<Page<PosStaffGrants>>;
2548
+ /**
2549
+ * Replace a staff member's grants (engine sprint 18): what they may do at a till without a
2550
+ * manager. The engine stores the set deduplicated, in its own order, and writes (and audits)
2551
+ * only a change. A manager keeps every power whatever is stored. Refused `POS_STAFF_NOT_FOUND`
2552
+ * (`NotFoundError`, 404) for an id that is not this store's, `ORGANIZATION_WORKSPACE_NOT_A_STORE`
2553
+ * on a workspace; a value outside the engine's `PosStaffGrant` enum fails its validation.
2554
+ *
2555
+ * @effect write
2556
+ */
2557
+ setGrants(id: string, grants: readonly PosStaffGrant[], options?: Call): Promise<PosStaffGrants>;
2558
+ }
541
2559
  export declare const POS_REGISTERS_QUERY = "query PosRegisters { posRegisters { id stockLocationId name status createdAt updatedAt } }";
542
2560
  export declare const POS_REGISTER_QUERY = "query PosRegister($id: ID!) { posRegister(id: $id) { id stockLocationId name status createdAt updatedAt } }";
543
2561
  export declare const CREATE_POS_REGISTER_MUTATION = "mutation CreatePosRegister($input: CreatePosRegisterInput!) { createPosRegister(input: $input) { id stockLocationId name status createdAt updatedAt } }";
@@ -546,22 +2564,97 @@ export declare const OPEN_POS_SESSION_MUTATION = "mutation OpenPosRegisterSessio
546
2564
  export declare const CLOSE_POS_SESSION_MUTATION = "mutation ClosePosRegisterSession($input: ClosePosRegisterSessionInput!, $staffToken: String) { closePosRegisterSession(input: $input, staffToken: $staffToken) { id registerId deviceId openedByStaffId openingFloat status expectedCash countedCash cashOverShort totals openedAt closedAt } }";
547
2565
  export declare const POS_X_REPORT_QUERY = "query PosXReport($sessionId: ID!) { posXReport(sessionId: $sessionId) { sessionId openingFloat expectedCash movementCount totals { cash card other refunds net saleCount } } }";
548
2566
  export declare const POS_SESSION_QUERY = "query PosRegisterSession($id: ID!) { posRegisterSession(id: $id) { id registerId deviceId openedByStaffId openingFloat status expectedCash countedCash cashOverShort totals openedAt closedAt } }";
2567
+ export declare const POS_SESSION_DETAIL_QUERY = "query PosRegisterSessionDetail($id: ID!) { posRegisterSession(id: $id) { id registerId deviceId openedByStaffId openingFloat status expectedCash countedCash cashOverShort totals openedAt closedAt closedByStaffId blindCount varianceThreshold varianceApproval varianceApprovedByStaffId varianceApprovedAt } }";
2568
+ export declare const POS_SESSION_APPROVAL_QUERY = "query PosRegisterSessionApproval($id: ID!) { posRegisterSession(id: $id) { id varianceApproval varianceThreshold varianceApprovedByStaffId varianceApprovedAt varianceApprovedByUserId varianceApprovedByUserName varianceApprovedByCredential varianceApprovalNote } }";
2569
+ export declare const APPROVE_POS_SESSION_CLOSE_MUTATION = "mutation ApprovePosRegisterSessionClose($input: ApprovePosRegisterSessionCloseInput!) { approvePosRegisterSessionClose(input: $input) { id registerId deviceId openedByStaffId openingFloat status expectedCash countedCash cashOverShort totals openedAt closedAt closedByStaffId blindCount varianceThreshold varianceApproval varianceApprovedByStaffId varianceApprovedAt varianceApprovedByUserId varianceApprovedByUserName varianceApprovedByCredential varianceApprovalNote } }";
2570
+ export declare const SESSION_RECORD_FIELDS = "businessDay stockLocationId timeZone zNumber closeSource closedByUserId autoCloseReason closeNote countedAt countedByUserId countNote";
2571
+ export declare const SESSION_RECORD_NAME_FIELDS = "varianceApprovedByUserName closedByUserName countedByUserName";
2572
+ export declare const POS_SESSION_RECORD_QUERY = "query PosRegisterSessionRecord($id: ID!) { posRegisterSession(id: $id) { id registerId deviceId openedByStaffId openingFloat status expectedCash countedCash cashOverShort totals openedAt closedAt closedByStaffId blindCount varianceThreshold varianceApproval varianceApprovedByStaffId varianceApprovedAt varianceApprovedByUserId varianceApprovedByCredential varianceApprovalNote businessDay stockLocationId timeZone zNumber closeSource closedByUserId autoCloseReason closeNote countedAt countedByUserId countNote varianceApprovedByUserName closedByUserName countedByUserName } }";
2573
+ export declare const POS_SESSION_RECORDS_QUERY = "query PosRegisterSessionRecords($options: PosRegisterSessionListOptions) { posRegisterSessions(options: $options) { totalItems items { id registerId deviceId openedByStaffId openingFloat status expectedCash countedCash cashOverShort totals openedAt closedAt closedByStaffId blindCount varianceThreshold varianceApproval varianceApprovedByStaffId varianceApprovedAt varianceApprovedByUserId varianceApprovedByCredential varianceApprovalNote businessDay stockLocationId timeZone zNumber closeSource closedByUserId autoCloseReason closeNote countedAt countedByUserId countNote } } }";
2574
+ export declare const CLOSE_POS_SESSION_UNCOUNTED_MUTATION = "mutation ClosePosRegisterSessionUncounted($input: ClosePosRegisterSessionUncountedInput!) { closePosRegisterSessionUncounted(input: $input) { id registerId deviceId openedByStaffId openingFloat status expectedCash countedCash cashOverShort totals openedAt closedAt closedByStaffId blindCount varianceThreshold varianceApproval varianceApprovedByStaffId varianceApprovedAt varianceApprovedByUserId varianceApprovedByCredential varianceApprovalNote businessDay stockLocationId timeZone zNumber closeSource closedByUserId autoCloseReason closeNote countedAt countedByUserId countNote varianceApprovedByUserName closedByUserName countedByUserName } }";
2575
+ export declare const COUNT_POS_SESSION_MUTATION = "mutation CountPosRegisterSession($input: CountPosRegisterSessionInput!) { countPosRegisterSession(input: $input) { id registerId deviceId openedByStaffId openingFloat status expectedCash countedCash cashOverShort totals openedAt closedAt closedByStaffId blindCount varianceThreshold varianceApproval varianceApprovedByStaffId varianceApprovedAt varianceApprovedByUserId varianceApprovedByCredential varianceApprovalNote businessDay stockLocationId timeZone zNumber closeSource closedByUserId autoCloseReason closeNote countedAt countedByUserId countNote varianceApprovedByUserName closedByUserName countedByUserName } }";
2576
+ export declare const POS_ORDERS_QUERY = "query PosOrders($input: PosOrderListInput) { posOrders(input: $input) { totalItems items { orderId orderCode receiptNumber placedAt state currencyCode totalWithTax totalQuantity refundedTotal tenderKinds customerKind customerName registerId registerName sessionId deviceId deviceLabel staffId staffName } } }";
2577
+ export declare const POS_TILL_SALE_QUERY = "query PosTillSale($orderId: ID!) { posTillOrder(orderId: $orderId) { order { id code state } receiptNumber placedAt customerKind deviceId deviceLabel registerId registerName sessionId staffId staffName payments { paymentId kind method state amount refunded refundUnknown refundable } idCheck { id checkedAt staffId staffName deviceId deviceLabel stockLocationId minimumAge } } }";
2578
+ /**
2579
+ * {@link POS_TILL_SALE_QUERY} for an engine older than the till's ID check (user decision L1),
2580
+ * which refuses the whole document at validation: the sale is still read, with no ID check.
2581
+ */
2582
+ export declare const POS_TILL_SALE_QUERY_LEGACY = "query PosTillSale($orderId: ID!) { posTillOrder(orderId: $orderId) { order { id code state } receiptNumber placedAt customerKind deviceId deviceLabel registerId registerName sessionId staffId staffName payments { paymentId kind method state amount refunded refundUnknown refundable } } }";
2583
+ export declare const POS_CASH_MOVEMENTS_QUERY = "query PosCashMovements($input: PosCashMovementListInput) { posCashMovements(input: $input) { totalItems items { id sessionId registerId registerName deviceId deviceLabel type amount reason staffId staffName approvedByStaffId approvedByStaffName orderId orderCode receiptNumber idempotencyKey createdAt } } }";
2584
+ export declare const STORE_DAY_TOTALS_FIELDS = "currencyCode sessionCount uncountedCount openingFloat expectedCash countedCash cashOverShort cash card other refunds net saleCount cashRefunds cardRefunds otherRefunds cashRounding";
2585
+ export declare const STORE_DAY_SESSION_FIELDS = "sessionId registerId registerName zNumber status closeSource openedAt closedAt openingFloat expectedCash countedCash cashOverShort varianceApproval totals { cash card other refunds net saleCount cashRefunds cardRefunds otherRefunds cashRounding }";
2586
+ export declare const STORE_DAY_FIELDS = "id stockLocationId businessDay timeZone startsAt endsAt status totalsFinal totals { currencyCode sessionCount uncountedCount openingFloat expectedCash countedCash cashOverShort cash card other refunds net saleCount cashRefunds cardRefunds otherRefunds cashRounding } openSessionCount pendingCount uncountedCount closedAt closedByUserId closedByCredential closeNote closeCount reopenedAt reopenedByUserId reopenNote";
2587
+ /** What a single day's read adds to a list item: its drawers and the two names. */
2588
+ export declare const STORE_DAY_DETAIL_FIELDS = "sessions { sessionId registerId registerName zNumber status closeSource openedAt closedAt openingFloat expectedCash countedCash cashOverShort varianceApproval totals { cash card other refunds net saleCount cashRefunds cardRefunds otherRefunds cashRounding } } closedByUserName reopenedByUserName";
2589
+ export declare const POS_STORE_DAY_QUERY = "query PosStoreDay($stockLocationId: ID!, $businessDay: String!) { posStoreDay(stockLocationId: $stockLocationId, businessDay: $businessDay) { id stockLocationId businessDay timeZone startsAt endsAt status totalsFinal totals { currencyCode sessionCount uncountedCount openingFloat expectedCash countedCash cashOverShort cash card other refunds net saleCount cashRefunds cardRefunds otherRefunds cashRounding } openSessionCount pendingCount uncountedCount closedAt closedByUserId closedByCredential closeNote closeCount reopenedAt reopenedByUserId reopenNote sessions { sessionId registerId registerName zNumber status closeSource openedAt closedAt openingFloat expectedCash countedCash cashOverShort varianceApproval totals { cash card other refunds net saleCount cashRefunds cardRefunds otherRefunds cashRounding } } closedByUserName reopenedByUserName } }";
2590
+ export declare const POS_STORE_DAYS_QUERY = "query PosStoreDays($input: PosStoreDayListInput!) { posStoreDays(input: $input) { totalItems items { id stockLocationId businessDay timeZone startsAt endsAt status totalsFinal totals { currencyCode sessionCount uncountedCount openingFloat expectedCash countedCash cashOverShort cash card other refunds net saleCount cashRefunds cardRefunds otherRefunds cashRounding } openSessionCount pendingCount uncountedCount closedAt closedByUserId closedByCredential closeNote closeCount reopenedAt reopenedByUserId reopenNote } } }";
2591
+ export declare const CLOSE_POS_STORE_DAY_MUTATION = "mutation ClosePosStoreDay($input: ClosePosStoreDayInput!) { closePosStoreDay(input: $input) { id stockLocationId businessDay timeZone startsAt endsAt status totalsFinal totals { currencyCode sessionCount uncountedCount openingFloat expectedCash countedCash cashOverShort cash card other refunds net saleCount cashRefunds cardRefunds otherRefunds cashRounding } openSessionCount pendingCount uncountedCount closedAt closedByUserId closedByCredential closeNote closeCount reopenedAt reopenedByUserId reopenNote sessions { sessionId registerId registerName zNumber status closeSource openedAt closedAt openingFloat expectedCash countedCash cashOverShort varianceApproval totals { cash card other refunds net saleCount cashRefunds cardRefunds otherRefunds cashRounding } } closedByUserName reopenedByUserName } }";
2592
+ export declare const REOPEN_POS_STORE_DAY_MUTATION = "mutation ReopenPosStoreDay($input: ReopenPosStoreDayInput!) { reopenPosStoreDay(input: $input) { id stockLocationId businessDay timeZone startsAt endsAt status totalsFinal totals { currencyCode sessionCount uncountedCount openingFloat expectedCash countedCash cashOverShort cash card other refunds net saleCount cashRefunds cardRefunds otherRefunds cashRounding } openSessionCount pendingCount uncountedCount closedAt closedByUserId closedByCredential closeNote closeCount reopenedAt reopenedByUserId reopenNote sessions { sessionId registerId registerName zNumber status closeSource openedAt closedAt openingFloat expectedCash countedCash cashOverShort varianceApproval totals { cash card other refunds net saleCount cashRefunds cardRefunds otherRefunds cashRounding } } closedByUserName reopenedByUserName } }";
2593
+ export declare const POS_SESSION_LIST_QUERY = "query PosRegisterSessionList($options: PosRegisterSessionListOptions) { posRegisterSessions(options: $options) { totalItems items { id registerId deviceId openedByStaffId openingFloat status expectedCash countedCash cashOverShort totals openedAt closedAt closedByStaffId blindCount varianceThreshold varianceApproval varianceApprovedByStaffId varianceApprovedAt } } }";
549
2594
  export declare const RECORD_POS_CASH_MOVEMENT_MUTATION = "mutation RecordPosCashMovement($input: RecordPosCashMovementInput!, $staffToken: String) { recordPosCashMovement(input: $input, staffToken: $staffToken) { id sessionId type amount reason orderId createdAt } }";
2595
+ export declare const POS_DRAWER_MOVEMENTS_QUERY = "query PosDrawerMovements($sessionId: ID!, $skip: Int, $take: Int) { posDrawerMovements(sessionId: $sessionId, skip: $skip, take: $take) { totalItems items { id type amount balanceAfter reason staffId staffName approvedByStaffId approvedByStaffName orderId orderCode receiptNumber createdAt } summary { openingFloat cashSales cashRefunds cashRounding paidIn paidOut safeDrops floatAdjustments noSaleCount expectedCash movementCount } } }";
550
2596
  export declare const POS_CREATE_CART_MUTATION = "mutation PosCreateCart($registerId: ID) { posCreateCart(registerId: $registerId) { id code state currencyCode total totalWithTax couponCodes\n lines { id quantity productVariant { id } linePriceWithTax }\n surcharges { description sku price priceWithTax taxRate } } }";
551
2597
  export declare const POS_ADD_ITEM_MUTATION = "mutation PosAddItem($input: PosAddItemInput!) { posAddItem(input: $input) { id code state currencyCode total totalWithTax couponCodes\n lines { id quantity productVariant { id } linePriceWithTax }\n surcharges { description sku price priceWithTax taxRate } } }";
552
2598
  export declare const POS_APPLY_DISCOUNT_MUTATION = "mutation PosApplyDiscount($input: PosApplyDiscountInput!, $staffToken: String) { posApplyDiscount(input: $input, staffToken: $staffToken) { id code state currencyCode total totalWithTax couponCodes\n lines { id quantity productVariant { id } linePriceWithTax }\n surcharges { description sku price priceWithTax taxRate } } }";
553
2599
  export declare const POS_APPLY_COUPON_CODE_MUTATION = "mutation PosApplyCouponCode($input: PosCouponCodeInput!) { posApplyCouponCode(input: $input) { id code state currencyCode total totalWithTax couponCodes\n lines { id quantity productVariant { id } linePriceWithTax }\n surcharges { description sku price priceWithTax taxRate } } }";
554
2600
  export declare const POS_REMOVE_COUPON_CODE_MUTATION = "mutation PosRemoveCouponCode($input: PosCouponCodeInput!) { posRemoveCouponCode(input: $input) { id code state currencyCode total totalWithTax couponCodes\n lines { id quantity productVariant { id } linePriceWithTax }\n surcharges { description sku price priceWithTax taxRate } } }";
2601
+ export declare const POS_ADD_CUSTOM_ITEM_MUTATION = "mutation PosAddCustomItem($input: PosAddCustomItemInput!, $staffToken: String, $approvalToken: String) { posAddCustomItem(input: $input, staffToken: $staffToken, approvalToken: $approvalToken) { id code state currencyCode total totalWithTax couponCodes\n lines { id quantity productVariant { id } linePriceWithTax }\n surcharges { description sku price priceWithTax taxRate } lines { id customFields { posCustomItemName } } } }";
2602
+ export declare const POS_SET_ORDER_NOTE_MUTATION = "mutation PosSetOrderNote($input: PosSetOrderNoteInput!, $staffToken: String) { posSetOrderNote(input: $input, staffToken: $staffToken) { id code state currencyCode total totalWithTax couponCodes\n lines { id quantity productVariant { id } linePriceWithTax }\n surcharges { description sku price priceWithTax taxRate } customFields { posOrderNote } lines { id customFields { posCustomItemName posLineNote } } } }";
2603
+ export declare const POS_SET_LINE_NOTE_MUTATION = "mutation PosSetLineNote($input: PosSetLineNoteInput!, $staffToken: String) { posSetLineNote(input: $input, staffToken: $staffToken) { id code state currencyCode total totalWithTax couponCodes\n lines { id quantity productVariant { id } linePriceWithTax }\n surcharges { description sku price priceWithTax taxRate } customFields { posOrderNote } lines { id customFields { posCustomItemName posLineNote } } } }";
2604
+ export declare const POS_TILL_SALE_DETAILS_QUERY = "query PosTillSaleDetails($id: ID!) { order(id: $id) { id customFields { isPosOrder posOrderNote } lines { id customFields { posCustomItemName posLineNote } } } }";
2605
+ export declare const POS_CLEAR_CART_MUTATION = "mutation PosClearCart($input: PosClearCartInput!, $staffToken: String) { posClearCart(input: $input, staffToken: $staffToken) { orderId orderCode } }";
555
2606
  export declare const POS_COMPLETE_SALE_MUTATION = "mutation PosCompleteSale($input: PosCompleteSaleInput!, $staffToken: String) { posCompleteSale(input: $input, staffToken: $staffToken) { orderId orderCode receiptNumber state } }";
556
2607
  export declare const POS_TENDER_CASH_MUTATION = "mutation PosTenderCash($input: PosTenderCashInput!, $staffToken: String) { posTenderCash(input: $input, staffToken: $staffToken) { orderId paymentId covered outstanding change } }";
557
2608
  export declare const POS_TENDER_CARD_MUTATION = "mutation PosTenderCard($input: PosTenderCardInput!, $staffToken: String) { posTenderCard(input: $input, staffToken: $staffToken) { orderId paymentId covered outstanding change } }";
558
2609
  export declare const POS_TENDER_STORED_VALUE_MUTATION = "mutation PosTenderStoredValue($input: PosTenderStoredValueInput!, $staffToken: String) { posTenderStoredValue(input: $input, staffToken: $staffToken) { orderId paymentId covered outstanding change } }";
559
2610
  export declare const POS_TENDER_MANUAL_MUTATION = "mutation PosTenderManual($input: PosTenderManualInput!, $staffToken: String) { posTenderManual(input: $input, staffToken: $staffToken) { orderId paymentId covered outstanding change } }";
560
2611
  export declare const POS_REFUND_MUTATION = "mutation PosRefund($input: PosRefundInput!, $staffToken: String) { posRefund(input: $input, staffToken: $staffToken) { orderId refundId state } }";
561
- export declare const POS_DEVICES_QUERY = "query PosDevices { posDevices { id stockLocationId registerId label status paired lastSeenAt } }";
2612
+ export declare const POS_DEVICES_QUERY = "query PosDevices { posDevices { id stockLocationId registerId label status paired lastSeenAt mollieTerminalId createdAt updatedAt } }";
562
2613
  export declare const POS_DEVICE_QUERY = "query PosDevice($id: ID!) { posDevice(id: $id) { lastSeenAt } }";
563
2614
  export declare const POS_PAIRING_CODE_MUTATION = "mutation GeneratePosPairingCode($deviceId: ID!) { generatePosPairingCode(deviceId: $deviceId) { code expiresAt } }";
564
- export declare const REVOKE_POS_DEVICE_MUTATION = "mutation RevokePosDevice($deviceId: ID!) { revokePosDevice(deviceId: $deviceId) { id stockLocationId registerId label status paired lastSeenAt } }";
2615
+ export declare const REVOKE_POS_DEVICE_MUTATION = "mutation RevokePosDevice($deviceId: ID!) { revokePosDevice(deviceId: $deviceId) { id stockLocationId registerId label status paired lastSeenAt mollieTerminalId createdAt updatedAt } }";
2616
+ export declare const POS_DEVICE_DETAIL_QUERY = "query PosDeviceDetail($id: ID!) { posDevice(id: $id) { id stockLocationId registerId label status paired lastSeenAt mollieTerminalId createdAt updatedAt } }";
2617
+ export declare const ASSIGN_POS_DEVICE_LOCATION_MUTATION = "mutation AssignPosDeviceLocation($deviceId: ID!, $stockLocationId: ID!) { assignPosDeviceLocation(deviceId: $deviceId, stockLocationId: $stockLocationId) { id stockLocationId registerId label status paired lastSeenAt mollieTerminalId createdAt updatedAt } }";
2618
+ export declare const ASSIGN_POS_DEVICE_REGISTER_MUTATION = "mutation AssignPosDeviceRegister($deviceId: ID!, $registerId: ID!) { assignPosDeviceRegister(deviceId: $deviceId, registerId: $registerId) { id stockLocationId registerId label status paired lastSeenAt mollieTerminalId createdAt updatedAt } }";
2619
+ export declare const ASSIGN_POS_DEVICE_TERMINAL_MUTATION = "mutation AssignPosDeviceMollieTerminal($deviceId: ID!, $terminalId: String!) { assignPosDeviceMollieTerminal(deviceId: $deviceId, terminalId: $terminalId) { id stockLocationId registerId label status paired lastSeenAt mollieTerminalId createdAt updatedAt } }";
2620
+ export declare const ASSIGN_POS_DEVICE_LOCATION_WITH_REGISTER_MUTATION = "mutation AssignPosDeviceLocationWithRegister($deviceId: ID!, $stockLocationId: ID!, $registerId: ID!) { assignPosDeviceLocation(deviceId: $deviceId, stockLocationId: $stockLocationId, registerId: $registerId) { id stockLocationId registerId label status paired lastSeenAt mollieTerminalId createdAt updatedAt } }";
2621
+ export declare const CLEAR_POS_DEVICE_TERMINAL_MUTATION = "mutation ClearPosDeviceMollieTerminal($deviceId: ID!) { clearPosDeviceMollieTerminal(deviceId: $deviceId) { id stockLocationId registerId label status paired lastSeenAt mollieTerminalId createdAt updatedAt } }";
2622
+ export declare const POS_OPEN_SESSION_FOR_DEVICE_QUERY = "query PosOpenSessionForDevice($deviceId: ID!) { posOpenSessionForDevice(deviceId: $deviceId) { id registerId deviceId openedByStaffId openingFloat status expectedCash countedCash cashOverShort totals openedAt closedAt } }";
2623
+ export declare const CREATE_POS_DEVICE_MUTATION = "mutation CreatePosDevice($input: CreatePosDeviceInput!) { createPosDevice(input: $input) { id stockLocationId registerId label status paired lastSeenAt mollieTerminalId createdAt updatedAt } }";
2624
+ export declare const CREATE_POS_DEVICE_KIND_MUTATION = "mutation CreatePosDeviceOfKind($input: CreatePosDeviceInput!) { createPosDevice(input: $input) { id stockLocationId registerId label status paired lastSeenAt mollieTerminalId createdAt updatedAt kind } }";
2625
+ export declare const POS_DEVICE_FLEET_QUERY = "query PosDeviceFleet($stockLocationId: ID) { posDeviceFleet(stockLocationId: $stockLocationId) { device { id stockLocationId registerId label status paired lastSeenAt mollieTerminalId createdAt updatedAt heartbeatAt lockedAt silentSince kind } health { status lastHeardAt silentSince } report { appVersion buildNumber runtimeVersion updateId updateChannel platform connection outboxPending offlineSalesPending offlineSalesRefused printer reportedAt } openDrawer { sessionId registerId openedAt openedByStaffName } lockedByUserName } }";
2626
+ export declare const LOCK_POS_DEVICE_MUTATION = "mutation LockPosDevice($deviceId: ID!) { lockPosDevice(deviceId: $deviceId) { id stockLocationId registerId label status paired lastSeenAt mollieTerminalId createdAt updatedAt heartbeatAt lockedAt silentSince kind } }";
2627
+ export declare const UNLOCK_POS_DEVICE_MUTATION = "mutation UnlockPosDevice($deviceId: ID!) { unlockPosDevice(deviceId: $deviceId) { id stockLocationId registerId label status paired lastSeenAt mollieTerminalId createdAt updatedAt heartbeatAt lockedAt silentSince kind } }";
565
2628
  export declare const POS_RECEIPT_NUMBERING_QUERY = "query PosReceiptNumberingConfig { posReceiptNumberingConfig { prefix suffix digits } }";
566
2629
  export declare const UPDATE_POS_RECEIPT_NUMBERING_MUTATION = "mutation UpdatePosReceiptNumberingConfig($input: UpdatePosReceiptNumberingConfigInput!) { updatePosReceiptNumberingConfig(input: $input) { prefix suffix digits } }";
2630
+ export declare const POS_SETTINGS_QUERY = "query PosSettings { getPosConfig { enabled cashPaymentMethodCode cardPaymentMethodCode inStoreShippingMethodId defaultStockLocationId cashRoundingMode hasMollieKey maskedMollieApiKey } }";
2631
+ export declare const UPDATE_POS_SETTINGS_MUTATION = "mutation UpdatePosSettings($input: UpdatePosConfigInput!) { updatePosConfig(input: $input) { enabled cashPaymentMethodCode cardPaymentMethodCode inStoreShippingMethodId defaultStockLocationId cashRoundingMode hasMollieKey maskedMollieApiKey } }";
2632
+ export declare const POS_MOLLIE_TERMINALS_QUERY = "query PosMollieTerminals { posMollieTerminals { terminalId description status brand model serialNumber currency } }";
2633
+ export declare const POS_CASH_CONTROLS_QUERY = "query PosCashControls { getPosConfig { cashControls { blindCount varianceThreshold } } }";
2634
+ export declare const SET_POS_CASH_CONTROLS_MUTATION = "mutation SetPosCashControls($input: PosCashControlsInput!) { setPosCashControls(input: $input) { blindCount varianceThreshold } }";
2635
+ export declare const POS_RECEIPT_SETTINGS_QUERY = "query PosReceiptSettings { getPosConfig { receipt { configured showStoreName showAddress showPhone showVatNumber headerLines footerLines taxDisplay identity { storeName addressLines phone vatNumber registrationNumber } } } }";
2636
+ export declare const SET_POS_RECEIPT_SETTINGS_MUTATION = "mutation SetPosReceiptSettings($input: PosReceiptSettingsInput!) { setPosReceiptSettings(input: $input) { configured showStoreName showAddress showPhone showVatNumber headerLines footerLines taxDisplay identity { storeName addressLines phone vatNumber registrationNumber } } }";
2637
+ export declare const POS_RECEIPT_PREVIEW_QUERY = "query PosReceiptPreview($input: PosReceiptSettingsInput) { posReceiptPreview(input: $input) { kind orderId orderCode receiptNumber issuedAt language locale timeZone currencyCode taxDisplay header { storeName addressLines phone vatNumber registrationNumber extraLines } cashierName registerName lines { orderLineId name sku quantity unitPrice amount taxRate discounts { kind description amount } note ships } subtotal adjustments { kind description amount } taxes { description rate base amount } total tenders { kind exchange methodName amount tendered cashRounding change } changeDue refunds { kind exchange methodName amount refundedAt } orderNote delivery { name addressLines methodName } footerLines thankYou scanCode } }";
2638
+ export declare const POS_RECEIPT_QUERY = "query PosReceipt($orderId: ID!) { posReceipt(orderId: $orderId) { kind orderId orderCode receiptNumber issuedAt language locale timeZone currencyCode taxDisplay header { storeName addressLines phone vatNumber registrationNumber extraLines } cashierName registerName lines { orderLineId name sku quantity unitPrice amount taxRate discounts { kind description amount } note ships } subtotal adjustments { kind description amount } taxes { description rate base amount } total tenders { kind exchange methodName amount tendered cashRounding change } changeDue refunds { kind exchange methodName amount refundedAt } orderNote delivery { name addressLines methodName } footerLines thankYou scanCode } }";
2639
+ export declare const POS_RECEIPT_SHARING_QUERY = "query PosReceiptSharing($orderId: ID!) { posReceiptSharing(orderId: $orderId) { available enabled ttlDays links { variant state url issuedAt expiresAt revokedAt revokeReason } receiptCopies giftPrints } }";
2640
+ export declare const POS_ISSUE_RECEIPT_LINK_MUTATION = "mutation PosIssueReceiptLink($orderId: ID!, $variant: PosReceiptVariant!) { posIssueReceiptLink(orderId: $orderId, variant: $variant) { variant state url issuedAt expiresAt revokedAt revokeReason } }";
2641
+ export declare const REVOKE_POS_RECEIPT_LINK_MUTATION = "mutation RevokePosReceiptLink($orderId: ID!, $variant: PosReceiptVariant!) { revokePosReceiptLink(orderId: $orderId, variant: $variant) { variant state url issuedAt expiresAt revokedAt revokeReason } }";
2642
+ export declare const POS_PRINT_RECEIPT_MUTATION = "mutation PosPrintReceipt($input: PosPrintReceiptInput!, $staffToken: String) { posPrintReceipt(input: $input, staffToken: $staffToken) { orderId variant printNumber copy receipt { kind orderId orderCode receiptNumber issuedAt language locale timeZone currencyCode taxDisplay header { storeName addressLines phone vatNumber registrationNumber extraLines } cashierName registerName lines { orderLineId name sku quantity unitPrice amount taxRate discounts { kind description amount } note ships } subtotal adjustments { kind description amount } taxes { description rate base amount } total tenders { kind exchange methodName amount tendered cashRounding change } changeDue refunds { kind exchange methodName amount refundedAt } orderNote delivery { name addressLines methodName } footerLines thankYou scanCode link { variant url issuedAt expiresAt } copy { number printedAt } } giftReceipt { orderId orderCode receiptNumber issuedAt language locale timeZone header { storeName addressLines phone vatNumber registrationNumber extraLines } registerName lines { orderLineId name sku quantity } footerLines thankYou scanCode link { variant url issuedAt expiresAt } copy { number printedAt } } } }";
2643
+ export declare const POS_GIFT_RECEIPT_QUERY = "query PosGiftReceipt($orderId: ID!) { posReceipt(orderId: $orderId) { gift { orderId orderCode receiptNumber issuedAt language locale timeZone header { storeName addressLines phone vatNumber registrationNumber extraLines } registerName lines { orderLineId name sku quantity } footerLines thankYou scanCode link { variant url issuedAt expiresAt } copy { number printedAt } } } }";
2644
+ export declare const POS_DIGITAL_RECEIPTS_QUERY = "query PosDigitalReceipts { getPosConfig { receipt { publicLink publicLinkAvailable } } }";
2645
+ export declare const POS_RECEIPT_ACCOUNT_CLAIM_QUERY = "query PosReceiptAccountClaim { getPosConfig { receipt { accountClaim accountClaimAvailable } } }";
2646
+ export declare const POS_EMAIL_RECEIPT_MUTATION = "mutation PosEmailReceipt($input: PosEmailReceiptInput!, $staffToken: String) { posEmailReceipt(input: $input, staffToken: $staffToken) { orderId source sentForSale } }";
2647
+ export declare const POS_DAY_CONTROLS_QUERY = "query PosDayControls { getPosConfig { id dayControls { businessDayStartsAt closingTime autoCloseAfterClosingMinutes autoCloseIdleMinutes } } }";
2648
+ export declare const SET_POS_DAY_CONTROLS_MUTATION = "mutation SetPosDayControls($input: PosDayControlsInput!) { setPosDayControls(input: $input) { businessDayStartsAt closingTime autoCloseAfterClosingMinutes autoCloseIdleMinutes } }";
2649
+ export declare const POS_SETUP_READINESS_QUERY = "query PosSetupReadiness { posSetupReadiness { ready checks { check ok required reason } } }";
2650
+ export declare const POS_CUSTOM_ITEM_POLICY_QUERY = "query PosCustomItemPolicy { posCustomItemPolicy { enabled available maxUnitPrice cashierLimit amountsIncludeTax currencyCode taxCategories { id name taxRate } taxCategoryChoices { id name taxRate } } }";
2651
+ export declare const SET_POS_CUSTOM_ITEM_POLICY_MUTATION = "mutation SetPosCustomItemPolicy($input: PosCustomItemPolicyInput!) { setPosCustomItemPolicy(input: $input) { enabled available maxUnitPrice cashierLimit amountsIncludeTax currencyCode taxCategories { id name taxRate } taxCategoryChoices { id name taxRate } } }";
2652
+ export declare const POS_STAFF_LIST_QUERY = "query PosStaffList { posStaffList { id name role active administratorId locale createdAt updatedAt } }";
2653
+ export declare const POS_STAFF_QUERY = "query PosStaff($id: ID!) { posStaff(id: $id) { id name role active administratorId locale createdAt updatedAt } }";
2654
+ export declare const CREATE_POS_STAFF_MUTATION = "mutation CreatePosStaff($input: CreatePosStaffInput!) { createPosStaff(input: $input) { id name role active administratorId locale createdAt updatedAt } }";
2655
+ export declare const UPDATE_POS_STAFF_MUTATION = "mutation UpdatePosStaff($id: ID!, $input: UpdatePosStaffInput!) { updatePosStaff(id: $id, input: $input) { id name role active administratorId locale createdAt updatedAt } }";
2656
+ export declare const SET_POS_STAFF_PIN_MUTATION = "mutation SetPosStaffPin($id: ID!, $pin: String!) { setPosStaffPin(id: $id, pin: $pin) }";
2657
+ export declare const POS_STAFF_GRANTS_QUERY = "query PosStaffGrants($id: ID!) { posStaff(id: $id) { id role grants } }";
2658
+ export declare const POS_STAFF_GRANTS_LIST_QUERY = "query PosStaffGrantsList { posStaffList { id role grants } }";
2659
+ export declare const SET_POS_STAFF_GRANTS_MUTATION = "mutation SetPosStaffGrants($id: ID!, $grants: [PosStaffGrant!]!) { setPosStaffGrants(id: $id, grants: $grants) { id role grants } }";
567
2660
  export declare function createPosModule(transport: Transport): PosModule;