我想做一个新的类目,我先把代码扔出来,让大家使用,并且自己去分析,然后下一期的时候给大家详细的去讲解,

先说一下功能:

开发一个零售环境智能收银系统(POS),核心功能包括
1.识别客户会员等级并自动计算折扣
2.处理多商品购买交易
3.实现收据打印和金额四舍五入逻辑
4.支持连续处理多个客户交易

成员和非成员支持
ii.通过客户ID检索客户详细信息
iii.客户列表(至少10个客户,包含相关详细信息)
iv.物品列表(至少10种产品,包括价格和描述)
v.至少5个不同的购买案例

import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import datetime
import math
import time
import json
import os
from tkinter.scrolledtext import ScrolledText

# Data file paths
DATA_FOLDER = "pos_data"
CUSTOMERS_FILE = os.path.join(DATA_FOLDER, "customers.json")
TRANSACTIONS_FILE = os.path.join(DATA_FOLDER, "transactions.json")


class Customer:
    def __init__(self, customer_id, name, member_type):
        self.customer_id = customer_id
        self.name = name
        self.member_type = member_type

    def get_discount_rate(self):
        """Return discount rate based on member type"""
        discount_rates = {
            "Platinum": 0.010,  # 1.0%
            "Gold": 0.006,  # 0.6%
            "Silver": 0.003,  # 0.3%
            "Bronze": 0.001  # 0.1%
        }
        return discount_rates.get(self.member_type, 0)

    def to_dict(self):
        """Convert customer object to dictionary for JSON serialization"""
        return {
            "customer_id": self.customer_id,
            "name": self.name,
            "member_type": self.member_type
        }

    @classmethod
    def from_dict(cls, data):
        """Create customer object from dictionary"""
        return cls(data["customer_id"], data["name"], data["member_type"])


class Item:
    def __init__(self, name, quantity, price):
        self.name = name
        self.quantity = quantity
        self.price = price

    def get_subtotal(self):
        return self.quantity * self.price

    def to_dict(self):
        """Convert item object to dictionary for JSON serialization"""
        return {
            "name": self.name,
            "quantity": self.quantity,
            "price": self.price
        }

    @classmethod
    def from_dict(cls, data):
        """Create item object from dictionary"""
        return cls(data["name"], data["quantity"], data["price"])


class Transaction:
    def __init__(self, customer):
        self.customer = customer
        self.items = []
        self.transaction_date = datetime.datetime.now()
        self.transaction_id = f"TXN-{int(time.time())}"

    def add_item(self, item):
        self.items.append(item)

    def get_subtotal(self):
        return sum(item.get_subtotal() for item in self.items)

    def get_discount_amount(self):
        subtotal = self.get_subtotal()
        discount_rate = self.customer.get_discount_rate()
        return subtotal * discount_rate

    def get_total(self):
        return self.get_subtotal() - self.get_discount_amount()

    def get_rounded_total(self):
        """Round the total to the nearest 5 cents"""
        total = self.get_total()
        # Multiply by 20 to convert to 5-cent units, round, then divide by 20
        return round(total * 20) / 20

    def to_dict(self):
        """Convert transaction object to dictionary for JSON serialization"""
        return {
            "transaction_id": self.transaction_id,
            "transaction_date": self.transaction_date.strftime("%Y-%m-%d %H:%M:%S"),
            "customer": self.customer.to_dict(),
            "items": [item.to_dict() for item in self.items],
            "subtotal": self.get_subtotal(),
            "discount": self.get_discount_amount(),
            "total": self.get_rounded_total()
        }

    @classmethod
    def from_dict(cls, data):
        """Create transaction object from dictionary"""
        customer = Customer.from_dict(data["customer"])
        transaction = cls(customer)
        transaction.transaction_id = data["transaction_id"]
        transaction.transaction_date = datetime.datetime.strptime(
            data["transaction_date"], "%Y-%m-%d %H:%M:%S")

        for item_data in data["items"]:
            transaction.add_item(Item.from_dict(item_data))

        return transaction

    def generate_receipt(self):
        # Format receipt as a string
        receipt = "\n" + "=" * 50 + "\n"
        receipt += f"{'RETAIL POS SYSTEM':^50}\n"
        receipt += "=" * 50 + "\n"
        receipt += f"Transaction ID: {self.transaction_id}\n"
        receipt += f"Date: {self.transaction_date.strftime('%Y-%m-%d %H:%M:%S')}\n"
        receipt += "-" * 50 + "\n"

        # Add customer info
        receipt += f"Customer ID: {self.customer.customer_id}\n"
        receipt += f"Name: {self.customer.name}\n"
        receipt += f"Membership: {self.customer.member_type}\n"
        receipt += "-" * 50 + "\n"

        # Add item details
        receipt += f"{'Item Name':<20}{'Qty':>8}{'Price':>10}{'Subtotal':>12}\n"
        receipt += "-" * 50 + "\n"
        for item in self.items:
            receipt += f"{item.name:<20}{item.quantity:>8}{item.price:>10.2f}{item.get_subtotal():>12.2f}\n"

        # Add summary
        receipt += "-" * 50 + "\n"
        receipt += f"Subtotal:{self.get_subtotal():>40.2f}\n"
        receipt += f"Discount ({self.customer.get_discount_rate() * 100:.1f}%):{self.get_discount_amount():>30.2f}\n"
        receipt += f"Total:{self.get_rounded_total():>43.2f}\n"
        receipt += "=" * 50 + "\n"
        receipt += f"{'Thank you for your purchase!':^50}\n"
        receipt += "=" * 50 + "\n"

        return receipt


class DataManager:
    @staticmethod
    def initialize_data_storage():
        """Create data directory and files if they don't exist"""
        # Create data directory
        if not os.path.exists(DATA_FOLDER):
            os.makedirs(DATA_FOLDER)

        # Create customers file if it doesn't exist
        if not os.path.exists(CUSTOMERS_FILE):
            with open(CUSTOMERS_FILE, 'w', encoding='utf-8') as f:
                json.dump([], f)

        # Create transactions file if it doesn't exist
        if not os.path.exists(TRANSACTIONS_FILE):
            with open(TRANSACTIONS_FILE, 'w', encoding='utf-8') as f:
                json.dump([], f)

    @staticmethod
    def save_customer(customer):
        """Save or update customer in customers.json"""
        customers = DataManager.load_customers()

        # Check if customer already exists
        for i, c in enumerate(customers):
            if c["customer_id"] == customer.customer_id:
                # Update existing customer
                customers[i] = customer.to_dict()
                break
        else:
            # Add new customer
            customers.append(customer.to_dict())

        # Save to file
        with open(CUSTOMERS_FILE, 'w', encoding='utf-8') as f:
            json.dump(customers, f, ensure_ascii=False, indent=2)

    @staticmethod
    def save_transaction(transaction):
        """Save transaction to transactions.json"""
        transactions = DataManager.load_transactions_dict()

        # Add new transaction
        transactions.append(transaction.to_dict())

        # Save to file
        with open(TRANSACTIONS_FILE, 'w', encoding='utf-8') as f:
            json.dump(transactions, f, ensure_ascii=False, indent=2)

    @staticmethod
    def load_customers():
        """Load all customers from customers.json"""
        try:
            with open(CUSTOMERS_FILE, 'r', encoding='utf-8') as f:
                return json.load(f)
        except (json.JSONDecodeError, FileNotFoundError):
            return []

    @staticmethod
    def load_customer_objects():
        """Load all customers as Customer objects"""
        customers_data = DataManager.load_customers()
        return [Customer.from_dict(c) for c in customers_data]

    @staticmethod
    def find_customer_by_id(customer_id):
        """Find a customer by ID"""
        customers = DataManager.load_customers()
        for c in customers:
            if c["customer_id"] == customer_id:
                return Customer.from_dict(c)
        return None

    @staticmethod
    def load_transactions_dict():
        """Load all transactions as dictionaries"""
        try:
            with open(TRANSACTIONS_FILE, 'r', encoding='utf-8') as f:
                return json.load(f)
        except (json.JSONDecodeError, FileNotFoundError):
            return []

    @staticmethod
    def load_transaction_objects():
        """Load all transactions as Transaction objects"""
        transactions_data = DataManager.load_transactions_dict()
        return [Transaction.from_dict(t) for t in transactions_data]

    @staticmethod
    def find_transactions_by_customer_id(customer_id):
        """Find all transactions for a customer"""
        transactions = DataManager.load_transactions_dict()
        return [t for t in transactions if t["customer"]["customer_id"] == customer_id]

    @staticmethod
    def find_transaction_by_id(transaction_id):
        """Find a transaction by ID"""
        transactions = DataManager.load_transactions_dict()
        for t in transactions:
            if t["transaction_id"] == transaction_id:
                return Transaction.from_dict(t)
        return None


class POSApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Retail POS System")
        self.geometry("800x600")
        self.resizable(True, True)
        self.current_transaction = None

        # Initialize data storage
        DataManager.initialize_data_storage()

        # Configure style
        self.style = ttk.Style()
        self.style.configure("TButton", padding=6, relief="flat")
        self.style.configure("TLabel")
        self.style.configure("TEntry")

        # Create main menu
        self.create_main_menu()

    def create_main_menu(self):
        # Clear window
        for widget in self.winfo_children():
            widget.destroy()

        # Main frame
        main_frame = ttk.Frame(self, padding="20")
        main_frame.pack(expand=True, fill="both")

        # Title
        title_label = ttk.Label(main_frame, text="Retail POS System", font=('Arial', 18, 'bold'))
        title_label.pack(pady=20)

        # Buttons
        new_transaction_btn = ttk.Button(main_frame, text="New Transaction", command=self.start_new_transaction,
                                         width=30)
        new_transaction_btn.pack(pady=10)

        history_btn = ttk.Button(main_frame, text="Transaction History", command=self.show_transaction_history,
                                 width=30)
        history_btn.pack(pady=10)

        customer_btn = ttk.Button(main_frame, text="Customer Management", command=self.show_customer_management,
                                  width=30)
        customer_btn.pack(pady=10)

        exit_btn = ttk.Button(main_frame, text="Exit System", command=self.quit, width=30)
        exit_btn.pack(pady=10)

    def start_new_transaction(self):
        # Clear window
        for widget in self.winfo_children():
            widget.destroy()

        # Create customer info frame
        self.create_customer_info_frame()

    def create_customer_info_frame(self):
        customer_frame = ttk.Frame(self, padding="20")
        customer_frame.pack(expand=True, fill="both")

        # Title
        title_label = ttk.Label(customer_frame, text="Customer Information", font=('Arial', 14, 'bold'))
        title_label.pack(pady=10)

        # Customer ID with search
        id_frame = ttk.Frame(customer_frame)
        id_frame.pack(fill="x", pady=5)
        id_label = ttk.Label(id_frame, text="Customer ID:", width=15)
        id_label.pack(side="left")
        self.id_entry = ttk.Entry(id_frame, width=20)
        self.id_entry.pack(side="left", padx=5)
        search_btn = ttk.Button(id_frame, text="Find", command=self.search_customer)
        search_btn.pack(side="left", padx=5)

        # Customer Name
        name_frame = ttk.Frame(customer_frame)
        name_frame.pack(fill="x", pady=5)
        name_label = ttk.Label(name_frame, text="Customer Name:", width=15)
        name_label.pack(side="left")
        self.name_entry = ttk.Entry(name_frame, width=30)
        self.name_entry.pack(side="left", padx=5)

        # Membership Type
        member_frame = ttk.Frame(customer_frame)
        member_frame.pack(fill="x", pady=5)
        member_label = ttk.Label(member_frame, text="Membership:", width=15)
        member_label.pack(side="left")
        self.member_var = tk.StringVar()
        member_types = ["Platinum", "Gold", "Silver", "Bronze"]
        self.member_combo = ttk.Combobox(member_frame, textvariable=self.member_var, values=member_types, width=28,
                                         state="readonly")
        self.member_combo.pack(side="left", padx=5)

        # Buttons
        btn_frame = ttk.Frame(customer_frame)
        btn_frame.pack(pady=20)

        next_btn = ttk.Button(btn_frame, text="Next", command=self.process_customer_info)
        next_btn.pack(side="left", padx=10)

        cancel_btn = ttk.Button(btn_frame, text="Cancel", command=self.create_main_menu)
        cancel_btn.pack(side="left", padx=10)

    def search_customer(self):
        customer_id = self.id_entry.get().strip()
        if not customer_id:
            messagebox.showwarning("Warning", "Please enter a Customer ID")
            return

        customer = DataManager.find_customer_by_id(customer_id)
        if customer:
            # Populate fields with customer data
            self.name_entry.delete(0, "end")
            self.name_entry.insert(0, customer.name)
            self.member_var.set(customer.member_type)
            messagebox.showinfo("Info", f"Customer found: {customer.name}")
        else:
            messagebox.showinfo("Info", "Customer not found. Please enter new customer information.")

    def process_customer_info(self):
        customer_id = self.id_entry.get().strip()
        customer_name = self.name_entry.get().strip()
        member_type = self.member_var.get()

        if not customer_id:
            messagebox.showwarning("Warning", "Please enter a Customer ID")
            return

        if not customer_name:
            messagebox.showwarning("Warning", "Please enter a Customer Name")
            return

        if not member_type:
            messagebox.showwarning("Warning", "Please select a Membership Type")
            return

        # Create customer and transaction
        customer = Customer(customer_id, customer_name, member_type)
        self.current_transaction = Transaction(customer)

        # Save/update customer in database
        DataManager.save_customer(customer)

        # Move to item entry
        self.create_item_entry_frame()

    def create_item_entry_frame(self):
        # Clear window
        for widget in self.winfo_children():
            widget.destroy()

        main_frame = ttk.Frame(self, padding="20")
        main_frame.pack(expand=True, fill="both")

        # Title
        title_label = ttk.Label(main_frame, text="Add Items", font=('Arial', 14, 'bold'))
        title_label.pack(pady=10)

        # Item list frame
        list_frame = ttk.Frame(main_frame)
        list_frame.pack(fill="both", expand=True, pady=10)

        # Create Treeview for items
        columns = ("Item Name", "Quantity", "Price", "Subtotal")
        self.item_tree = ttk.Treeview(list_frame, columns=columns, show="headings", height=10)

        # Configure column headings
        for col in columns:
            self.item_tree.heading(col, text=col)
            self.item_tree.column(col, width=100)

        self.item_tree.pack(side="left", fill="both", expand=True)

        # Scrollbar for treeview
        scrollbar = ttk.Scrollbar(list_frame, orient="vertical", command=self.item_tree.yview)
        scrollbar.pack(side="right", fill="y")
        self.item_tree.configure(yscrollcommand=scrollbar.set)

        # Item input frame
        input_frame = ttk.Frame(main_frame)
        input_frame.pack(fill="x", pady=10)

        # Item Name
        name_frame = ttk.Frame(input_frame)
        name_frame.pack(fill="x", pady=5)
        name_label = ttk.Label(name_frame, text="Item Name:", width=15)
        name_label.pack(side="left")
        self.item_name_entry = ttk.Entry(name_frame, width=30)
        self.item_name_entry.pack(side="left", padx=5)

        # Item Quantity
        qty_frame = ttk.Frame(input_frame)
        qty_frame.pack(fill="x", pady=5)
        qty_label = ttk.Label(qty_frame, text="Quantity:", width=15)
        qty_label.pack(side="left")
        self.qty_entry = ttk.Entry(qty_frame, width=30)
        self.qty_entry.pack(side="left", padx=5)

        # Item Price
        price_frame = ttk.Frame(input_frame)
        price_frame.pack(fill="x", pady=5)
        price_label = ttk.Label(price_frame, text="Price:", width=15)
        price_label.pack(side="left")
        self.price_entry = ttk.Entry(price_frame, width=30)
        self.price_entry.pack(side="left", padx=5)

        # Buttons
        btn_frame = ttk.Frame(main_frame)
        btn_frame.pack(pady=10)

        add_btn = ttk.Button(btn_frame, text="Add Item", command=self.add_item)
        add_btn.pack(side="left", padx=10)

        remove_btn = ttk.Button(btn_frame, text="Remove Selected", command=self.remove_selected_item)
        remove_btn.pack(side="left", padx=10)

        complete_btn = ttk.Button(btn_frame, text="Complete", command=self.complete_transaction)
        complete_btn.pack(side="left", padx=10)

        cancel_btn = ttk.Button(btn_frame, text="Cancel", command=self.create_main_menu)
        cancel_btn.pack(side="left", padx=10)

    def add_item(self):
        name = self.item_name_entry.get().strip()
        qty_str = self.qty_entry.get().strip()
        price_str = self.price_entry.get().strip()

        if not name:
            messagebox.showwarning("Warning", "Please enter an Item Name")
            return

        try:
            qty = int(qty_str)
            if qty <= 0:
                raise ValueError()
        except ValueError:
            messagebox.showwarning("Warning", "Please enter a valid quantity (must be a positive integer)")
            return

        try:
            price = float(price_str)
            if price <= 0:
                raise ValueError()
        except ValueError:
            messagebox.showwarning("Warning", "Please enter a valid price (must be a positive number)")
            return

        # Create item and add to transaction
        item = Item(name, qty, price)
        self.current_transaction.add_item(item)

        # Add to treeview
        subtotal = item.get_subtotal()
        self.item_tree.insert("", "end", values=(name, qty, f"{price:.2f}", f"{subtotal:.2f}"))

        # Clear entries
        self.item_name_entry.delete(0, "end")
        self.qty_entry.delete(0, "end")
        self.price_entry.delete(0, "end")
        self.item_name_entry.focus()

    def remove_selected_item(self):
        selected_item = self.item_tree.selection()
        if not selected_item:
            messagebox.showwarning("Warning", "Please select an item first")
            return

        # Get item index
        item_id = selected_item[0]
        index = self.item_tree.index(item_id)

        # Remove from transaction
        if 0 <= index < len(self.current_transaction.items):
            self.current_transaction.items.pop(index)
            self.item_tree.delete(item_id)

    def complete_transaction(self):
        if not self.current_transaction.items:
            messagebox.showwarning("Warning", "Please add at least one item")
            return

        # Save transaction to database
        DataManager.save_transaction(self.current_transaction)

        self.show_receipt()

    def show_receipt(self):
        # Clear window
        for widget in self.winfo_children():
            widget.destroy()

        receipt_frame = ttk.Frame(self, padding="20")
        receipt_frame.pack(expand=True, fill="both")

        # Title
        title_label = ttk.Label(receipt_frame, text="Receipt", font=('Arial', 14, 'bold'))
        title_label.pack(pady=10)

        # Receipt text area
        receipt_text = ScrolledText(receipt_frame, width=60, height=20)
        receipt_text.pack(fill="both", expand=True, pady=10)

        # Insert receipt content
        receipt_content = self.current_transaction.generate_receipt()
        receipt_text.insert("1.0", receipt_content)
        receipt_text.config(state="disabled")  # Make read-only

        # Buttons
        btn_frame = ttk.Frame(receipt_frame)
        btn_frame.pack(pady=10)

        new_btn = ttk.Button(btn_frame, text="New Transaction", command=self.start_new_transaction)
        new_btn.pack(side="left", padx=10)

        main_btn = ttk.Button(btn_frame, text="Back to Main Menu", command=self.create_main_menu)
        main_btn.pack(side="left", padx=10)

    def show_transaction_history(self):
        # Clear window
        for widget in self.winfo_children():
            widget.destroy()

        history_frame = ttk.Frame(self, padding="20")
        history_frame.pack(expand=True, fill="both")

        # Title
        title_label = ttk.Label(history_frame, text="Transaction History", font=('Arial', 14, 'bold'))
        title_label.pack(pady=10)

        # Search options
        search_frame = ttk.Frame(history_frame)
        search_frame.pack(fill="x", pady=10)

        # Customer ID search
        id_label = ttk.Label(search_frame, text="Customer ID:", width=10)
        id_label.pack(side="left", padx=5)
        self.history_id_entry = ttk.Entry(search_frame, width=15)
        self.history_id_entry.pack(side="left", padx=5)

        # Transaction ID search
        txn_label = ttk.Label(search_frame, text="Transaction ID:", width=10)
        txn_label.pack(side="left", padx=5)
        self.txn_id_entry = ttk.Entry(search_frame, width=15)
        self.txn_id_entry.pack(side="left", padx=5)

        # Search button
        search_btn = ttk.Button(search_frame, text="Search",
                                command=self.search_transactions)
        search_btn.pack(side="left", padx=10)

        # Transaction list
        list_frame = ttk.Frame(history_frame)
        list_frame.pack(fill="both", expand=True, pady=10)

        # Create Treeview for transactions
        columns = ("Transaction ID", "Date", "Customer ID", "Customer Name", "Amount")
        self.txn_tree = ttk.Treeview(list_frame, columns=columns, show="headings", height=10)

        # Configure column headings
        for col in columns:
            self.txn_tree.heading(col, text=col)
            self.txn_tree.column(col, width=100)

        self.txn_tree.pack(side="left", fill="both", expand=True)

        # Scrollbar for treeview
        scrollbar = ttk.Scrollbar(list_frame, orient="vertical", command=self.txn_tree.yview)
        scrollbar.pack(side="right", fill="y")
        self.txn_tree.configure(yscrollcommand=scrollbar.set)

        # Double-click to view details
        self.txn_tree.bind("<Double-1>", self.view_transaction_details)

        # Load all transactions initially
        self.load_all_transactions()

        # Buttons
        btn_frame = ttk.Frame(history_frame)
        btn_frame.pack(pady=10)

        view_btn = ttk.Button(btn_frame, text="View Details",
                              command=lambda: self.view_transaction_details(None))
        view_btn.pack(side="left", padx=10)

        main_btn = ttk.Button(btn_frame, text="Back to Main Menu", command=self.create_main_menu)
        main_btn.pack(side="left", padx=10)

    def load_all_transactions(self):
        """Load all transactions into the transaction tree"""
        # Clear existing items
        for item in self.txn_tree.get_children():
            self.txn_tree.delete(item)

        # Get all transactions
        transactions = DataManager.load_transactions_dict()

        # Add to tree
        for txn in transactions:
            self.txn_tree.insert("", "end", values=(
                txn["transaction_id"],
                txn["transaction_date"],
                txn["customer"]["customer_id"],
                txn["customer"]["name"],
                f"{txn['total']:.2f}"
            ))

    def search_transactions(self):
        """Search transactions by customer ID or transaction ID"""
        customer_id = self.history_id_entry.get().strip()
        transaction_id = self.txn_id_entry.get().strip()

        # Clear existing items
        for item in self.txn_tree.get_children():
            self.txn_tree.delete(item)

        # Get transactions
        if transaction_id:
            # Search by transaction ID
            txn = DataManager.find_transaction_by_id(transaction_id)
            if txn:
                self.txn_tree.insert("", "end", values=(
                    txn.transaction_id,
                    txn.transaction_date.strftime("%Y-%m-%d %H:%M:%S"),
                    txn.customer.customer_id,
                    txn.customer.name,
                    f"{txn.get_rounded_total():.2f}"
                ))
            else:
                messagebox.showinfo("Info", "No transaction found")
        elif customer_id:
            # Search by customer ID
            transactions = DataManager.find_transactions_by_customer_id(customer_id)
            if transactions:
                for txn in transactions:
                    self.txn_tree.insert("", "end", values=(
                        txn["transaction_id"],
                        txn["transaction_date"],
                        txn["customer"]["customer_id"],
                        txn["customer"]["name"],
                        f"{txn['total']:.2f}"
                    ))
            else:
                messagebox.showinfo("Info", "No transactions found for this customer")
        else:
            # Load all if no search criteria
            self.load_all_transactions()

    def view_transaction_details(self, event):
        """View details of selected transaction"""
        # Get selected item
        if event:  # Called from double-click
            item_id = self.txn_tree.identify_row(event.y)
            if not item_id:
                return
            self.txn_tree.selection_set(item_id)
        else:  # Called from button
            selected = self.txn_tree.selection()
            if not selected:
                messagebox.showwarning("Warning", "Please select a transaction first")
                return
            item_id = selected[0]

        # Get transaction ID
        txn_id = self.txn_tree.item(item_id, "values")[0]

        # Get transaction
        transaction = DataManager.find_transaction_by_id(txn_id)
        if not transaction:
            messagebox.showerror("Error", "Cannot find transaction record")
            return

        # Show receipt
        self.show_transaction_receipt(transaction)

    def show_transaction_receipt(self, transaction):
        """Show receipt for a transaction"""
        # Clear window
        for widget in self.winfo_children():
            widget.destroy()

        receipt_frame = ttk.Frame(self, padding="20")
        receipt_frame.pack(expand=True, fill="both")

        # Title
        title_label = ttk.Label(receipt_frame, text="Transaction Details", font=('Arial', 14, 'bold'))
        title_label.pack(pady=10)

        # Receipt text area
        receipt_text = ScrolledText(receipt_frame, width=60, height=20)
        receipt_text.pack(fill="both", expand=True, pady=10)

        # Insert receipt content
        receipt_content = transaction.generate_receipt()
        receipt_text.insert("1.0", receipt_content)
        receipt_text.config(state="disabled")  # Make read-only

        # Buttons
        btn_frame = ttk.Frame(receipt_frame)
        btn_frame.pack(pady=10)

        back_btn = ttk.Button(btn_frame, text="Back",
                              command=self.show_transaction_history)
        back_btn.pack(side="left", padx=10)

        main_btn = ttk.Button(btn_frame, text="Back to Main Menu", command=self.create_main_menu)
        main_btn.pack(side="left", padx=10)

    def show_customer_management(self):
        """Show customer management screen"""
        # Clear window
        for widget in self.winfo_children():
            widget.destroy()

        customer_frame = ttk.Frame(self, padding="20")
        customer_frame.pack(expand=True, fill="both")

        # Title
        title_label = ttk.Label(customer_frame, text="Customer Management", font=('Arial', 14, 'bold'))
        title_label.pack(pady=10)

        # Customer list
        list_frame = ttk.Frame(customer_frame)
        list_frame.pack(fill="both", expand=True, pady=10)

        # Create Treeview for customers
        columns = ("Customer ID", "Customer Name", "Membership")
        self.customer_tree = ttk.Treeview(list_frame, columns=columns, show="headings", height=10)

        # Configure column headings
        for col in columns:
            self.customer_tree.heading(col, text=col)
            self.customer_tree.column(col, width=100)

        self.customer_tree.pack(side="left", fill="both", expand=True)

        # Scrollbar for treeview
        scrollbar = ttk.Scrollbar(list_frame, orient="vertical", command=self.customer_tree.yview)
        scrollbar.pack(side="right", fill="y")
        self.customer_tree.configure(yscrollcommand=scrollbar.set)

        # Load customers
        self.load_customers()

        # Buttons
        btn_frame = ttk.Frame(customer_frame)
        btn_frame.pack(pady=10)

        view_txn_btn = ttk.Button(btn_frame, text="View Transactions",
                                  command=self.view_customer_transactions)
        view_txn_btn.pack(side="left", padx=10)

        main_btn = ttk.Button(btn_frame, text="Back to Main Menu", command=self.create_main_menu)
        main_btn.pack(side="left", padx=10)

    def load_customers(self):
        """Load all customers into the customer tree"""
        # Clear existing items
        for item in self.customer_tree.get_children():
            self.customer_tree.delete(item)

        # Get all customers
        customers = DataManager.load_customers()

        # Add to tree
        for cust in customers:
            self.customer_tree.insert("", "end", values=(
                cust["customer_id"],
                cust["name"],
                cust["member_type"]
            ))

    def view_customer_transactions(self):
        """View transactions for selected customer"""
        # Get selected item
        selected = self.customer_tree.selection()
        if not selected:
            messagebox.showwarning("Warning", "Please select a customer first")
            return
        item_id = selected[0]

        # Get customer ID
        customer_id = self.customer_tree.item(item_id, "values")[0]

        # Switch to transaction history with customer ID
        self.show_transaction_history()
        self.history_id_entry.insert(0, customer_id)
        self.search_transactions()


if __name__ == "__main__":
    app = POSApp()
    # Set app icon if available
    try:
        app.iconbitmap("pos_icon.ico")  # You would need to create this icon file
    except:
        pass  # Continue without icon if not available
    app.mainloop()
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐