#!/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) ) ''') # Create non_loanable_devices table cursor.execute(''' CREATE TABLE IF NOT EXISTS non_loanable_devices ( id INTEGER PRIMARY KEY AUTOINCREMENT, brand TEXT NOT NULL, model TEXT NOT NULL, serial_number TEXT UNIQUE NOT NULL, device_type TEXT NOT NULL, location TEXT, status TEXT DEFAULT 'available', notes TEXT, purchase_date TEXT, purchase_cost REAL ) ''') 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 add_non_loanable_device(brand, model, serial_number, device_type, location='', notes='', purchase_date='', purchase_cost=None): """Add a new non-loanable device to inventory""" conn = sqlite3.connect('tablets.db') cursor = conn.cursor() try: cursor.execute(''' INSERT INTO non_loanable_devices (brand, model, serial_number, device_type, location, status, notes, purchase_date, purchase_cost) VALUES (?, ?, ?, ?, ?, 'available', ?, ?, ?) ''', (brand, model, serial_number, device_type, location, notes, purchase_date, purchase_cost)) conn.commit() print(f"✓ Added non-loanable device: {brand} {model} ({serial_number}) - Type: {device_type}") except sqlite3.IntegrityError: print(f"✗ Error: Serial number {serial_number} already exists") finally: conn.close() def show_non_loanable_devices(): """Show all non-loanable devices""" conn = sqlite3.connect('tablets.db') cursor = conn.cursor() cursor.execute("SELECT id, brand, model, serial_number, device_type, location, status FROM non_loanable_devices") devices = cursor.fetchall() print("\n=== Non-Loanable Devices ===") if devices: for device in devices: print(f"ID: {device[0]}, Type: {device[4]}, {device[1]} {device[2]} ({device[3]}), Location: {device[5] or 'N/A'}, Status: {device[6]}") else: print("No non-loanable devices") conn.close() def delete_non_loanable_device(device_id): """Delete a non-loanable device""" conn = sqlite3.connect('tablets.db') cursor = conn.cursor() cursor.execute("DELETE FROM non_loanable_devices WHERE id = ?", (device_id,)) conn.commit() if cursor.rowcount > 0: print(f"✓ Non-loanable device {device_id} deleted") else: print(f"✗ Error: Device {device_id} not found") 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. Add Non-Loanable Device") print("9. Show Non-Loanable Devices") print("10. Delete Non-Loanable Device") print("11. Exit") choice = input("Enter your choice (1-11): ") 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("\n=== Add Non-Loanable Device ===") brand = input("Brand: ") model = input("Model: ") serial_number = input("Serial Number: ") device_type = input("Device Type (e.g., projector, monitor): ") location = input("Location (optional): ") notes = input("Notes (optional): ") add_non_loanable_device(brand, model, serial_number, device_type, location, notes) elif choice == '9': show_non_loanable_devices() elif choice == '10': print("\n=== Delete Non-Loanable Device ===") show_non_loanable_devices() device_id = input("Enter Device ID to delete: ") try: delete_non_loanable_device(int(device_id)) except ValueError: print("✗ Error: Invalid ID format") elif choice == '11': 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()