Sales & Transaction Processing
Relevant source files
The following files were used as context for generating this wiki page:The Sales & Transaction Processing system is the core feature of the POS Tio Adan application, responsible for managing the entire lifecycle of a customer sale. It is implemented within the POSApplication class in pos_app.py and handles product scanning, in-memory cart management, inventory updates, sale recording, and receipt generation. The system is designed as a monolithic component using Python's tkinter for the user interface and SQLite for data persistence.
The process begins when a user scans a product barcode in the "Venta/Salida de Inventario" tab. The system adds the product to an in-memory cart, which can be modified before checkout. Upon checkout, the system atomically decrements inventory, records the transaction details in the sales table, generates a unique folio number for the sale, and produces a printable PDF receipt. The system also includes features for viewing the last receipt and generating daily sales reports.
Sources: CLAUDE.md:5-10, pos_app.py:601-610, 1581-1616
Architecture and Data Flow
The sales process is a linear flow orchestrated by the POSApplication class, interacting with the Database class for data persistence. The cart is stored ephemerally in memory as a list of dictionaries and is cleared after each successful checkout or when the application is closed.
Sources: CLAUDE.md:21-22, 29
The following diagram illustrates the high-level data flow for a typical sales transaction.
Sources: pos_app.py:882-909, 1581-1616, CLAUDE.md:21-22
Database Schema for Sales
Sales data is persisted across two main tables in the pos_inventory.db SQLite database: sales and folio_counter. The sales table holds a record for each product sold in a transaction, linked by a common folio ID.
Sources: pos_app.py:40-54, 98-108
ER Diagram
This diagram shows the relationship between products, sales, and the folio counter.
Sources: pos_app.py:28-108
sales Table
This table records each line item of a sale. Multiple rows can share the same folio to represent a single transaction with multiple products.
| Column | Type | Constraints | Description |
|---|---|---|---|
id | INTEGER | PRIMARY KEY, AUTOINCREMENT | Unique identifier for the sale record. |
folio | TEXT | A unique identifier for the entire sale transaction (e.g., "F-0001"). | |
product_id | INTEGER | FOREIGN KEY (products.id) | The ID of the product sold. |
quantity | INTEGER | The number of units of the product sold in this transaction. | |
total | REAL | The total price for this line item (price * quantity). | |
timestamp | TEXT | The date and time the sale was recorded. |
Sources: pos_app.py:40-54, 321-329
folio_counter Table
This table ensures that each sale transaction receives a unique, sequential folio number. It contains only a single row.
| Column | Type | Constraints | Description |
|---|---|---|---|
id | INTEGER | PRIMARY KEY, CHECK (id = 1) | Ensures only one row exists. |
current_folio | INTEGER | NOT NULL, DEFAULT 0 | The last used folio number. |
Sources: pos_app.py:98-108, 303-320
Core Components & Logic
Product Lookup for Sales
When a user enters a code in the sales tab, the scan_product function executes a multi-stage search to find the corresponding item. This allows flexibility for using either internal codes (Clave) or manufacturer barcodes (Código de barras).
The lookup logic is as follows:
- Exact match on
product_barcode. - Exact match on
barcode(internalClave). - Partial, case-insensitive match on
barcode. - Partial, case-insensitive match on
product_barcode.
If a partial search yields multiple results, a selection dialog is presented to the user.
Sources: pos_app.py:882-936
Shopping Cart Management
The shopping cart (self.cart) is an in-memory list of dictionaries. Each dictionary represents a product in the cart.
Cart Item Structure:
{
"id": 123,
"barcode": "PROD-001",
"name": "Sample Product",
"price": 150.5,
"quantity": 1
}
Key cart operations are:
| Function | Description |
|---|---|
add_product_to_cart() | Adds a product to the cart or increments its quantity if it already exists. Checks against available stock. |
edit_cart_quantity() | Opens a dialog to change the quantity or apply a special price for a selected item. |
remove_cart_item() | Removes the selected item from the cart after confirmation. |
clear_cart() | Empties the entire cart. |
update_cart_display() | Refreshes the ttk.Treeview to reflect the current state of the cart and recalculates the total. |
Sources: pos_app.py:603, pos_app.py:938-971, 1079-1161, 1163-1185, 1073-1077, 1056-1071
Checkout Process
The checkout function orchestrates the finalization of a sale. It is a critical transaction that involves multiple database operations. While it does not use an explicit SQL transaction block, it processes items sequentially.
The sequence diagram below details the interactions during the checkout process.
Receipt and Report Generation
PDF Receipts
After a successful checkout, a receipt preview is shown. The user can then save the receipt as a PDF.
- Generation: The
generate_receipt_pdf()function uses theFPDFlibrary to create a PDF formatted for a narrow 80mm thermal printer. - Content: Includes business information, folio, date, and a list of items with quantities and prices.
- Location: PDFs are saved in a
recibosfolder on the user's Desktop. If the Desktop is inaccessible, it falls back to areceiptsfolder in the application's current directory.
Sources: pos_app.py:1455-1502, 590-610, 1310-1355
Sales Reports
The application provides two ways to get sales reports: manually through the UI and automatically via Telegram notifications.
Manual PDF Reports
The "Reportes" tab allows a user to generate a detailed sales report for any given date.
- Function:
generate_sales_report_pdf() - Output: An A4-sized PDF file saved in the
reports/directory. - Contents:
- Sales Summary: Total transactions, total items sold, and total revenue.
- Top 10 Selling Products: A table listing the most sold products by quantity.
- Products Without Stock: A list of all products with a quantity of zero.
Sources: pos_app.py:796-819, 1504-1579
Automated Telegram Reports
An external service, notification_service.py, runs independently to monitor the database and send daily summaries.
- Trigger: Scheduled to run at a specific time each day (e.g., 9:00 AM), defined in
config.json. - Data Retrieval: The
POSDatabaseReaderclass in the service queries thesalestable usingget_top_selling_products()andget_total_sales()to gather data for the previous day. - Notification: A formatted message is sent to a pre-configured Telegram chat, summarizing total sales and listing the top-selling products. A test message format is visible in
test_telegram.py.
Sources: notification_service.py:461-482, 303-343, 345-371, test_telegram.py:49-57, README_Notifications.txt:16-18
Summary
The Sales & Transaction Processing module is a comprehensive system that forms the commercial core of the POS application. It manages the entire sales flow from product selection to final recording and receipting within pos_app.py. The process is robust, ensuring inventory is updated in real-time and all sales are logged with a unique folio for traceability. The functionality is extended by both in-app PDF reporting and an external automated notification service, providing valuable business insights derived directly from the sales data.
Sources: pos_app.py, CLAUDE.md, notification_service.py