POS
A register, kitchen display and cash drawer for selling in person, with tables, receipts, recipes and staff PINs.
POS is the register a business sells from in person. It holds the menu, open tickets, tables, payments and the cash drawer, sends dishes to the kitchen display and printers, and signs staff in by PIN. A recipe on a menu item draws its ingredients from Inventory, so stock goes down as dishes are fired. Shop products come from Catalog when it's on, and Guest ordering lets diners add to their own ticket from a table QR code. Discounts come from Discounts, the same ones the shop uses. POS doesn't own stock counts, the staff directory, discounts or online orders: those belong to Inventory, Staff, Discounts and Storefront.
Discounts on a ticket
- Automatic discounts ring up by themselves. Every time a line is added, changed or removed, or a member is added, the ticket is priced again and each line shows its discount. A register item linked to a shop product gets that product's discounts, so a sale on a shop collection applies in store too.
- The Discounts button on the ticket shows what applies and why. The cashier enters a customer's code there, or picks a staff discount for the whole ticket. A staff discount needs the role it names: a cashier asking for a managers-only discount is refused.
- Free gifts. When the ticket earns a free item, the cashier sees Add free … and taps it to add the item at no charge.
- Bill discount. On the pay screen, Discount takes an amount, a percentage or the whole bill off, with a reason; a cashier's needs a manager's PIN. Redeeming points is the same bill discount, so one replaces the other. It comes off after the Discounts page's discounts, and it can take at most what they leave of the bill, service charge included.
- Receipts. A discounted line names its discount and what it took off, and the receipt ends with what the customer saved.
- Offline. The register keeps a copy of the live discounts and shows the same discounts while it's offline. When it reconnects, the server's prices are the ones charged, as they are for menu prices: a discount that ended while the register was offline is taken off before payment.
- Usage limits. A code's use is held while the ticket is open, counted when it's paid, and given back if the ticket is voided.
What it handles
- A register that loses its connection. A cashier rings up a 51-item basket while offline and the tab reloads. The register keeps the queued basket, sends it in order once it's back online, and every line lands once. If the server refuses a line, a quantity change queued behind it is dropped too and both report why. Tested: "Pos: register offline queue"
- A register that sends the same command twice. A resent command gets the recorded answer and creates nothing new, and a split check resent by the register doesn't split twice. A command from a device that isn't a registered register is refused without creating one. Tested: "Pos: commands" Tested: "Pos: split-check"
- Cancelling food the kitchen already has. A cashier can't cancel a fired dish alone: it needs a manager's approval, and the approver is recorded in the ticket's history. A non-manager can't approve, nobody approves their own cancellation, and an approval expires five minutes after it's given. An approval covers the one action on the one order it names, such as voiding order #12, and is used up by it. Tested: "Pos: approvals" Tested: "Pos: an approval covers one command"
- A QR payment confirmed by more than one path. A paid Beam charge can be reported by the provider's webhook, the register's status check and the background sweep, in whichever order they arrive. The ticket closes once with one receipt number. A webhook that fails on a database error is retried by the provider, and the retry and later duplicates still close the ticket once. Tested: "Pos: settlement-race" Tested: "Pos: payment-webhooks"
- Two taps on Charge. Two charge requests for the same payment create one charge with the provider. An app with no payment connection fails the QR charge at once, and the cashier can take the card on a separate machine instead. A register can't charge a ticket from another location. Tested: "Pos: beam-charge"
- Cash drawers. A drawer can't be opened twice, and one register can't move cash in or close the drawer session of another. A business that switches the drawer off still takes cash and records cash refunds, with no drawer session. Tested: "Pos: cash" Tested: "Pos: drawer disabled"
- A lost iPad or a stranger with a register's id. A register's orders, tables and cash drawer answer only a browser signed in on it. Devices shows how many browsers are signed in to each register, and Sign out these browsers sends them back to the PIN pad. Changing a person's PIN, role or location signs out their open sessions. When the owner keeps the sample business, its demo PINs stop working. Tested: "Pos: register sign-in" Tested: "Pos: sessions follow staff changes" Tested: "Keep sample data: the demo PINs stop working"
- More than one location. A register belongs to one location. It can't add to, take payment on, or void a ticket from another location, its live ticket feed shows only its own location, and a deactivated register gets nothing. Tested: "Pos: authz-matrix"
- Ingredients running out. Firing a dish deducts each ingredient of its recipe, in the right units, once, even if the deduction is retried after a crash. With auto sold-out switched on, a dish whose stock can't cover one more recipe is refused at the register and comes back when stock is received. A dish staff marked sold out by hand stays sold out. Tested: "Pos: stock-deduct" Tested: "Pos: auto sold-out from stock"
- Two registers ringing one ticket under a discount. Two registers adding to the same ticket, one after the other or at the same moment, end with the discounts one register would give. A one-use code closes on one ticket and is refused on the next, and voiding a ticket gives its code back. A cashier can't apply a managers-only staff discount; a manager can. Tested: "Pos: check discounts"
- A shop sale rung up in store. A 20% sale on a shop collection takes ฿100 off a ฿500 register item linked to a product in it, before the service charge and VAT, in both VAT modes, so the service charge isn't taken on money the customer didn't pay. Tested: "Pos × catalog: a collection discount at the register"
- The screen and the bill agree. The register's own total for a ticket with a discounted line matches what the server charges. Tested: "Pos: money-parity"
What you build on top
- Modules that add to the register. Catalog lets the register sell shop products and link a
menu item to one through the
pos.menu-item-linkslot. Customers puts its search-and-scan finder in the Find or add customer dialog throughpos.customer-finder. Queue offers waiting parties in the seating dialog throughpos.register-seating-picks. Booking lets register staff work their bookings, and Membership adds loyalty points and member discounts. - Your own register pages and panels. Add a page to the register menu with
pos.register-nav, or a panel on the order screen, the register, a table, or above the menu withpos.register-panel. Guest ordering uses that slot for its order panel, request inbox and table QR. See Extend a Module. - Payments. QR and terminal card payments go through the app's Beam payment connection. Without one, the register takes cash and records card payments taken on another machine.
- Menu photos. Menu item photos need the optional
mediafile storage connected to the app. - Your words and setup. The register's home screen and switched-on features follow the business type. Rename what staff see with an override.
- In code. Your coding agent imports POS only through its public API:
index.tsandserver/index.tsinapps/web/src/modules/pos/. See Build on a Module.
Limits
- Refunds in POS are cash only. POS refuses to refund an order paid by card or QR; return that money through the payment provider.
- A card payment taken on a separate machine is recorded on the ticket, not charged by POS.
- POS doesn't hold stock quantities. Recipes read and deduct Inventory items, and receiving stock happens in Inventory.
Facts
- Kind: feature Module, can be switched on and off
- Needs: Audit log, Branches, Discounts, Formatting, i18n, Identity, Infra, Inventory, Staff, Outbox, Standard UI
- Needed by: Guest ordering
- Adds to these when they're on: Catalog, Customers, Booking, Queue, Supply chain, Account, Tour, Membership
- Added to by: Finance, Outbox, Storefront, Supply chain
- Off by default for these business types: Tour operator, Online classes, Car hire, Snack store
Pages
| Where | Path |
|---|---|
| Register | /register |
| Customer site | /visit |
| Kitchen display | /kitchen |
| Admin | /admin/pos/menu |
| Admin | /admin/pos/devices |
| Admin | /admin/pos/staff |
| Admin | /admin/pos/orders |
| Admin | /admin/pos/reports |
| Admin | /admin/pos/recipes |
| Admin | /admin/pos/production |
| Admin | /admin/pos/receipt |
| Admin | /admin/pos/venue |
| Admin | /admin/pos/settings |
Permissions
Admin holds every key. The other roles listed hold it when the app first gets the Module; after that, roles are yours to change under Settings → Roles & Permissions.
| Permission | What it allows | Organization roles that start with it |
|---|---|---|
admin-panel:write | Full compatibility access to all module administration, including POS, catalog, storefront, and CRM staff tools. | Admin |
pos-menu:write | Manage POS menu items, categories, modifiers, stations, and order modes. | Admin, Manager |
pos-devices:write | Pair, configure, and unpair POS devices, registers, printers, and terminals. | Admin, Manager |
pos-staff:write | Manage POS staff accounts, roles, and PINs. | Admin, Manager |
pos-orders:write | View POS orders and record refunds and reprints. | Admin, Manager, Staff |
pos-reports:read | View and export POS sales, session, and margin reports. | Admin, Manager, Viewer |
pos-settings:write | Configure POS settings and receipt layout. | Admin |
Data
- Tables:
bom_line,cash_movement,cash_session,device,dining_table,floor_fixture,floor_zone,discount,menu_category,menu_change,menu_item,menu_item_modifier_group,modifier,modifier_group,order_event,order_item,order_mode,pos_payment,pos_command,pos_counter,pos_order,price_override,print_job,printer,register_credential,register_setup,routing_rule,staff_token,station,terminal,pos_visit,prep_recipe,prep_recipe_line - File storage
media: optional, shared across the organization
Slots
Places other Modules and your app code can add to. See Extend a Module.
pos.register-panelpos.menu-item-linkpos.register-seating-pickspos.register-navpos.customer-finder
Tested workflows
- Pos: Beam activated and deactivated while the register runs
- POS on the admin home and in search
- Pos: admin-auth-matrix
- Pos: adopt-edge-printer
- Pos: authz-matrix
- Pos: beam-charge
- Pos: bolt-charge
- Pos: cash
- Pos: commands
- Pos: counters
- Pos: customer-lookup
- Pos: devices-admin
- Pos: drawer disabled
- Pos: edge-admin
- Pos: effect-drain-wiring
- Pos: feature-switches
- Pos: fire-on-close
- Pos: inventory engine
- Pos: inventory-register-auth
- Pos: item-move
- Pos: item-update
- Pos: janitor
- Pos: janitor-operational
- Pos: janitor-schedule
- Pos: kds-display
- Pos: kds-recipes
- Pos: location VAT rate
- Pos: menu-admin
- Pos: menu-availability
- Pos: menu-management
- Pos: modifier-defaults
- Pos: money
- Pos: money-parity
- Pos: check discounts
- Pos: order-core
- Pos: order-mode-capabilities
- Pos: order-modes
- Pos: the register follows the business type
- Pos: orders-admin
- Pos: payment-webhooks
- Pos: payments
- Pos: peripherals-deletion
- Pos: peripherals-pool
- Pos: peripherals-register-defaults
- Pos: peripherals-resolution
- Pos: pos-integrity
- Pos: print-dispatch
- Pos: printing-operational
- Pos: rate-limit-wiring
- Pos: receipt
- Pos: receipt-customization
- Pos: receipt language
- Pos: register-choices
- Pos: register without Loyalty
- Pos: register setups
- Pos: register setup at runtime
- Pos: reports
- Pos: reprint
- Pos: settings-admin
- Pos: settlement
- Pos: settlement-race
- Pos: staff
- Pos: staff-admin
- Pos: state-machine
- Pos: station ticket printer
- Pos: stock-deduct
- Pos: auto sold-out from stock
- Pos: recipe spreadsheet import
- Pos: recipe costing
- Pos: recipes-api
- Pos: sync-endpoint
- Pos: transport-contract
- Pos: branch-availability
- Pos: tables
- Pos: floor fixtures
- Pos: a shared recipe reads each Location's own stock
- Pos: split-check
- Pos: approvals
- Pos: guest-lines
- Pos: menu-media
- Pos: dining visits
- Pos: located admin scope
- Pos: located admin staff writes
- Pos: sessions follow staff changes
- Pos: an approval covers one command
- Pos: register sign-in
- Keep sample data: the demo PINs stop working
- Pos: branch predicates go through identity
- POS: staff location binds the register they may sign in on
- POS: staff picked first, then their PIN
- Pos: session branch resolver
- Pos: audit
- Pos: register offline queue
- Pos: portal visits
- Pos: receipt profile QR
- Pos: tour sample ticket
- Pos: allergy-note
- Pos: allergy-kitchen
- Pos: warehouse-role
- POS: staff register language
- POS: manual discount and comp
- POS: bill discount on top of line discounts
- POS: completing a check a move left unpriced
- POS: kitchen cancellation slips
- Pos: catalog retail sale (with Catalog on)
- Pos: register sales on the shared shelf (with Catalog on)
- Pos: every register close takes the stock once (with Catalog on)
- Pos: a register sale whose stock write failed is retried (with Catalog on)
- Pos: the register sale outbox (with Catalog on)
- Pos × catalog: sell a product at the register from its page (with Catalog on)
- Pos × catalog: the ledger migration links what matched by SKU (with Catalog on)
- Pos × catalog: seeded take-home shelves (with Catalog on)
- Pos × catalog: a collection discount at the register (with Catalog on)
- POS + customers: activity projection (with Customers on)
- POS + customers: source panel (with Customers on)
- POS + customers: walk-in capture at the register (with Customers on)
- POS + customers: save this visit link (with Customers on)
- POS + customers: customer lookup at the register (with Customers on)
- Pos + booking: dining reservations (with Booking on)
- Pos + booking: booked staff retirement (with Booking on)
- Pos + booking: dining seat location (with Booking on)
- Pos + booking: register staff work their bookings (with Booking on)
- POS + Booking: register menu follows features in use (with Booking on)
- POS + Booking: the register opens on the business type's home (with Booking on)
- Pos + booking + staff: commission and tips for the people who did the work (with Booking on)
- Pos + queue: seat from queue (with Queue on)
- Pos + queue: register staff auth (with Queue on)
- Pos: stock-operational (with Supply chain on)
- Pos: pos-rewards-accrual (with Membership on)
- Pos: pos-rewards-audit-gaps (with Membership on)
- Pos: pos-rewards-binding (with Membership on)
- Pos: rewards-redeem (with Membership on)
Operator Guide pages
Pages this Module adds to the app's built-in Guide for the people who run the business.
- Tables, seats, and seated parties
- Bookings at the register