Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:The pos-tioadan project is a desktop Point of Sale (POS) system designed for small retail operations. It features a graphical user interface for sales and inventory management, and a separate, decoupled service for sending real-time notifications. The core application is built with Python using the tkinter library for the GUI and SQLite for data persistence.
The system is composed of two main, independent components: the POSApplication and the NotificationService. The POS application is a monolithic, single-file GUI application responsible for all user-facing interactions. The notification service runs as a background process, monitoring the shared database and sending alerts via the Telegram API for events like zero-stock products and daily sales summaries. This decoupled design allows the notification service to run independently on a server or the same machine, without interfering with the performance of the main POS terminal.
High-Level System Diagram
The following diagram illustrates the high-level interaction between the system's main components. The POS Application and the Notification Service both interact with the pos_inventory.db database, but they do not communicate directly with each other.
Sources: pos_app.py, notification_service.py, CLAUDE.md
POS Application (pos_app.py)
The main POS application is a single-file monolithic application that handles all core business logic, including sales processing, inventory management, and reporting.
Sources: pos_app.py, CLAUDE.md
Core Components
The application is structured into two primary classes within pos_app.py:
Database: A dedicated class that encapsulates allSQLitedatabase operations for thepos_inventory.dbfile. It handles creating tables, adding/updating products, recording sales, and querying data.POSApplication: The main GUI class built withtkinter. It manages the user interface, including all tabs, widgets, and event handling. It uses an instance of theDatabaseclass for all data persistence.
This diagram shows the relationship between the main classes in the POS application.
Sources: pos_app.py:22-1815
GUI Structure
The user interface is organized using a ttk.Notebook widget, which provides a tabbed interface for different functionalities:
- Venta/Salida de Inventario: The main Point of Sale tab for scanning products, managing the shopping cart, and processing payments.
- Entrada y Busqueda de Inventario: The inventory management dashboard. It allows users to add/update stock, search, filter, edit, and delete products. It also includes functionality to import products from an XLSX file.
- Imprimir Ticket: A tab to view, reprint, or copy the last sales receipt.
- Reportes: A section for generating manual sales reports for a specific date.
Sources: pos_app.py:643-731, pos_app.py:733-855, pos_app.py:857-900, pos_app.py:902-959
Data Flow: Sales Process
The checkout process involves user interaction, in-memory cart management, and database transactions.
Sources: pos_app.py:996-1045, pos_app.py:1658-1699
Notification Service (notification_service.py)
This is a standalone, multi-threaded Python script that runs in the background to monitor the POS database and send alerts. It is designed to be resilient and not interfere with the main POS application.
Sources: notification_service.py, README_Notifications.txt
Architecture
The service is composed of four main classes:
| Class | Description |
|---|---|
NotificationService | The main orchestrator. It loads configuration, sets up logging, and manages the lifecycle of worker threads. |
POSDatabaseReader | Provides read-only access to the pos_inventory.db to fetch product and sales data. |
StateTracker | Manages a separate notification_state.db to track sent alerts and prevent duplicates. |
TelegramNotifier | Handles all communication with the Telegram Bot API, including message formatting and sending. |
This diagram illustrates the relationships between the service's components.
Sources: notification_service.py:30-515
Worker Threads
The service runs three concurrent threads to perform its tasks:
zero_stock_monitor: Periodically polls thepos_inventory.dbfor products with zero quantity. If a new out-of-stock product is found, it uses theTelegramNotifierto send an alert andStateTrackerto record that the alert was sent.daily_report_scheduler: At a configured time each day (e.g., 08:00), it queries the database for the previous day's sales data, generates a summary report, and sends it via Telegram.health_monitor: A simple thread that logs a health check message at regular intervals to confirm the service is still running.
Sources: notification_service.py:415-455, notification_service.py:457-481, notification_service.py:503-515
Data Flow: Zero-Stock Alert
The following sequence diagram shows how a zero-stock notification is generated.
Database Schema
The system uses two separate SQLite databases to decouple the main application data from the notification service's state.
pos_inventory.db
This is the primary database for the POS application.
Sources: pos_app.py:24-114
products Table
Stores all inventory items.
| Column | Type | Constraints | Description |
|---|---|---|---|
id | INTEGER | PRIMARY KEY, AUTOINCREMENT | Unique identifier for the product. |
barcode | TEXT | UNIQUE, NOT NULL | The internal code (Clave) for the product. |
product_barcode | TEXT | The actual product barcode from the manufacturer. | |
name | TEXT | NOT NULL | Product name/description. |
price | REAL | NOT NULL | Selling price. |
quantity | INTEGER | NOT NULL | Current stock quantity. |
category | TEXT | Product category. | |
brand | TEXT | Product brand. | |
cost | REAL | DEFAULT 0 | The cost of the product. |
| Sources: pos_app.py:28-37, pos_app.py:65-71, pos_app.py:73-79, pos_app.py:81-87 |
sales Table
Logs every item sold in a transaction.
| Column | Type | Constraints | Description |
|---|---|---|---|
id | INTEGER | PRIMARY KEY, AUTOINCREMENT | Unique identifier for the sale record. |
folio | TEXT | A unique ID grouping all items in a single sale. | |
product_id | INTEGER | FOREIGN KEY to products.id | The ID of the product sold. |
quantity | INTEGER | The quantity of the product sold in this transaction. | |
total | REAL | The total price for this line item (price * quantity). | |
timestamp | TEXT | The date and time of the sale. | |
| Sources: pos_app.py:40-50, pos_app.py:53-59 |
notification_state.db
This database is exclusively used by the NotificationService to maintain its state.
Sources: notification_service.py:28-59
notified_products Table
Tracks which products have already had a zero-stock alert sent to prevent duplicates.
| Column | Type | Description |
|---|---|---|
product_id | INTEGER | PRIMARY KEY. The ID from the products table. |
barcode | TEXT | The product's internal code. |
product_name | TEXT | The product's name. |
notified_at | TEXT | Timestamp of when the notification was sent. |
| Sources: notification_service.py:33-40 |
daily_report_log Table
Logs when daily reports were successfully sent to avoid sending more than one per day.
| Column | Type | Description |
|---|---|---|
id | INTEGER | PRIMARY KEY, AUTOINCREMENT. |
report_date | TEXT | The date for which the report was generated (e.g., "2023-10-27"). |
sent_at | TEXT | Timestamp of when the report was sent. |
top_products_count | INTEGER | Number of products included in the report. |
total_sales | REAL | Total revenue for the reported day. |
| Sources: notification_service.py:43-51 |
Configuration & Deployment
Notification Service Configuration
The NotificationService is configured via a config.json file. This allows for easy changes to bot credentials, polling intervals, and message templates without modifying the source code.
| Section | Key | Description |
|---|---|---|
telegram | bot_token, chat_id | Credentials for the Telegram bot. |
polling | zero_stock_interval_seconds | How often to check for out-of-stock products. |
daily_report | send_time, timezone | When to send the daily sales summary. |
database | pos_db_path, state_db_path | Paths to the SQLite database files. |
notifications | out_of_stock, daily_report | Templates and enable/disable flags for messages. |
| Sources: config.example.json, notification_service.py:365-376, test_telegram.py:13-22 |
Build Process
The project includes a batch script (build_exe.bat) that uses PyInstaller to package the pos_app.py script and its dependencies into a single standalone Windows executable (POS_TioAdan.exe). This simplifies deployment for non-technical users, as it doesn't require a Python installation on the target machine.
Sources: build_exe.bat:16-20