POS terminal
Purpose and who uses it
Restaurant MgrAccountantHotel ManagerWaiters and bar staff ring up orders; a manager approves the sensitive ones with their PIN; 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; a small hotel has just the one) with their own menu, tables and service-charge rate. An outlet is a menu and a bill; where the work is done is the station on the dish, kitchen or bar. The till shows every menu at once, so a table's food and its drinks go on one ticket and each line reaches the board that makes it. A sale is a ticket of lines; lines are sent to the kitchen, adjusted, voided with a reason, discounted, split, and finally settled by one or more tenders, cash, mobile money, card, or a charge to an in-house guest's room folio. Several orders stay open side by side: the Open orders strip under the outlet switch lists every open ticket in the hotel (naming the outlet when more than one has orders open), and a tap brings it back onto the panel, so a waiter can work three tables at once.
The terminal sits under the Restaurant permission module. Anyone with Restaurant at Can edit (a Waiter, a Chef, the Receptionist) can ring, send and print the bill; Restaurant at View only sees the ticket and totals but no buttons. Settling a bill (taking cash, mobile money, card or a room charge) is Restaurant at Full: the Cashier, the Restaurant Manager and the managers. A waiter sees Print billwhere Pay would be and takes the bill to the cashier. Cancelling an order that already went to the kitchen, editing the menu and closing a shift also need Restaurant at Full. A flagged discount or a refund asked for by somebody without that level opens an Approve dialog: pick a manager from the list and they tap their own four-digit approval PIN. Nobody signs out, and the audit row names both people. Voiding a line the kitchen already has needs no manager: anyone who can ring gives a reason, and the audit log records who voided it and why.
Screen anatomy
Outlet and shift bar on top, category rail on the left, menu grid in the middle, the ticket on the right.
- 1Menu switch and shift chipAll menus, then one button per outlet (fork icon for restaurants, glass for bars). The button that is lit says whose menu the grid is showing; tapping an outlet also moves the ticket, its shift and its tables to it, and the outlet you are on keeps a thin ring while All menus is up. When a shift is open a chip shows its code and “Shift open · <opener>”. New ticket sits at the right end.
- 2Menu gridOne tile per item from every menu the hotel sells: name, the section it comes from (“Bar · Beers”) while searching, “N options” when it has modifier groups, price, a star if popular. Sold-out dishes leave the grid; a “N sold out” chip next to the search shows them greyed. 24 tiles a page.
- 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 Kitchen or Bar tag when the ticket holds both, the stage once fired, the red void bin, 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 (Print bill for a waiter, who does not settle).
- 6SearchThe search finds a dish or a drink by any word of its name, section or description, and the count of matches sits beside it. The menu it searches is the one the switch at the top has chosen.
- 7Category railPopular (starred items) and All items first, then every section grouped under the menu it belongs to, each with its item count. Typing in the search box overrides the rail.
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.
- 1OpenOpen shift (Restaurant · Full access, next to the outlet chips) asks for the opening float, the cash in the drawer before the first sale. The terminal then shows the green shift chip with the code and who opened it; without one it reads “No shift open”.
- 2TradeEvery ticket that closes on the outlet is stamped with the shift. By default the till still sells without a shift; Settings → Hotel → “Require an open shift to take money at the till” makes cash, card and mobile money refuse (“No shift is open on this outlet”) until one is opened.
- 3CloseClose shift opens the drawer count: a row per note (50,000 down to 100 shillings) with a count, plus closing notes. If tickets are still open the close is refused and offers “Close the shift anyway”, in which case their money rolls to the next shift and the report says so.
- 4Read the Z-reportTickets (and refunds), gross sales, discounts, voids, a line per tender method, the opening float, the cash expected in the drawer (float plus the net cash taken, change and refunds already netted), the cash counted, and Balanced / Over / Short. The same report is stored with the shift and audited.
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. A second course on an order the kitchen already marked Ready or Served puts the ticket back into Cooking on the kitchen display. Send is disabled when nothing is waiting (“No unsent lines” if forced).
- 4Watch each line come backEvery sent line carries a word from the pass: in kitchen, ready or served; the header badge reads “2 of 3 ready” until the last plate is up, then the ticket's kitchen status. The open-orders strip shows “ready” on a ticket whose food is all up. Print bill prints the same word beside each item.
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 sold out · Quality complaint · Duplicate entry · Manager comp).Keep item cancels; Void item confirms.
Discounts and split bills
Restaurant MgrWhole-ticket percentage discounts, some needing a manager's PIN; 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, and so do the flagged ones when you hold Restaurant at Full yourself.
- 2Ask a managerOnes marked “(auth)” open the Discount authorisation dialog. Approved by lists everyone who may sign this off and has an approval PIN set, and the field below takes their PIN. Approve sends the name and the PIN with the request.
- 3Server checkThe approver must be an active user of this hotel holding Restaurant, Payments or Settings at Full access, and the PIN must be theirs. On success the toast says “Discount applied”; the audit row names you and them.
Merge bills
Merge (next to Split) lists every other open ticket in the hotel, the same table or room first: the bar's tab, a second kitchen ticket, room service. Tick the ones that belong to this guest and they fold into this bill with their lines, sent state and station intact; the other tickets are cancelled with the note “Merged into TKT-…”. A ticket that already has money on it cannot be merged until its tenders are removed. One bill, one receipt, one payment.
Split bill
Split opens “Split bill · TKT-… · table · UGX … due” with three modes.Evenly asks for the number of guests (it starts at the covers, 2 to 20, and can differ from them) and divides every line that many ways, creating one child ticket per extra guest with the same table, room and discount; guest 1 stays on the original, which keeps the odd shillings. By amount lists guest 2 onwards with an amount box each (Another guest adds a row, Equal shares fills them evenly): every amount becomes a ticket of its own carrying one “Share of TKT-…” line, and guest 1 keeps the food and whatever is left, shown live at the top; the amounts must leave something for guest 1. By item lets you tick lines and Move to new ticket; the panel shows what goes and what stays. Each child is a normal ticket paid separately; a share ticket cannot be edited, only paid or cancelled, and it pays only once the pass has marked the parent's food ready.
Taking payment
Restaurant MgrAccountantPay opens the tender drawer; a bill can be taken in several tenders, and the ticket closes on its own when the balance reaches zero, printing the receipt, depleting stock and, for room charge, posting to the folio.
Pay (enabled once the ticket has a live line) opens the Take payment drawer. With the hotel settingTake money only after the kitchen marks the food ready (on by default) the drawer first lists any kitchen dish that is unsent or still cooking, and the server refuses the tender (“2 items not ready: … still in the kitchen”) until the pass marks them ready; drinks never hold a bill, and Restaurant · Full access may take the money anyway, which is written to the audit log. The drawer shows: “TKT-… · table · outlet”, the bill card (total, paid so far, balance due), the tenders already taken on this bill, four tender tiles, and a right-hand panel that changes with the tender. The amount defaults to the balance; type a smaller figure to take part of it, and the drawer reads “Take UGX … · UGX … left”.
| Field | Type | Notes |
|---|---|---|
| Cash | UGX drawer | Quick-cash chips 10K · 20K · 50K · 100K · 200K, Exact and Half, plus a numpad. Cash above the balance is change: the button reads “Settle · change UGX …”, the tender is stored net and the change is printed on the receipt. |
| Mobile Money | MTN / Airtel | Provider select (MTN Mobile Money · Airtel Money), Reference / phone (at least 3 characters) and the amount pad. Never above the balance. |
| Card | Visa · Mastercard | Card auth reference (“Auth code or last 4 digits”, at least 3 characters) and the amount pad. Never above the balance. |
| Charge to Room | Posts to folio | Charge to room select listing every in-house room as “Room N · guest”. Takes the whole balance, so it is greyed out once another tender is on the bill. “Posts the whole balance to the guest folio as an F&B charge. It settles at check-out.” |
| Pay later | On an account | For somebody the hotel lets pay later: a regular who pays next week, a company, or the manager whose guests eat “on him”. Choose the account (each shows what it already owes), or “+ Open a new account…” right there: a name, what kind, a phone, an optional limit and how many days they have to pay. Takes the whole balance like a room charge. It is not money in the drawer: it goes on the account's folio and is paid off later from Restaurant › Pay later (Receive payment), where the cash book counts it. A bill that would take the account over its limit is refused, saying how much room is left; only a manager can raise a limit or close an account. |
- 1Choose the tender, the amount and fill its fieldThe button stays disabled until the tender's rule is met. A partial amount reads “Take UGX … · UGX … left”.
- 2Take UGX …A tender row is written for what was applied to the bill (never more than the balance), the ticket stays open with the balance on the panel, the audit log gets pos.tender.taken, and the drawer lists the tender under “Taken on this bill” with an × to remove it if it was a slip.
- 3Settle UGX …The tender that brings the balance to zero closes the ticket: its table goes to “needs bussing”, the audit log gets pos.ticket.closed with method, total and the number of tenders. Two guests paying their halves are simply two tenders.
- 4Print the bill firstPrint bill on the ticket panel opens the ticket as a BILL (not yet paid) to take to the table; nothing is settled by printing. The Restaurant page's Tickets tab has the same Bill or Receipt button on every row, plus a Download that saves the PDF.
- 5ReceiptThe receipt PDF opens in a new tab (/api/pos/tickets/<id>/pdf), laid out for the paper set in Settings (an 80 mm roll by default): the hotel and its TIN, the outlet, the ticket code and time, table or room, covers, Served by (whoever opened the ticket) and Cashier (whoever settled it, when that is someone else), each line with its unit price, discount, service, VAT, total, every tender and the change, then the hotel's own footer. A second print says Reprint. Toast: “Bill settled” or “Posted to guest folio”.
- 6StockEvery 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 (Balance reaches zero)
- Open → Cancelled (Cancel (no money taken))
Every edit, lines, covers, table, void, discount, split, send, needs the ticket to be Open; a closed ticket answers “Ticket is closed”. Cancel on the ticket head cancels an open order nothing has been paid on: anyone who can ring up may cancel a ticket the kitchen has not seen; once items were sent, only Restaurant at Full may, and every sent line is voided with the reason. A cancelled ticket keeps its code and disappears from the open orders strip. 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. The starting number of guests for Split evenly, which can be changed in the dialog. |
| 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 on sale (not sold out). 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 Restaurant module: View to look, Can edit to ring and settle, Full for shifts, tender removal, fired-line voids and refunds.
| Role | Restaurant | Kitchen | Settings |
|---|---|---|---|
| Super Admin | Full | Full | Full |
| Hotel Manager | Full | Full | Edit |
| Receptionist | Edit | None | None |
| Accountant | View | None | None |
| Housekeeping Mgr | None | None | None |
| Maintenance | None | None | None |
| Restaurant Mgr | Full | Full | None |
| HR Manager | None | None | View |
| Security | None | None | None |
| Waiter | Edit | View | None |
| Chef | View | Edit | None |
| Housekeeper | None | None | None |
| Cashier | Full | View | None |
- See the terminal, menu, tables, tickets, shift and receipts: Restaurant · View only.
- New ticket, add/adjust/remove unsent lines, table, covers, Send, void any line with a reason, discount, split, merge, Print bill, cancel an unsent ticket: Restaurant · Can edit (the Waiter).
- Settle a bill (Pay: cash, mobile money, card, room charge), open and close shifts, remove a tender, cancel a sent ticket, rename or resize tables, refund a closed ticket: Restaurant · Full access (the Cashier, the Restaurant Manager, the managers). A refund can also be approved by somebody who holds it, with their PIN.
- Kitchen status (Start cooking / Mark ready / Mark served): Kitchen · Can edit or Restaurant · Can edit.
- Approve an “(auth)” discount: the name picked in the dialog needs Restaurant · Full, Payments · Full or Settings · Full, and an approval PIN set in Staff → Accounts.
- Approve a refund: the name picked needs Restaurant · Full (the Restaurant Manager, the Cashier, a manager).
- 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 closed2 items not ready: 2 x Chips still in the kitchen; Tilapia not sent to the kitchen. Ask the pass to mark the food ready before taking paymentThis is a share of a split bill; cancel the ticket insteadEvery guest's amount must be more than zeroAdd items before closingMenu item unavailableLine is voidedLine already voidedUse void-line for sent itemsNo unsent linesUnknown discountThat approval PIN was not acceptedToo many wrong approval PINs. Try again in 15 minutesUnknown approval actionNo 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, sold out, 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.
- Sold out
- Off the menu for now (kitchens call it 86'd). A sold-out dish cannot be rung and is hidden on the till until it is back on sale.
- 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.
Refunding a closed ticket
Restaurant MgrA cash, card or mobile-money ticket that closed by mistake is reversed from the Restaurant tickets table; Restaurant Full only.
Rung twice, wrong table, a guest who sent the dish back after paying: the bill has to come back out of the till, and the books have to show it. Restaurant → Tickets shows a Refund button on every closed ticket that was paid at the till.
- 1Click RefundThe dialog “Refund TKT-…?” asks for a Reason (required, it goes on the audit trail and the receipt) and whether to Return the ingredients to stock (ticked by default; untick when the food actually left the kitchen).
- 2Confirm “Refund UGX …”Every tender on the ticket is mirrored as a negative tender of the same method, the ticket is stamped refunded with who did it, and the toast reads “TKT-… refunded”. The row shows a Refunded badge and the ticket drops out of Sales today, the reports and the night audit.
- 3Hand the money backThe receipt (Print) now carries a REFUNDED band and the negative tender rows; give it to the guest with the cash. A shift cash-up nets the refund against the day's cash.