Repository navigation
Code audit fixes, a roomier Reports screen, and better menu and retail item management - #434
Merged
Merged
Conversation
A percent off was worked out on the lines that may be discounted, but its share of each tax class was spread over every taxed line by sales. A 50% discount on $10 of food beside $10 of wine that can't be discounted taxed each on $7.50: too little tax on the wine, too much on the food. Each discount now carries its own share of each class: a percent off on the class's lines it applies to, a fixed amount over everything that may be discounted. When discounts are capped at the items total, each one's line on the receipt shrinks too, so they add up to what came off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
A failed batch went back on the queue and was tried again every two seconds for good. A row SQLite would always refuse (a table a standby doesn't have yet, a constraint) held up every later sale, and they piled up in memory. A row refused five times running for its own fault (not a full or busy disk) is now written to <database>.unsaved.jsonl and taken out of the line; the rest save at once, and the manager is told. Retries wait longer each time, up to a minute. Each batch prepares one statement per kind of row instead of one per row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
A stop between adding the column and moving the schema version left a database every later start refused (the column was already there). Both now happen in one transaction, and a database left that way by an older ViewTouch opens: only its version moves. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
The writer puts table and column names into its statements as they are. A standby takes them from the main server's messages, so a peer that sent something else could change what runs. Names other than letters, digits and _ are now refused and reported, never queued. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
Taking over as the main server asked for a manager's PIN with no limit on tries: a paired screen could try every four-digit PIN. After five wrong ones it now waits 30 seconds, twice as long each time after (up to 15 minutes); the right PIN starts the count again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
…tart Each piece of a long message (a welcome, a standby copy) searched the whole buffer again for its end, so a 32 MB one arriving 64 KB at a time did hundreds of times the work. Now only what's new is searched. A line past the limit on a connection that doesn't check for one (the standby, pairing) now closes it instead of growing without end. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
A screen's offline check was recognized as already taken in only among the open checks and today's closed ones. If End of Day ran before the screen heard back, sending it again booked the sale a second time. The saved days around it are looked at too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
Time punches, refunds, shifts, deliveries, problems and parties were read by time with no index, so every lookup read the whole table: slow for a store with years of data. Made on opening; an older ViewTouch (a standby a version behind) opens the database the same with them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
A terminal that couldn't reach the store's computer tried every 2 seconds forever, and a try to an address nothing answered waited for the system's own timeout (minutes). After five tries it now waits a little longer each time, up to 10 seconds, and a try still not through after 10 seconds is given up and made again. A store's answer with a port that isn't one is ignored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
"18,5" for a gratuity, a pay rate or a fee read as 0 or was refused,
while prices already took a comma. Number fields now read it the same
way ("1,250.00" still has a thousands comma).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
The reports screen put its 27 report keys in three rows (seven on a phone), the days in another, then the day bar: about a third of the screen, and on a phone nearly all of it, before the first line of the report. - The reports are a list by kind (Sales, Staff, Money, Stock, Guests, Checks) at the report's right, in the column that was empty above ‹ Manager. On a phone, one key with the report's name opens the list over the report. - The days are one row of keys to slide. Days that can't be read over several days are dimmed for reports that are one day at a time, and picking such a report goes back to one day (it showed Sales before). - Reading further down folds the days' row away; scrolling back up brings it back. - A swipe across the report goes to the next or the previous report. - Value columns are as wide as what's in them; a table wider than the screen slides sideways instead of cutting its numbers short. - Print, CSV and PDF sit beside the day (on a phone under ⋯). - The page editor's "Opens on" lists every report (Turns, Checklists, Drivers and IRS 8027 were missing). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
The Menu Builder showed one category's items as tiles at a time, its Find matched only a name or an exact number (30 at most), and Select could move, color, sell out or remove items, but not change prices or tax. - ☰ List shows every item in one table: name, category, price, tax and number or barcode. A heading sorts by it (again: the other way); All Items, the category, Sold Out and No Number or Barcode narrow it. A row opens the item's card; in Select, it is chosen, and All chooses every row shown. - Find matches any part of a name, number, barcode, category or kitchen name, with no limit. - Select → Price… sets one price, or moves each item's own price by an amount or a percent, showing a few before → after first. Tax… sets the tax for all of them. One Undo each (changeMenuItems: priceAdd, pricePercent). - The card's More… opens the Menu panel on that item, not on an empty list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
- Scanning a code nothing has, with a manager logged in, offers Add an Item With It: the Menu Builder opens on a new item with that barcode. - A barcode read with a 0 in front (a scanner that reads a UPC as an EAN-13) now rings the item in, as the rest of ViewTouch already matched it. - A spreadsheet with both a Cost and a Price column now imports the price as the price. The first of the two used to win, so a shop's sheet put what it paid on the menu. A sheet with only Cost still uses it as the price. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
A shop's item (a T-shirt, a bottle of wine) could only count its stock by making an ingredient in Inventory and typing a recipe line for it in the Menu panel. The card now has Track stock, with On hand, Low at and Cost (and the margin it leaves). Behind it is an ingredient of the item's own, one used up for each sold, so everything the kitchen's stock does works for it: counted down on a sale (also a shop's, paid without being sent), back on a void, Running low, sold out by itself at none and back when restocked, Count Stock, deliveries and the Stock report. Saving the card without touching the count keeps what sold since it was opened. Turned off, an item sold out for want of its stock is for sale again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
Export wrote only ViewTouch's own file, for another store's Import…, so an owner couldn't go over prices in a spreadsheet. Export now also offers As a Spreadsheet (.csv): every item with its category, price, cost, tax, number, barcodes, stock and sold out, under headings Import… reads back (Update prices brings changed prices in). Saved with a byte-order mark, so Excel shows accented names right. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
On a store whose menu pages have buttons placed by hand, a new item didn't show up anywhere until a manager added its button, one page at a time (Also a button on). A new item's button now goes by itself on the page with its category's items (the one with the most of them), in the next free place, sized and styled like its neighbors. Removing an item already removed its buttons. Self-filling pages need neither. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A code audit with its fixes, a Reports screen that leaves room for the report, and better ways to manage menu and retail items. One commit per change, each with tests; the audit's findings are written up in
modern/docs/AUDIT-2026-10.md.Audit fixes
<database>.unsaved.jsonland the manager is told; retries back off. Migration 13 (cash tips column) is one transaction, and a database left half-migrated by it opens. Indexes for lookups by time (made on opening, not a schema version, so a standby a version behind still opens it).Left for a decision (changes saved data or a larger rework), in the write-up: past tax worked out at today's rates in range reports, doubles in labor/tip pool/stock math, the standby copy and some reads on the main thread,
adminChangedrefreshing 33 properties, the kitchen display rebuilding every card.Reports
Menu and retail items
Tests
The full suite (681 test cases) passes locally on Ubuntu 26.04 with Qt 6.10. New tests cover each fix and feature; translations for es, fr, pt and zh are included (
tools/i18n.py checkclean).🤖 Generated with Claude Code
https://claude.ai/code/session_015JJaarV4sfTKegR57HYFZ8