SolvexaRetail
Manual · POS Screen Design
All TopicsBack to app

POS Screen Design

Every part of the retail POS screen is setup-driven. Nothing is hardcoded — the button strip, the color theme, whether the bottom status bar shows, and how refunds settle back are all per-terminal or per-store toggles you can change without touching code.

Two designer pages you will use:
  • /POS/POSTerminal — terminal-level settings (button strip, manager-auth flags, color theme, dual display, shift/float toggles).
  • /POS/StoreCard — store-level settings (return window in days, refund-to-same-tender flag, receipt header / footer).

Action Strip — the buttons on the right

The right-side vertical strip contains the cashier action buttons: Select Item, Customer, Change Qty, HOLD, % Line Disc., % Invoice Disc., Void Line, Void Txn, Refund, Coupon, Float, X Report, Z / Shift End, Logout, and the orange PAY button at the bottom.

Every one of these is a row in POSStripButton and is fully editable per terminal.

Add / remove / reorder buttons

  1. Go to /POS/POSTerminal and pick the terminal you want to change.
  2. Click Edit.
  3. Scroll to the Action Strip — Buttons card.
  4. Use the up/down arrows on each row to reorder. Use the to delete a button. Click + Add Button to add a new row and pick its ActionKey from the dropdown.
  5. Rename any button in the LABEL column — this is what the cashier sees.
  6. Tick On to enable, untick to hide it (soft-disable — the row stays in the DB).
  7. Tick Red to render the button with the red danger tint (recommended for Void Txn and Logout).
  8. Tick PAY to render as the big orange sticky button at the bottom — usually only payment gets this flag.
  9. Click Save Strip. The next POS session on that terminal picks up the change on next login / Init.

If you delete every row for a terminal, the POS falls back to the default 15-button list so cashiers always have something to click.

Reset to defaults restores the 15-button seed if you want to start over.

Require manager approval per button

Any button in the strip can be gated behind a manager-auth prompt (card swipe or Manager ID + PIN). Tick the Mgr column in the Action Strip designer, save, and the next time a cashier taps that button they'll see the manager auth modal first. Cashiers who already hold the underlying POS permission (for example POS.VOID) skip the prompt.

Common patterns:

  • Void Line & Void Txn — on by default.
  • % Invoice Disc. — on if you don't want cashiers giving away bill-level discounts unsupervised.
  • Refund — recommended on for stores where cashiers should not process returns without a manager.

Refund back to same tender

Set at /POS/StoreCard under the store's operational block:

  • ON (default) — when a refund is posted, the cashier taps PAY and the refund is auto-settled to the same tenders that were used on the original bill, in the same proportions. If the original bill was ₹500 UPI + ₹500 Cash, a ₹200 partial refund posts ₹100 back on UPI and ₹100 back in Cash. No cashier choice.
  • OFF — after tapping PAY the tender picker opens and the cashier chooses which tender to refund to. Use this if you always refund in cash or want operator control.

Stored as Store.RefundSameTender BIT.

Refund workflow — step by step

  1. Cashier taps the Refund button in the right strip.
  2. The right context panel switches to Refund — pick a receipt. It lists returnable receipts from the last N days (N = Store.ReturnWindowDays, default 30).
  3. Cashier can scan the receipt barcode (Code128 printed on every receipt), type the receipt number in the search box, or tap a row.
  4. The panel switches to a line picker showing every returnable line with a checkbox, a − / + quantity stepper, and a live −₹ refund total.
  5. Cashier ticks the lines to refund and adjusts the quantity (defaults to full available qty).
  6. Cashier taps Refund →. The negative-quantity lines appear on the left cart with red minus signs. Nothing is settled yet.
  7. Cashier taps PAY.
    • If Refund to same tender = ON → auto-settled to the original tenders, receipt prints. Done.
    • If Refund to same tender = OFF → the tender picker opens for the cashier to choose Cash / UPI / Card etc.

The refund receipt is a separate row in POSTransaction with TransactionType = 'Return' and a receipt number like RTN-STOREXX-000001. Line quantities and amounts are negative. Inventory (ILE) and cost ledger (VLE) reversals post automatically.

Color theme — light-green & others

Terminal-level setting: POSTerminal.ColorTheme. Set via the theme swatches on /POS/POSTerminal. Available palettes:

  • light-green (default) — white body, green accents, orange PAY button.
  • light — white body, blue accents.
  • dark-navy — dark navy, blue accents (classic POS look).
  • midnight-purple — dark purple.
  • forest-green — dark green.
  • rose-gold — dark rose.
  • slate-blue — dark slate.
  • high-contrast — accessibility.

Cashiers can override the terminal theme on their own device (stored in browser localStorage.mspos-theme-manual). Clearing that flag restores the terminal default.

Layout mode — Retail vs Hospitality

MenuProfile.LayoutMode switches between the two big layouts:

  • RetailClean — 3-bucket layout: cart on the left, action buttons in the middle strip, context panel on the right (Today's Offers by default, item picker / customer picker / refund picker on demand). No numpad. This is what a retail POS wants.
  • HospitalityTiles — tile grid on the right for menu-item ordering (dining, QSR, cafe). The tile grid is driven by MenuButton rows against the terminal's MenuProfileID.

The POS also auto-picks based on POSTerminal.TerminalType (Retail vs Hospitality) if LayoutMode is left blank.

Show / hide the bottom bar

MenuProfile.ShowBottomBar. ON (default) shows a slim footer with the date, time, store, terminal, and app-name chips. Turn OFF for kiosk / customer-facing terminals where you want a completely stripped screen.

Dual customer display

Terminal-level setting: Enable Dual Customer Display under the terminal edit page. When ON the cashier can open /POS/CustomerDisplay?terminalID=N on a second monitor / tablet — it streams the cart and Today's Offers to the shopper via BroadcastChannel (same-origin window-to-window, no server round-trip).

At payment time the UPI QR renders on the customer display, not on the cashier's screen. The cashier's screen just shows a "waiting for UPI confirmation" prompt.

Idle timeout (seconds) — seconds without cart activity before flipping to the idle content playlist. Default 30.

Idle content playlist (JSON) — array of {url, type: image|video, durationSec} to rotate when the till is idle. Leave empty for a plain branded fallback.

Ask Saathi to do it

You can ask the Saathi assistant to walk you through or make any of the changes above. Examples:

  • “How do I move the PAY button to the top of the action strip?”
  • “Make Void Line require manager approval on TERM-01.”
  • “Change our POS to the light-green theme.”
  • “Turn off refund-to-same-tender for the Bengaluru store.”
  • “Hide the bottom bar on the kiosk terminal.”
  • “How does refund work?”

Saathi answers instructional questions from this manual directly (no LLM burn). For change actions Saathi presents a preview and asks you to confirm before writing to POSStripButton / POSTerminal / Store.

Troubleshooting

  • My new buttons don't show up. Hard-refresh the POS tab (Ctrl+Shift+R). The action strip is rebuilt on every Init — the cashier needs to re-open the POS page or re-authenticate the PIN.
  • PAY button is missing after I edited the strip. Make sure at least one row has PAY ticked — that flag renders it as the sticky orange bottom button. If no row is flagged, the PAY button is absent (by design).
  • Refund lines don't appear in the cart. Check the server error toast — usually a schema mismatch. Confirm migration 411 (Store.RefundSameTender) and 412 (POSStripButton) are applied.
  • Colors look wrong. Clear the browser's mspos-theme-manual localStorage key — a cashier may have manually overridden the theme. Then the terminal's ColorTheme takes effect.
  • Refund goes to the wrong tender. Check Store.RefundSameTender and the original bill's POSTransactionPayment rows — the auto-settlement is proportional to what the customer actually paid.