POS terminal
Purpose and who uses it
Restaurant MgrAccountantHotel ManagerWaiters and bar staff ring up orders; supervisors authorise sensitive discounts; managers open and close shifts.
The POS terminal is the screen a server stands at. Each hotel has one or more outlets (a restaurant, a bar) with their own menu, tables and service-charge rate. A sale is a ticket of lines; lines are sent to the kitchen, adjusted, voided with a reason, discounted, split, and finally settled by a tender, cash, mobile money, card, or a charge to an in-house guest's room folio.
The terminal sits under the Payments permission module. Anyone with Payments at Can edit can ring and settle; Payments at View only sees the ticket and totals but no buttons. Discounts flagged as needing authorisation ask for the email and password of a supervisor who holds Payments or Settings at Full.
Screen anatomy
Outlet and shift bar on top, category rail on the left, menu grid in the middle, the ticket on the right.
- 1Outlet switch and shift chipOne button per outlet (fork icon for restaurants, glass for bars). When a shift is open a chip shows its code and “Shift open · <opener>”. New ticket sits at the right end.
- 7Category railPopular (starred items) first, then each menu category with its item count. Typing in the search box overrides the rail.
- 2Menu gridOne tile per item: name, “N options” when it has modifier groups, price, a star if popular. Unavailable items are dimmed and marked 86'd.
- 6Search“Search the <outlet> menu…” filters every category by name; the count of shown items sits beside it.
- 3Ticket headPick table (or the assigned table number), the TKT-… code, a badge with “N to send” or the kitchen status, Covers stepper, and a Room · guest banner when the ticket belongs to an in-house room.
- 4Ticket linesName, modifiers, kitchen note, quantity stepper, a “sent” tag once fired, the void bin icon, and the line total with unit price.
- 5Totals and actionsDiscount select, Split, then Subtotal · discount · Service N% · VAT · Total due, and the two big buttons Send (N) and Pay.
If the hotel has no outlet the page shows “No POS outlet configured for this hotel.” Outlets, tables and menus are seeded per hotel; the per-outlet service % and the discount and void-reason lists are edited in Settings → Ops config.
Shifts
Restaurant MgrAccountantOne open shift per outlet; the shift report totals tenders, discounts and voids at close.
A shift (code SHF-…) is opened per outlet with an opening float and closed with an optional cash count. Only one shift can be open per outlet at a time, the server locks the outlet while it checks, and a database constraint backs it up, so two managers opening at once get one shift, not two.
- 1OpenPOST /pos/shifts/open with the outlet and the opening float (whole shillings, ≥ 0). The terminal then shows the green shift chip with the code and who opened it.
- 2TradeTickets are not blocked by the absence of a shift; the chip is informational. Everything closed between open and close belongs to the shift.
- 3ClosePOST /pos/shifts/:id/close with optional closing notes and a denomination count (note value × count). The stored report holds ticket count, gross sales, total discounts, void count and value, totals per tender method, and the counted cash.
Building a ticket
Restaurant MgrTap items to add them, pick a table or room, set covers, adjust quantities; a ticket is created the first time you need one.
- 1StartTap a menu tile, click Pick table, or click New ticket. If no open ticket is selected, the first tap creates one (TKT-…, 1 cover) on the current outlet. The terminal reopens the most recent open ticket for the outlet when you return.
- 2Table or walk-inPick table opens the floor by zone; each tile shows the number, seats and status. Choose a table, or Walk-in / no table. The table turns “open”; moving the ticket elsewhere frees the old table.
- 3Room serviceA ticket created against an in-house room (roomId) is linked to that guest's booking and shows a Room N · guest banner. The link is also made at payment time if you choose Charge to Room.
- 4Add itemsTapping a plain item adds one straight away (“Added <name>”). Items with options open the modifier sheet.
- 5QuantitiesUse the − / + stepper on a line (1–99). Taking an unsent line to zero deletes it; taking a sent line to zero opens the void dialog instead.
- 6CoversThe Covers stepper (1–20) sets how many guests; it also decides how many ways Split evenly divides the bill.
The modifier sheet
Titled with the item name and “Choose options · UGX … base”. Each modifier group is a row of chips; a group marked · required must have a choice (single-choice required groups preselect the first option), · choose any allows several. Price deltas show as +2K / −1K on the chip. Below is theKitchen / bar note (“e.g. allergy, no peanuts”), a quantity stepper and the running unit × qty price. Add to ticket stays disabled until every required group has a choice.
Sending to the kitchen and voiding
Restaurant MgrSend fires every unsent line and starts the kitchen ticket; voiding a sent line needs a reason and is audited.
Send
- 1Check the badgeThe ticket head shows “N to send” in purple while unsent lines exist; once everything is fired it shows the kitchen status instead.
- 2Click Send (N)All unsent, non-voided lines are marked sent; the ticket's kitchen status moves from new to preparing if it was new. Toast: “N items sent to kitchen”. The kitchen sees it on the Restaurant order board immediately.
- 3Add more laterNew lines start unsent; Send fires just those. Send is disabled when nothing is waiting (“No unsent lines” if forced).
Void a line
Click the bin icon on a line (or step a sent line to zero). The Void item dialog shows “2 × Chicken curry · UGX 48,000” and the reason list from Settings (defaults: Guest changed mind · Wrong item rung · Item unavailable / 86'd · Quality complaint · Duplicate entry · Manager comp).Keep item cancels; Void item confirms.
Discounts and split bills
Restaurant MgrWhole-ticket percentage discounts, some needing a supervisor; split evenly by covers or move items to a new ticket.
Discounts
The select under the lines lists the hotel's discounts (defaults: No discount · Staff meal 30% (auth) · Happy hour 20% · Loyalty member 10% · Manager comp 100% (auth)). A discount applies to the whole ticket subtotal and shows as a red line with its label; the ticket copies the label and % so later edits to the list do not change old tickets.
- 1Pick a discountOnes without “(auth)” apply immediately.
- 2Supervisor authorisationOnes marked “(auth)” open “Discount authorization, Enter supervisor credentials to continue” with Supervisor email and Password. Authorize sends them with the request.
- 3Server checkThe supervisor must be an active user of this hotel with Payments or Settings at Full access. On success the toast says “Discount applied”.
Split bill
Split opens “Split bill · TKT-… · table · UGX … due” with two modes.Split evenly divides every line by the number of covers (minimum 2), creating one child ticket per extra guest with the same table, room and discount; the original keeps its share. Split by itemlets you tick lines and Move to new ticket; the panel shows what goes to the new ticket and what stays. Each child is a normal ticket that is sent and paid separately.
Taking payment
Restaurant MgrAccountantPay opens the tender drawer; settling closes the ticket, prints the receipt, depletes stock and, for room charge, posts to the folio.
Pay (enabled once the ticket has a live line) opens the Take payment drawer: “TKT-… · table · outlet”, four tender tiles, the Balance due card and a right-hand panel that changes with the tender.
| Field | Type | Notes |
|---|---|---|
| Cash | UGX drawer | Quick-cash chips 10K · 20K · 50K · 100K · 200K and Exact, plus a numpad. Entering more than due shows Change and the button reads “Settle · change UGX …”. |
| Mobile Money | MTN / Airtel | Provider select (MTN Mobile Money · Airtel Money) and Reference / phone. Settle needs at least 3 characters of reference. |
| Card | Visa · Mastercard | Card auth reference (“Auth code or last 4 digits”), at least 3 characters. |
| Charge to Room | Posts to folio | Charge to room select listing every in-house room as “Room N · guest”. “Posts to the guest folio as an F&B charge. Amount settles at check-out.” |
- 1Choose the tender and fill its fieldThe Settle button stays disabled until the tender's rule is met.
- 2Settle UGX …The ticket is recalculated, a tender row is written for the full total (one tender per ticket, no mixed tenders), the ticket closes, its table goes to “bill”, and the audit log gets pos.ticket.closed with method and total.
- 3ReceiptThe receipt PDF opens in a new tab (/api/pos/tickets/<id>/pdf): outlet, table or room, covers, server, live lines with modifiers and notes, discount, service, VAT, total and the tender. Toast: “Ticket settled” or “Posted to guest folio”.
- 4StockEvery live line with a recipe depletes its stock items. Stock never goes below zero: the decrement is clamped to what is on hand, the movement records what was actually taken, and any shortfall raises the notification “Stock short: <item>” (“TKT-… needed 6 but only 4 was on hand · count and adjust”). The sale itself is never blocked.
Ticket, kitchen and table statuses
A ticket is open or closed; its kitchen status runs new → preparing → ready → served; tables carry their own status.
- Open → Closed (Settle (any tender))
Every edit, lines, covers, table, void, discount, split, send, needs the ticket to be Open; a closed ticket answers “Ticket is closed”. Closing a ticket with a kitchen status of new moves it topreparing so the kitchen still sees it. The kitchen flow itself (new → preparing → ready → served) is driven from the Restaurant & kitchen boards.
| Field | Type | Notes |
|---|---|---|
| free | No ticket. Grey border in the picker. | |
| seated | Guests sat, no ticket opened yet (blue). | |
| open | A ticket is attached to the table (purple). Set when a ticket is created on or moved to the table. | |
| bill | The ticket has been settled (amber). Set when the ticket closes. | |
| dirty | Needs clearing before reuse (red). |
The terminal itself only writes free, open and bill; seated and dirtyexist for the floor picker's colours and for seeded data.
Ticket and line fields
What a ticket and a line carry, and the limits the server enforces.
| Field | Type | Notes |
|---|---|---|
| Outlet * | Chosen in the top bar; fixes the menu, tables and service %. | |
| Table | Optional; from Pick table. One outlet's tables only. | |
| Room / booking | Optional; links the ticket to an in-house guest for room charge and the Room banner. | |
| Covers | 1–20 | Default 1. Drives Split evenly. |
| Note | ≤ 300 chars | Ticket-level note (API). |
| Discount | One of the configured discounts; label and % are copied onto the ticket. |
| Field | Type | Notes |
|---|---|---|
| Menu item * | Must be available (not 86'd). Name and price are copied at the time of adding. | |
| Qty | 1–99 | Line total = (price + modifier deltas) × qty. |
| Modifiers | Label and price delta per chosen option; required groups enforced on the sheet. | |
| Note | ≤ 200 chars | Kitchen / bar note printed on the receipt and shown on the kitchen card. |
| Void reason * | ≤ 200 chars | Required when voiding; chosen from the Settings list. |
Permissions
The terminal is guarded by the Payments module: View to look, Can edit to ring and settle, Full to authorise discounts.
| Role | Payments | Settings |
|---|---|---|
| Super Admin | Full | Full |
| Hotel Manager | Full | Edit |
| Receptionist | View | None |
| Accountant | Full | None |
| Housekeeping Mgr | None | None |
| Maintenance | None | None |
| Restaurant Mgr | Edit | None |
| HR Manager | View | View |
| Security | None | None |
- See the terminal, menu, tables, tickets, shift and receipts: Payments · View only.
- New ticket, add/adjust/remove lines, table, covers, Send, void, discount, split, Pay, open and close shifts, kitchen status: Payments · Can edit.
- Authorise an “(auth)” discount: the supervisor whose credentials are entered needs Payments · Full or Settings · Full.
- Edit discounts, void reasons and outlet service %: Settings · Can edit, in Settings → Ops config.
Tips
Popular tab, search, live refresh, receipts and the audit trail.
Errors you may see
Every message the POS API can return, verbatim.
Ticket is closedTicket already closedAdd items before closingMenu item unavailableLine is voidedLine already voidedUse void-line for sent itemsNo unsent linesUnknown discountSupervisor credentials required for this discountSupervisor credentials invalidSupervisor must have Payments or Settings at Full levelNo active lines to splitlineIds required for by_item splitNo matching linesCannot move KDS from <from> to <to>Select the mobile money networkRoom or booking required for room chargeNo checked-in guest in that roomBooking required for room chargeNo open folio for this booking. Check the guest in firstFolio is closedShift SHF-… is already open for this outletShift already open for this outletShift already closedoutletId requiredYour role (<role>) has "View only" on Payments; this action needs "Can edit".Terms
Outlet, ticket, cover, 86'd, tender, room charge, shift.
- Outlet
- A selling point (restaurant, bar) with its own menu, tables, service % and shifts.
- Ticket
- One bill (TKT-…): lines, discount, totals, one tender. Open until settled.
- Cover
- A guest at the table; sets how many ways Split evenly divides.
- 86'd
- Kitchen slang for “sold out / off the menu”. An unavailable item cannot be rung.
- Tender
- How a ticket is settled. The terminal offers Cash, Mobile Money, Card and Charge to Room; the shared tender enum also lists cash, momo, card, room, voucher, staff for reporting.
- Room charge
- A tender that posts the ticket to the in-house guest's open folio; settled at check-out.
- Shift
- An opened/closed trading period per outlet (SHF-…) with a float and a close report.