PROJECT_03

Ya lávame

Ya lávame — Punto de venta

Touch point of sale for a car wash: it came to replace the notebook they charged with.

TYPE
Desktop · Point of sale
STATUS
IN PRODUCTION
DIAGRAMS
4
SCREENSHOTS
3
  • Python 3.12
  • PySide6 (Qt 6)
  • SQLite
  • python-escpos
  • pywin32
  • PyInstaller
  • Inno Setup

YaLavame_Setup_1.3.0.exe Windows · no Python required

01 What it is

A touch point of sale for a car wash, in production. It replaces charging by notebook with a complete flow: pick who washed, which vehicle and which services, charge, print the ticket on the thermal printer and open the drawer. It is built to run with a finger on a touch screen, no keyboard or mouse, so any employee can use it without explanation.

  • A single desktop app in Python + PySide6 (Qt 6) with a local SQLite database: no server, no internet, no configuration.
  • Five tabs: New (charge), Cash count, History, Debtors and Admin (the latter behind a password).
  • ESC/POS ticket with logo, hardware drawer opening and five ways to connect the printer.
  • Windows installer with kiosk-mode autostart; the same core runs on Linux.

02 Charging a service

This is the screen the terminal lives on all day. Everything is big cards; there are no hidden menus or fields that need a physical keyboard.

  1. Tap the worker who handled the car. The list comes from Admin → Workers.
  2. Tap the vehicle type: sedan, SUV, pickup, motorcycle… Each has its base price in the catalogue.
  3. Tick the extras done (wax, teflon, restorer…). The total is recalculated instantly.
  4. Type what the customer paid on the on-screen numeric keypad; the app works out the change.
  5. Tap Charge: it is saved to the history, the ticket comes out and the drawer opens. If the customer will owe it, tap Assign debt and pick the debtor instead of charging.

03 The other screens

TabWhat forDetail
Cash countClosing countTotal takings, cars washed and the detail of every service of the day, per worker
HistoryLook up previous daysEvery wash with date, worker, vehicle, service, cost, paid and change
DebtorsCustomers who pay laterCreate with initial debt, add debt, record a payment, payment history and delete; amounts can be hidden with a button when people are watching
AdminPassword onlyPrices per vehicle and service, workers, password change, business name and ticket footer, printer, screen scale and drawer

On first launch the app asks for the business name and the administrator password the owner chooses; there is no factory password in production. If it is lost, scripts/fix_password.py resets it from the machine.

04 Printing and drawer

The ticket is not "printed" as a document: it is built with low-level ESC/POS commands through python-escpos, and the same code works for any way of connecting the printer. The logo goes rasterized to the paper width; the business name and the total in double height and width; at the end, paper cut and, if enabled, the drawer kick sequence (ESC p) that opens the drawer.

ModeWhenWhat it needs
windowsPrinter installed in Windows (default)The spooler name, e.g. POS-58; goes through pywin32
serialSerial or USB-serial portPort (COM3, /dev/ttyUSB0) and baud rate (9600)
networkNetwork printerIP and port, usually 9100
usbDirect USB, no driverVendor and product id (0x0416 / 0x5011); needs libusb
fileDiagnosticsWrites the ESC/POS bytes to a file to inspect them
  • 58 mm (384 dots) or 80 mm (576 dots) paper; the width decides how much the logo is scaled.
  • Test print and Test connection buttons in Admin → Printer, to get the terminal ready before putting it on the counter.
  • The drawer can also be opened by hand from Admin, without printing anything.
  • If the printer does not support auto cut, the ticket ends with three line feeds instead of failing.

05 Touch interface

  • Kiosk mode: starts full screen with its own password login and on-screen keyboard; nothing of the Windows bar is visible.
  • Own numeric and alphanumeric keyboards as Qt components, so it does not depend on the system touch keyboard.
  • Automatic scaling: the factor comes from the screen height against a baseline and is clamped between a minimum and a maximum, with a margin so the bottom buttons do not overflow on small screens. From Admin it can be set by hand for 13" or very large monitors, and card size is adjusted separately.
  • Forced light theme with its own palette: it looks the same even if Windows is in dark mode, with no invisible text. The whole look lives in one central Qt style sheet (QSS).
  • Vector SVG icons generated in code, sharp at any resolution.

06 Data

Everything lives in one SQLite file, lavado.db. The data layer (database.py) is the only thing that touches it; screens read and write through it. On first launch, if the previous version historial_lavados.json exists, it is imported into the history table without the user doing anything.

TableWhat it stores
configuracionKey-value: business name, admin password, ticket footer, printer, scale
serviciosPrice per (categoria_vehiculo, tipo_servicio), unique per pair
historialEvery wash: date, worker, vehicle, service, cost, paid and change
trabajadoresUnique staff names
deudores · pagos_deudoresTotal debt per customer and every payment with date and amount

07 Install and build

On the counter goes the Windows installer (button above): it needs no Python. It creates shortcuts and, if ticked, autostart at login so the terminal boots straight into the point of sale.

> pip install -r requirements.txt           # PySide6, pywin32, python-escpos, pyserial, Pillow
> python src\main_qt.py                     # o doble clic en inicio.bat; en Linux: ./run_app.sh
> build_installer.bat                       # 1) PyInstaller con SistemaAutolavado.spec  2) Inno Setup con installer\YaLavame.iss
>                                           # resultado: installer\output\YaLavame_Setup_1.3.0.exe
  • Paths to data/ and assets/ resolve against the project root, or next to the .exe when running packaged (sys.frozen): it works from any folder.
  • The core is cross-platform: Qt and SQLite run the same on Windows and Linux; on Linux you just pick a serial, network or USB printer instead of the spooler.
  • To keep data when reinstalling, copy the previous lavado.db into the data folder after installing.

DIAGRAMS

PRICE SUM CHARGE Worker who washed Vehicle sedan · SUV · pickup · motorcycle Extras wax · teflon · restorer Total and change on-screen numeric keypad Assign debt if the customer pays later SQLite · history saved first Ticket + drawer ESC/POS · drawer kick
01 One charge, from screen to drawer
BYTES ESC/POS ticket logo · double height · cut · ESC p Admin → Printer mode · paper 58/80 · drawer windows spooler · pywin32 serial COM3 · 9600 network IP : 9100 usb vendor · product file diagnostics Thermal printer + cash drawer
02 One ticket, five paths to the printer
READ · SAVE SQL FIRST LAUNCH Qt screens New · Count · History · Debtors · Admin database.py the only layer that touches the DB lavado.db SQLite · C:\ProgramData\YaLavame\data historial_lavados.json previous version Backup copy the file configuracion · servicios · historial · trabajadores · deudores · pagos_deudores
03 Everything in one file
1 2 · dist/ OPTIONAL src/ + assets/ Python 3.12 · PySide6 PyInstaller SistemaAutolavado.spec Inno Setup 6 installer/YaLavame.iss YaLavame_Setup_1.3.0.exe needs no Python Program Files the app · shortcuts ProgramData\YaLavame data\lavado.db · writable Autostart kiosk mode at login
04 From code to the counter

01 04

SCREENSHOTS

Charging screen: worker, vehicle type and extra services selection, with the payment summary and printer status
Charging a service
End-of-day screen with total takings, cars washed and service breakdown
End-of-day count
Admin screen with per-vehicle prices, workers, security and settings
Administration

01 01