Initial commit: Tablet lending system with user-tablet many-to-many relationship
- Database schema: tablets, users, loans (junction table) - CLI app: minimal_app.py - Web apps: app.py (Flask), simple_app.py (http.server) - Features: loan management, search, user loans view, project notes - Git structure: CONTRIBUTING.md, .gitignore Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
commit
8a8d2f02fa
25 changed files with 2885 additions and 0 deletions
296
minimal_app.py
Normal file
296
minimal_app.py
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Minimal Tablet Lending and Return Management System
|
||||
Using only built-in Python modules
|
||||
"""
|
||||
|
||||
import sqlite3
|
||||
from datetime import datetime
|
||||
|
||||
def init_db():
|
||||
"""Initialize database with required tables"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Create tables
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS tablets (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
brand TEXT NOT NULL,
|
||||
model TEXT NOT NULL,
|
||||
serial_number TEXT UNIQUE NOT NULL,
|
||||
status TEXT DEFAULT 'available'
|
||||
)
|
||||
''')
|
||||
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
identification TEXT UNIQUE
|
||||
)
|
||||
''')
|
||||
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS loans (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
tablet_id INTEGER NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
loan_date TEXT NOT NULL,
|
||||
return_date TEXT,
|
||||
status TEXT DEFAULT 'active',
|
||||
FOREIGN KEY (tablet_id) REFERENCES tablets (id),
|
||||
FOREIGN KEY (user_id) REFERENCES users (id)
|
||||
)
|
||||
''')
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
def add_tablet(brand, model, serial_number):
|
||||
"""Add a new tablet to inventory"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
try:
|
||||
cursor.execute('''
|
||||
INSERT INTO tablets (brand, model, serial_number, status)
|
||||
VALUES (?, ?, ?, 'available')
|
||||
''', (brand, model, serial_number))
|
||||
conn.commit()
|
||||
print(f"✓ Added tablet: {brand} {model} ({serial_number})")
|
||||
except sqlite3.IntegrityError:
|
||||
print(f"✗ Error: Serial number {serial_number} already exists")
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
def add_user(name, identification):
|
||||
"""Add a new user"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
try:
|
||||
cursor.execute('''
|
||||
INSERT INTO users (name, identification)
|
||||
VALUES (?, ?)
|
||||
''', (name, identification))
|
||||
conn.commit()
|
||||
print(f"✓ Added user: {name} ({identification})")
|
||||
except sqlite3.IntegrityError:
|
||||
print(f"✗ Error: Identification {identification} already exists")
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
def loan_tablet(tablet_id, user_id):
|
||||
"""Loan a tablet to a user"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Check if tablet is available
|
||||
cursor.execute("SELECT status FROM tablets WHERE id = ?", (tablet_id,))
|
||||
result = cursor.fetchone()
|
||||
|
||||
if result and result[0] == 'available':
|
||||
# Update tablet status
|
||||
cursor.execute("UPDATE tablets SET status = 'loaned' WHERE id = ?", (tablet_id,))
|
||||
|
||||
# Create loan record
|
||||
loan_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
cursor.execute('''
|
||||
INSERT INTO loans (tablet_id, user_id, loan_date, status)
|
||||
VALUES (?, ?, ?, 'active')
|
||||
''', (tablet_id, user_id, loan_date))
|
||||
|
||||
conn.commit()
|
||||
print(f"✓ Tablet {tablet_id} loaned to user {user_id}")
|
||||
else:
|
||||
print(f"✗ Error: Tablet {tablet_id} is not available for loan")
|
||||
|
||||
conn.close()
|
||||
|
||||
def return_tablet(loan_id):
|
||||
"""Return a loaned tablet"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Get loan information
|
||||
cursor.execute("SELECT tablet_id FROM loans WHERE id = ? AND status = 'active'", (loan_id,))
|
||||
loan = cursor.fetchone()
|
||||
|
||||
if loan:
|
||||
tablet_id = loan[0]
|
||||
|
||||
# Update loan status and return date
|
||||
return_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
cursor.execute('''
|
||||
UPDATE loans SET status = 'returned', return_date = ? WHERE id = ?
|
||||
''', (return_date, loan_id))
|
||||
|
||||
# Update tablet status
|
||||
cursor.execute("UPDATE tablets SET status = 'available' WHERE id = ?", (tablet_id,))
|
||||
|
||||
conn.commit()
|
||||
print(f"✓ Tablet returned for loan {loan_id}")
|
||||
else:
|
||||
print(f"✗ Error: Loan {loan_id} not found or already returned")
|
||||
|
||||
conn.close()
|
||||
|
||||
def show_available_tablets():
|
||||
"""Show available tablets"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("SELECT id, brand, model, serial_number FROM tablets WHERE status = 'available'")
|
||||
tablets = cursor.fetchall()
|
||||
|
||||
print("\n=== Available Tablets ===")
|
||||
if tablets:
|
||||
for tablet in tablets:
|
||||
print(f"ID: {tablet[0]}, {tablet[1]} {tablet[2]} ({tablet[3]})")
|
||||
else:
|
||||
print("No available tablets")
|
||||
|
||||
conn.close()
|
||||
|
||||
def show_active_loans():
|
||||
"""Show active loans"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('''
|
||||
SELECT l.id, t.brand, t.model, t.serial_number, u.name, l.loan_date
|
||||
FROM loans l
|
||||
JOIN tablets t ON l.tablet_id = t.id
|
||||
JOIN users u ON l.user_id = u.id
|
||||
WHERE l.status = 'active'
|
||||
''')
|
||||
loans = cursor.fetchall()
|
||||
|
||||
print("\n=== Active Loans ===")
|
||||
if loans:
|
||||
for loan in loans:
|
||||
print(f"Loan ID: {loan[0]}, Tablet: {loan[1]} {loan[2]} ({loan[3]}), Borrower: {loan[4]}, Loan Date: {loan[5]}")
|
||||
else:
|
||||
print("No active loans")
|
||||
|
||||
conn.close()
|
||||
|
||||
def show_loan_history():
|
||||
"""Show complete loan history"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('''
|
||||
SELECT l.id, t.brand, t.model, t.serial_number, u.name,
|
||||
l.loan_date, l.return_date, l.status
|
||||
FROM loans l
|
||||
JOIN tablets t ON l.tablet_id = t.id
|
||||
JOIN users u ON l.user_id = u.id
|
||||
ORDER BY l.loan_date DESC
|
||||
''')
|
||||
loans = cursor.fetchall()
|
||||
|
||||
print("\n=== Loan History ===")
|
||||
if loans:
|
||||
for loan in loans:
|
||||
return_date = loan[6] or 'Not returned'
|
||||
print(f"Loan ID: {loan[0]}, Tablet: {loan[1]} {loan[2]} ({loan[3]}), Borrower: {loan[4]}")
|
||||
print(f" Loan Date: {loan[5]}, Return Date: {return_date}, Status: {loan[7]}")
|
||||
else:
|
||||
print("No loan history")
|
||||
|
||||
conn.close()
|
||||
|
||||
def main():
|
||||
"""Main menu"""
|
||||
init_db()
|
||||
|
||||
print("=== Tablet Lending and Return Management System ===")
|
||||
print("Using SQLite database: tablets.db")
|
||||
|
||||
while True:
|
||||
print("\nMenu:")
|
||||
print("1. Add Tablet")
|
||||
print("2. Add User")
|
||||
print("3. Loan Tablet")
|
||||
print("4. Return Tablet")
|
||||
print("5. Show Available Tablets")
|
||||
print("6. Show Active Loans")
|
||||
print("7. Show Loan History")
|
||||
print("8. Exit")
|
||||
|
||||
choice = input("Enter your choice (1-8): ")
|
||||
|
||||
if choice == '1':
|
||||
print("\n=== Add Tablet ===")
|
||||
brand = input("Brand: ")
|
||||
model = input("Model: ")
|
||||
serial_number = input("Serial Number: ")
|
||||
add_tablet(brand, model, serial_number)
|
||||
|
||||
elif choice == '2':
|
||||
print("\n=== Add User ===")
|
||||
name = input("Name: ")
|
||||
identification = input("Identification: ")
|
||||
add_user(name, identification)
|
||||
|
||||
elif choice == '3':
|
||||
print("\n=== Loan Tablet ===")
|
||||
show_available_tablets()
|
||||
show_users()
|
||||
|
||||
tablet_id = input("Enter Tablet ID to loan: ")
|
||||
user_id = input("Enter User ID: ")
|
||||
|
||||
try:
|
||||
loan_tablet(int(tablet_id), int(user_id))
|
||||
except ValueError:
|
||||
print("✗ Error: Invalid ID format")
|
||||
|
||||
elif choice == '4':
|
||||
print("\n=== Return Tablet ===")
|
||||
show_active_loans()
|
||||
|
||||
loan_id = input("Enter Loan ID to return: ")
|
||||
|
||||
try:
|
||||
return_tablet(int(loan_id))
|
||||
except ValueError:
|
||||
print("✗ Error: Invalid Loan ID format")
|
||||
|
||||
elif choice == '5':
|
||||
show_available_tablets()
|
||||
|
||||
elif choice == '6':
|
||||
show_active_loans()
|
||||
|
||||
elif choice == '7':
|
||||
show_loan_history()
|
||||
|
||||
elif choice == '8':
|
||||
print("Goodbye!")
|
||||
break
|
||||
|
||||
else:
|
||||
print("✗ Invalid choice. Please try again.")
|
||||
|
||||
def show_users():
|
||||
"""Show available users"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("SELECT id, name, identification FROM users")
|
||||
users = cursor.fetchall()
|
||||
|
||||
print("\n=== Available Users ===")
|
||||
if users:
|
||||
for user in users:
|
||||
print(f"ID: {user[0]}, {user[1]} ({user[2]})")
|
||||
else:
|
||||
print("No users available")
|
||||
|
||||
conn.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue