feat: implement SQLite-based grocery receipt tracker with add and price history features
Co-authored-by: aider (openai/unsloth/Qwen3-Coder-Next) <aider@aider.chat>
This commit is contained in:
184
app.py
Normal file
184
app.py
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
import sqlite3
|
||||||
|
from datetime import datetime
|
||||||
|
import os
|
||||||
|
|
||||||
|
DB_PATH = "grocery_receipts.db"
|
||||||
|
|
||||||
|
def init_db():
|
||||||
|
"""Initialize the database with required tables."""
|
||||||
|
conn = sqlite3.connect(DB_PATH)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# Create stores table
|
||||||
|
cursor.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS stores (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL UNIQUE
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
|
||||||
|
# Create products table
|
||||||
|
cursor.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS products (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL UNIQUE
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
|
||||||
|
# Create receipts table
|
||||||
|
cursor.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS receipts (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
store_id INTEGER NOT NULL,
|
||||||
|
date DATE NOT NULL,
|
||||||
|
total REAL NOT NULL,
|
||||||
|
FOREIGN KEY (store_id) REFERENCES stores(id)
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
|
||||||
|
# Create receipt_items table (linking products to receipts with prices)
|
||||||
|
cursor.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS receipt_items (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
receipt_id INTEGER NOT NULL,
|
||||||
|
product_id INTEGER NOT NULL,
|
||||||
|
quantity REAL NOT NULL,
|
||||||
|
price REAL NOT NULL,
|
||||||
|
FOREIGN KEY (receipt_id) REFERENCES receipts(id),
|
||||||
|
FOREIGN KEY (product_id) REFERENCES products(id)
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
def add_receipt(store_name, date, items):
|
||||||
|
"""
|
||||||
|
Add a receipt to the database.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
store_name: Name of the store
|
||||||
|
date: Date of the receipt (YYYY-MM-DD format)
|
||||||
|
items: List of tuples (product_name, quantity, price_per_unit)
|
||||||
|
"""
|
||||||
|
conn = sqlite3.connect(DB_PATH)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# Get or create store
|
||||||
|
cursor.execute("SELECT id FROM stores WHERE name = ?", (store_name,))
|
||||||
|
store = cursor.fetchone()
|
||||||
|
if not store:
|
||||||
|
cursor.execute("INSERT INTO stores (name) VALUES (?)", (store_name,))
|
||||||
|
conn.commit()
|
||||||
|
cursor.execute("SELECT id FROM stores WHERE name = ?", (store_name,))
|
||||||
|
store = cursor.fetchone()
|
||||||
|
|
||||||
|
store_id = store[0]
|
||||||
|
|
||||||
|
# Insert receipt
|
||||||
|
cursor.execute("INSERT INTO receipts (store_id, date, total) VALUES (?, ?, ?)",
|
||||||
|
(store_id, date, sum(item[1] * item[2] for item in items)))
|
||||||
|
receipt_id = cursor.lastrowid
|
||||||
|
|
||||||
|
# Insert items
|
||||||
|
for product_name, quantity, price in items:
|
||||||
|
# Get or create product
|
||||||
|
cursor.execute("SELECT id FROM products WHERE name = ?", (product_name,))
|
||||||
|
product = cursor.fetchone()
|
||||||
|
if not product:
|
||||||
|
cursor.execute("INSERT INTO products (name) VALUES (?)", (product_name,))
|
||||||
|
conn.commit()
|
||||||
|
cursor.execute("SELECT id FROM products WHERE name = ?", (product_name,))
|
||||||
|
product = cursor.fetchone()
|
||||||
|
|
||||||
|
product_id = product[0]
|
||||||
|
cursor.execute("INSERT INTO receipt_items (receipt_id, product_id, quantity, price) VALUES (?, ?, ?, ?)",
|
||||||
|
(receipt_id, product_id, quantity, price))
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
def get_product_prices(product_name):
|
||||||
|
"""
|
||||||
|
Get all prices for a specific product across all receipts.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
product_name: Name of the product
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of tuples (date, store_name, quantity, price_per_unit)
|
||||||
|
"""
|
||||||
|
conn = sqlite3.connect(DB_PATH)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
cursor.execute('''
|
||||||
|
SELECT r.date, s.name, ri.quantity, ri.price
|
||||||
|
FROM receipt_items ri
|
||||||
|
JOIN receipts r ON ri.receipt_id = r.id
|
||||||
|
JOIN stores s ON r.store_id = s.id
|
||||||
|
JOIN products p ON ri.product_id = p.id
|
||||||
|
WHERE p.name = ?
|
||||||
|
ORDER BY r.date
|
||||||
|
''', (product_name,))
|
||||||
|
|
||||||
|
results = cursor.fetchall()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
def list_receipts():
|
||||||
|
"""
|
||||||
|
List all receipts in the database.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of tuples (receipt_id, store_name, date, total)
|
||||||
|
"""
|
||||||
|
conn = sqlite3.connect(DB_PATH)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
cursor.execute('''
|
||||||
|
SELECT r.id, s.name, r.date, r.total
|
||||||
|
FROM receipts r
|
||||||
|
JOIN stores s ON r.store_id = s.id
|
||||||
|
ORDER BY r.date DESC
|
||||||
|
''')
|
||||||
|
|
||||||
|
results = cursor.fetchall()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
# Initialize the database when the module is imported
|
||||||
|
init_db()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Example usage
|
||||||
|
print("Grocery Receipt Tracker - Demo")
|
||||||
|
print("=" * 30)
|
||||||
|
|
||||||
|
# Add a sample receipt
|
||||||
|
items = [
|
||||||
|
("Milk", 2, 1.50),
|
||||||
|
("Bread", 1, 2.00),
|
||||||
|
("Apples", 3, 0.80)
|
||||||
|
]
|
||||||
|
add_receipt("SuperMarket", "2023-10-15", items)
|
||||||
|
print("Added sample receipt to database.")
|
||||||
|
|
||||||
|
# Add another receipt for comparison
|
||||||
|
items2 = [
|
||||||
|
("Milk", 1, 1.30),
|
||||||
|
("Bread", 1, 1.80)
|
||||||
|
]
|
||||||
|
add_receipt("Corner Store", "2023-10-20", items2)
|
||||||
|
print("Added another receipt to database.")
|
||||||
|
|
||||||
|
# Show all receipts
|
||||||
|
print("\nAll Receipts:")
|
||||||
|
for receipt in list_receipts():
|
||||||
|
print(f" ID: {receipt[0]}, Store: {receipt[1]}, Date: {receipt[2]}, Total: ${receipt[3]:.2f}")
|
||||||
|
|
||||||
|
# Show prices for a specific product
|
||||||
|
print("\nMilk Prices Over Time:")
|
||||||
|
for price_info in get_product_prices("Milk"):
|
||||||
|
print(f" Date: {price_info[0]}, Store: {price_info[1]}, Qty: {price_info[2]}, Price: ${price_info[3]:.2f}")
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# No external dependencies required for this SQLite-based implementation
|
||||||
|
# Python standard library is sufficient for the core functionality
|
||||||
|
|||||||
Reference in New Issue
Block a user