| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
共有 85 人关注过本帖
标题:python代码制作的进销存软件
取消只看楼主 加入收藏
wyu8888
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2020-9-10
收藏
 问题点数:20 回复次数:4 
python代码制作的进销存软件
python制作的一款局域网的进销存软件,因为没有数据库也不太懂,直接用自带的库做的,应该是调用和存储问题,进入界面后出入库时显示未知,请高手帮助。
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册


搜索更多相关主题的帖子: 代码 进销存 python 软件 制作 
昨天 14:21
wyu8888
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2020-9-10
收藏
得分:0 
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import sqlite3
import time
from datetime import datetime, date
from tkinter.simpledialog import Dialog
import openpyxl
from openpyxl.styles import Font, Alignment, Border, Side
from openpyxl.utils import get_column_letter
import os
import sys

class DatePickerDialog(Dialog):
    """自定义日期选择对话框"""
    def __init__(self, parent, title=None, initial_date=None):
        self.selected_date = initial_date or date.today()
        super().__init__(parent, title=title or "选择日期")
   
    def body(self, master):
        # 年份选择
        ttk.Label(master, text="年:").grid(row=0, column=0, padx=5, pady=5)
        self.year_var = tk.IntVar(value=self.selected_date.year)
        years = list(range(2020, 2031))
        (master, textvariable=self.year_var, values=years, width=6).grid(row=0, column=1, padx=5, pady=5)
        
        # 月份选择
        ttk.Label(master, text="月:").grid(row=0, column=2, padx=5, pady=5)
        self.month_var = tk.IntVar(value=self.selected_date.month)
        months = list(range(1, 13))
        (master, textvariable=self.month_var, values=months, width=4).grid(row=0, column=3, padx=5, pady=5)
        
        # 日期选择
        ttk.Label(master, text="日:").grid(row=0, column=4, padx=5, pady=5)
        self.day_var = tk.IntVar(value=self.selected_date.day)
        days = list(range(1, 32))
        (master, textvariable=self.day_var, values=days, width=4).grid(row=0, column=5, padx=5, pady=5)
        
        return master
   
    def apply(self):
        try:
            year = self.year_var.get()
            month = self.month_var.get()
            day = self.day_var.get()
            self.selected_date = date(year, month, day)
        except ValueError:
            messagebox.showerror("错误", "无效的日期!")
            self.selected_date = date.today()

class LoginWindow:
    """登录界面"""
    def __init__(self, root, main_app):
        self.root = root
        self.main_app = main_app
        self.root.title("XXXXX进销存管理系统")
        self.root.geometry("600x400")
        self.root.configure(bg="#2c3e50")
        
        # 设置窗口居中
        self.center_window(600, 400)
        
        # 创建主框架
        self.main_frame = tk.Frame(self.root, bg="#2c3e50")
        self.main_frame.pack(fill="both", expand=True, padx=50, pady=50)
        
        # 系统标题
        title = tk.Label(
            self.main_frame,
            text="XXXXX进销存管理系统",
            font=("微软雅黑", 24, "bold"),
            fg="#ecf0f1",
            bg="#2c3e50"
        )
        title.pack(pady=(30, 50))
        
        # 登录信息
        login_frame = tk.Frame(self.main_frame, bg="#34495e", padx=20, pady=20, bd=0, relief="flat")
        login_frame.pack(fill="x")
        
        # 用户名
        tk.Label(
            login_frame,
            text="用户名:",
            font=("微软雅黑", 12),
            fg="#ecf0f1",
            bg="#34495e"
        ).grid(row=0, column=0, padx=5, pady=10, sticky="e")
        
        self.username = ttk.Entry(login_frame, width=20, font=("微软雅黑", 12))
        self.username.grid(row=0, column=1, padx=5, pady=10)
        self.username.insert(0, "admin")  # 只提供用户名,不提供密码
        
        # 密码
        tk.Label(
            login_frame,
            text="密  码:",
            font=("微软雅黑", 12),
            fg="#ecf0f1",
            bg="#34495e"
        ).grid(row=1, column=0, padx=5, pady=10, sticky="e")
        
        self.password = ttk.Entry(login_frame, width=20, font=("微软雅黑", 12), show="*")
        self.password.grid(row=1, column=1, padx=5, pady=10)
        
        # 登录按钮
        login_btn = ttk.Button(
            login_frame,
            text="登 录",
            width=15,
            command=self.login,
            style="Accent.TButton"
        )
        login_btn.grid(row=2, column=0, columnspan=2, pady=20)
        
        # 状态信息
        self.status = tk.Label(
            self.main_frame,
            text="",
            font=("微软雅黑", 10),
            fg="#e74c3c",
            bg="#2c3e50"
        )
        self.status.pack(pady=10)
        
        # 版权信息
        copyright = tk.Label(
            self.main_frame,
            text="© 2025 XXXXX",
            font=("微软雅黑", 10),
            fg="#bdc3c7",
            bg="#2c3e50"
        )
        copyright.pack(side="bottom", pady=10)
        
        # 绑定回车键
        self.root.bind('<Return>', lambda event: self.login())
        
        # 设置样式
        self.set_style()
   
    def set_style(self):
        style = ttk.Style()
        style.configure("Accent.TButton",
                        foreground="white",
                        background="#3498db",
                        font=("微软雅黑", 11, "bold"),
                        borderwidth=0)
        style.map("Accent.TButton",
                  background=[('active', '#2980b9'), ('pressed', '#1f618d')])
   
    def center_window(self, width, height):
        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()
        
        x = (screen_width - width) // 2
        y = (screen_height - height) // 2
        
        self.root.geometry(f"{width}x{height}+{x}+{y}")
   
    def login(self):
        username = self.username.get()
        password = self.password.get()
        
        if username == "admin" and password == "******":
            self.status.config(text="登录成功,正在进入系统...", fg="#2ecc71")
            self.root.update()
            time.sleep(1)
            self.root.destroy()
            self.main_app.show_main_window()
        else:
            self.status.config(text="用户名或密码错误!", fg="#e74c3c")

class PrintPreviewWindow:
    """打印预览窗口"""
    def __init__(self, parent, data, headers, title):
        self.parent = parent
        self.data = data
        self.headers = headers
        self.title = title
        
        self.window = tk.Toplevel(parent)
        self.window.title("打印预览")
        self.window.geometry("900x600")
        self.window.configure(bg="#f5f5f5")
        
        # 设置窗口居中
        self.center_window(900, 600)
        
        # 标题
        title_frame = tk.Frame(self.window, bg="#3498db", height=60)
        title_frame.pack(fill="x")
        
        tk.Label(
            title_frame,
            text=self.title,
            font=("微软雅黑", 18, "bold"),
            fg="white",
            bg="#3498db"
        ).pack(pady=15)
        
        # 单位信息
        tk.Label(
            title_frame,
            text="XXXXX",
            font=("微软雅黑", 12),
            fg="white",
            bg="#3498db"
        ).pack(side="left", padx=20)
        
        # 日期
        date_label = tk.Label(
            title_frame,
            text=f"打印日期: {datetime.now().strftime('%Y-%m-%d')}",
            font=("微软雅黑", 10),
            fg="white",
            bg="#3498db"
        )
        date_label.pack(side="right", padx=20)
        
        # 表格框架
        table_frame = tk.Frame(self.window, bg="#f5f5f5", padx=20, pady=20)
        table_frame.pack(fill="both", expand=True, padx=10, pady=10)
        
        # 创建表格
        self.tree = ttk.Treeview(
            table_frame,
            columns=self.headers,
            show="headings",
            height=20
        )
        
        # 设置列
        for i, header in enumerate(self.headers):
            self.tree.column(f"#{i+1}", width=150, anchor="center")
            self.tree.heading(f"#{i+1}", text=header)
        
        # 添加滚动条
        scrollbar = ttk.Scrollbar(table_frame, orient="vertical", command=self.tree.yview)
        self.tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side="right", fill="y")
        self.tree.pack(fill="both", expand=True)
        
        # 添加数据
        for row in self.data:
            self.tree.insert("", "end", values=row)
        
        # 按钮区域
        btn_frame = tk.Frame(self.window, bg="#f5f5f5", pady=10)
        btn_frame.pack(fill="x")
        
        ttk.Button(
            btn_frame,
            text="打印",
            width=15,
            command=self.print_data,
            style="Accent.TButton"
        ).pack(side="left", padx=20)
        
        ttk.Button(
            btn_frame,
            text="导出",
            width=15,
            command=self.export_data,
            style="Accent.TButton"
        ).pack(side="left", padx=10)
        
        ttk.Button(
            btn_frame,
            text="关闭",
            width=15,
            command=self.window.destroy
        ).pack(side="right", padx=20)
   
    def center_window(self, width, height):
        screen_width = self.window.winfo_screenwidth()
        screen_height = self.window.winfo_screenheight()
        
        x = (screen_width - width) // 2
        y = (screen_height - height) // 2
        
        self.window.geometry(f"{width}x{height}+{x}+{y}")
   
    def print_data(self):
        messagebox.showinfo("打印", "数据已发送到打印机!")
   
    def export_data(self):
        filename = filedialog.asksaveasfilename(
            defaultextension=".xlsx",
            filetypes=[("Excel 文件", "*.xlsx"), ("所有文件", "*.*")],
            title="保存为Excel文件"
        )
        
        if not filename:
            return
        
        wb = openpyxl.Workbook()
        ws = wb.active
        ws.title = "数据导出"
        
        # 设置标题
        ws.merge_cells('A1:H1')
        title_cell = ws['A1']
        title_cell.value = self.title
        title_cell.font = Font(size=16, bold=True)
        title_cell.alignment = Alignment(horizontal='center', vertical='center')
        
        # 设置单位信息
        ws['A2'] = "单位:XXXXX"
        ws['H2'] = f"导出日期:{datetime.now().strftime('%Y-%m-%d')}"
        
        # 添加表头
        for col_idx, header in enumerate(self.headers, 1):
            cell = ws.cell(row=3, column=col_idx, value=header)
            cell.font = Font(bold=True)
            cell.alignment = Alignment(horizontal='center')
        
        # 添加数据
        for row_idx, row_data in enumerate(self.data, 4):
            for col_idx, cell_value in enumerate(row_data, 1):
                ws.cell(row=row_idx, column=col_idx, value=cell_value)
        
        # 设置列宽
        for col_idx in range(1, len(self.headers) + 1):
            col_letter = get_column_letter(col_idx)
            ws.column_dimensions[col_letter].width = 20
        
        # 添加边框
        thin_border = Border(
            left=Side(style='thin'),
            right=Side(style='thin'),
            top=Side(style='thin'),
            bottom=Side(style='thin')
        )
        
        for row in ws.iter_rows(min_row=3, max_row=len(self.data)+3, min_col=1, max_col=len(self.headers)):
            for cell in row:
                cell.border = thin_border
        
        try:
            wb.save(filename)
            messagebox.showinfo("导出成功", f"数据已成功导出到:\n{filename}")
        except Exception as e:
            messagebox.showerror("导出失败", f"导出过程中发生错误:\n{str(e)}")

class InventorySystem:
    def __init__(self):
        # 创建登录窗口
        self.login_root = tk.Tk()
        self.login_window = LoginWindow(self.login_root, self)
        
        # 初始化主窗口(但先不创建)
        self.main_root = None
        
        # 启动登录窗口事件循环
        self.login_root.mainloop()
   
    def show_main_window(self):
        """显示主窗口"""
        # 创建主窗口
        self.main_root = tk.Tk()
        self.main_root.title("XXXXX进销存管理系统")
        self.main_root.geometry("1200x700")
        self.main_root.configure(bg="#ecf0f1")
        
        # 设置窗口居中
        self.center_window(1200, 700)
        
        # 设置样式
        self.set_style()
        
        # 创建数据库连接
        self.conn = sqlite3.connect('inventory.db')
        self.cursor = self.conn.cursor()
        self.create_tables()
        
        # 创建主界面
        self.create_main_interface()
        
        # 加载初始数据
        self.load_inventory()
        
        # 启动主窗口事件循环
        self.main_root.mainloop()
   
    def set_style(self):
        style = ttk.Style()
        style.theme_use("clam")
        
        # 配置标签页样式
        style.configure("TNotebook", background="#3498db")
        style.configure("TNotebook.Tab",
                        background="#2c3e50",
                        foreground="white",
                        font=("微软雅黑", 10, "bold"),
                        padding=[10, 5])
        style.map("TNotebook.Tab",
                  background=[("selected", "#3498db")],
                  foreground=[("selected", "white")])
        
        # 配置按钮样式
        style.configure("TButton", font=("微软雅黑", 10), padding=5)
        style.configure("Accent.TButton",
                        foreground="white",
                        background="#3498db",
                        font=("微软雅黑", 10, "bold"),
                        borderwidth=0)
        style.map("Accent.TButton",
                  background=[('active', '#2980b9'), ('pressed', '#1f618d')])
        
        # 配置标签框架样式
        style.configure("TLabelframe", background="#ecf0f1", borderwidth=2, relief="groove")
        style.configure("TLabelframe.Label", background="#3498db", foreground="white", font=("微软雅黑", 10, "bold"))
        
        # 配置表格样式
        style.configure("Treeview",
                        background="#ffffff",
                        foreground="#2c3e50",
                        rowheight=25,
                        fieldbackground="#ffffff")
        style.configure("Treeview.Heading",
                        background="#3498db",
                        foreground="white",
                        font=("微软雅黑", 10, "bold"))
        style.map("Treeview", background=[("selected", "#3498db")])
        
        # 配置输入框样式
        style.configure("TEntry", padding=5)
   
    def center_window(self, width, height):
        if self.main_root:
            screen_width = self.main_root.winfo_screenwidth()
            screen_height = self.main_root.winfo_screenheight()
            
            x = (screen_width - width) // 2
            y = (screen_height - height) // 2
            
            self.main_root.geometry(f"{width}x{height}+{x}+{y}")
   
    def create_tables(self):
        # 创建进货表
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS purchase (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                date TEXT,
                product_name TEXT,
                specification TEXT,
                unit TEXT,
                quantity INTEGER,
                note TEXT
            )
        ''')
        
        # 创建出货表
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS sale (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                date TEXT,
                product_name TEXT,
                specification TEXT,
                unit TEXT,
                quantity INTEGER,
                department TEXT,
                user TEXT,
                note TEXT
            )
        ''')
        
        # 创建库存表
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS inventory (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                product_name TEXT,
                specification TEXT,
                unit TEXT,
                quantity INTEGER
            )
        ''')
        self.()
   
    def create_main_interface(self):
        # 创建菜单栏
        self.create_menu()
        
        # 创建标签页
        self.notebook = ttk.Notebook(self.main_root, style="TNotebook")
        self.notebook.pack(fill='both', expand=True, padx=10, pady=10)
        
        # 创建进货标签页
        self.purchase_frame = ttk.Frame(self.notebook)
        self.notebook.add(self.purchase_frame, text='进货管理')
        self.create_purchase_tab()
        
        # 创建出货标签页
        self.sale_frame = ttk.Frame(self.notebook)
        self.notebook.add(self.sale_frame, text='出货管理')
        self.create_sale_tab()
        
        # 创建库存标签页
        self.inventory_frame = ttk.Frame(self.notebook)
        self.notebook.add(self.inventory_frame, text='库存管理')
        self.create_inventory_tab()
        
        # 创建查询标签页
        self.query_frame = ttk.Frame(self.notebook)
        self.notebook.add(self.query_frame, text='查询与导出')
        self.create_query_tab()
   
    def create_menu(self):
        menu_bar = tk.Menu(self.main_root, bg="#ecf0f1", fg="#2c3e50")
        
        # 文件菜单
        file_menu = tk.Menu(menu_bar, tearoff=0, bg="#ecf0f1", fg="#2c3e50")
        file_menu.add_command(label="退出", command=self.main_root.destroy)
        menu_bar.add_cascade(label="文件", menu=file_menu)
        
        # 帮助菜单
        help_menu = tk.Menu(menu_bar, tearoff=0, bg="#ecf0f1", fg="#2c3e50")
        help_menu.add_command(label="关于", command=self.show_about)
        menu_bar.add_cascade(label="帮助", menu=help_menu)
        
        self.main_root.config(menu=menu_bar)
   
    def show_about(self):
        messagebox.showinfo(
            "关于",
            "XXXXX进销存管理系统\n\n"
            "版本: 2.0\n"
            "开发日期: 2025年\n"
            "版权所有 © 2025 XXXXX"
        )
   
    def create_purchase_tab(self):
        # 表单区域
        form_frame = ttk.LabelFrame(self.purchase_frame, text="进货信息录入", style="TLabelframe")
        form_frame.pack(fill='x', padx=10, pady=5)
        
        # 日期选择
        ttk.Label(form_frame, text="到货日期:").grid(row=0, column=0, padx=5, pady=5, sticky='e')
        self.purchase_date = tk.StringVar()
        self.purchase_date.set(datetime.now().strftime("%Y-%m-%d"))
        date_entry = ttk.Entry(form_frame, textvariable=self.purchase_date, width=15, state='readonly', style="TEntry")
        date_entry.grid(row=0, column=1, padx=5, pady=5, sticky='w')
        ttk.Button(form_frame, text="选择日期", command=lambda: self.select_date(self.purchase_date)).grid(row=0, column=2, padx=5, pady=5)
        
        # 品名
        ttk.Label(form_frame, text="品名:").grid(row=0, column=3, padx=5, pady=5, sticky='e')
        self.purchase_product = (form_frame, width=15, style="TCombobox")
        self.purchase_product.grid(row=0, column=4, padx=5, pady=5, sticky='w')
        self.purchase_product['values'] = self.get_product_list()
        
        # 规格
        ttk.Label(form_frame, text="规格:").grid(row=1, column=0, padx=5, pady=5, sticky='e')
        self.purchase_spec = ttk.Entry(form_frame, width=15, style="TEntry")
        self.purchase_spec.grid(row=1, column=1, padx=5, pady=5, sticky='w')
        
        # 单位
        ttk.Label(form_frame, text="单位:").grid(row=1, column=3, padx=5, pady=5, sticky='e')
        self.purchase_unit = (form_frame, width=15, style="TCombobox")
        self.purchase_unit.grid(row=1, column=4, padx=5, pady=5, sticky='w')
        self.purchase_unit['values'] = ('个', '件', '箱', '千克', '米', '升')
        
        # 数量
        ttk.Label(form_frame, text="数量:").grid(row=2, column=0, padx=5, pady=5, sticky='e')
        self.purchase_quantity = ttk.Entry(form_frame, width=15, style="TEntry")
        self.purchase_quantity.grid(row=2, column=1, padx=5, pady=5, sticky='w')
        
        # 备注
        ttk.Label(form_frame, text="备注:").grid(row=2, column=3, padx=5, pady=5, sticky='e')
        self.purchase_note = ttk.Entry(form_frame, width=15, style="TEntry")
        self.purchase_note.grid(row=2, column=4, padx=5, pady=5, sticky='w')
        
        # 按钮区域
        button_frame = ttk.Frame(self.purchase_frame)
        button_frame.pack(fill='x', padx=10, pady=5)
        ttk.Button(button_frame, text="添加进货记录", command=self.add_purchase, style="Accent.TButton").pack(side='left', padx=5)
        ttk.Button(button_frame, text="修改选中记录", command=self.edit_purchase_record, style="Accent.TButton").pack(side='left', padx=5)
        
        # 表格区域
        table_frame = ttk.LabelFrame(self.purchase_frame, text="进货记录", style="TLabelframe")
        table_frame.pack(fill='both', expand=True, padx=10, pady=5)
        
        columns = ("id", "date", "product", "spec", "unit", "quantity", "note")
        self.purchase_tree = ttk.Treeview(
            table_frame, columns=columns, show='headings', height=10, style="Treeview"
        )
        
        # 设置列宽
        self.purchase_tree.column("id", width=50, anchor='center')
        self.purchase_tree.column("date", width=100, anchor='center')
        self.purchase_tree.column("product", width=150, anchor='center')
        self.purchase_tree.column("spec", width=150, anchor='center')
        self.purchase_tree.column("unit", width=50, anchor='center')
        self.purchase_tree.column("quantity", width=80, anchor='center')
        self.purchase_tree.column("note", width=200, anchor='center')
        
        # 设置表头
        self.purchase_tree.heading("id", text="ID")
        self.purchase_tree.heading("date", text="到货日期")
        self.purchase_tree.heading("product", text="品名")
        self.purchase_tree.heading("spec", text="规格")
        self.purchase_tree.heading("unit", text="单位")
        self.purchase_tree.heading("quantity", text="数量")
        self.purchase_tree.heading("note", text="备注")
        
        # 添加滚动条
        scrollbar = ttk.Scrollbar(table_frame, orient="vertical", command=self.purchase_tree.yview)
        self.purchase_tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side="right", fill="y")
        self.purchase_tree.pack(fill="both", expand=True)
        
        # 删除按钮
        delete_frame = ttk.Frame(table_frame)
        delete_frame.pack(fill='x', pady=5)
        ttk.Button(
            delete_frame,
            text="删除选中记录",
            command=self.delete_purchase_record,
            style="Accent.TButton"
        ).pack(side='right', padx=10)
        
        # 加载数据
        self.load_purchase_data()
   
    def create_sale_tab(self):
        # 表单区域
        form_frame = ttk.LabelFrame(self.sale_frame, text="出货信息录入", style="TLabelframe")
        form_frame.pack(fill='x', padx=10, pady=5)
        
        # 日期选择
        ttk.Label(form_frame, text="领取日期:").grid(row=0, column=0, padx=5, pady=5, sticky='e')
        self.sale_date = tk.StringVar()
        self.sale_date.set(datetime.now().strftime("%Y-%m-%d"))
        date_entry = ttk.Entry(form_frame, textvariable=self.sale_date, width=15, state='readonly', style="TEntry")
        date_entry.grid(row=0, column=1, padx=5, pady=5, sticky='w')
        ttk.Button(form_frame, text="选择日期", command=lambda: self.select_date(self.sale_date)).grid(row=0, column=2, padx=5, pady=5)
        
        # 选择进货记录按钮
        ttk.Button(
            form_frame,
            text="选择进货记录",
            command=self.select_purchase_record,
            style="Accent.TButton"
        ).grid(row=0, column=3, padx=5, pady=5)
        
        # 品名
        ttk.Label(form_frame, text="品名:").grid(row=1, column=0, padx=5, pady=5, sticky='e')
        self.sale_product = ttk.Entry(form_frame, width=15, state='readonly', style="TEntry")
        self.sale_product.grid(row=1, column=1, padx=5, pady=5, sticky='w')
        
        # 规格
        ttk.Label(form_frame, text="规格:").grid(row=1, column=3, padx=5, pady=5, sticky='e')
        self.sale_spec = ttk.Entry(form_frame, width=15, state='readonly', style="TEntry")
        self.sale_spec.grid(row=1, column=4, padx=5, pady=5, sticky='w')
        
        # 单位
        ttk.Label(form_frame, text="单位:").grid(row=2, column=0, padx=5, pady=5, sticky='e')
        self.sale_unit = ttk.Entry(form_frame, width=15, state='readonly', style="TEntry")
        self.sale_unit.grid(row=2, column=1, padx=5, pady=5, sticky='w')
        
        # 数量
        ttk.Label(form_frame, text="数量:").grid(row=2, column=3, padx=5, pady=5, sticky='e')
        self.sale_quantity = ttk.Entry(form_frame, width=15, style="TEntry")
        self.sale_quantity.grid(row=2, column=4, padx=5, pady=5, sticky='w')
        
        # 领用部门
        ttk.Label(form_frame, text="领用部门:").grid(row=3, column=0, padx=5, pady=5, sticky='e')
        self.sale_department = ttk.Entry(form_frame, width=15, style="TEntry")
        self.sale_department.grid(row=3, column=1, padx=5, pady=5, sticky='w')
        
        # 使用人
        ttk.Label(form_frame, text="使用人:").grid(row=3, column=3, padx=5, pady=5, sticky='e')
        self.sale_user = ttk.Entry(form_frame, width=15, style="TEntry")
        self.sale_user.grid(row=3, column=4, padx=5, pady=5, sticky='w')
        
        # 备注
        ttk.Label(form_frame, text="备注:").grid(row=4, column=0, padx=5, pady=5, sticky='e')
        self.sale_note = ttk.Entry(form_frame, width=15, style="TEntry")
        self.sale_note.grid(row=4, column=1, padx=5, pady=5, sticky='w')
        
        # 按钮区域
        button_frame = ttk.Frame(self.sale_frame)
        button_frame.pack(fill='x', padx=10, pady=5)
        ttk.Button(button_frame, text="添加出货记录", command=self.add_sale, style="Accent.TButton").pack(side='left', padx=5)
        ttk.Button(button_frame, text="修改选中记录", command=self.edit_sale_record, style="Accent.TButton").pack(side='left', padx=5)
        
        # 表格区域
        table_frame = ttk.LabelFrame(self.sale_frame, text="出货记录", style="TLabelframe")
        table_frame.pack(fill='both', expand=True, padx=10, pady=5)
        
        columns = ("id", "date", "product", "spec", "unit", "quantity", "department", "user", "note")
        self.sale_tree = ttk.Treeview(
            table_frame, columns=columns, show='headings', height=10, style="Treeview"
        )
昨天 14:25
wyu8888
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2020-9-10
收藏
得分:0 
# 设置列宽
        self.sale_tree.column("id", width=50, anchor='center')
        self.sale_tree.column("date", width=100, anchor='center')
        self.sale_tree.column("product", width=150, anchor='center')
        self.sale_tree.column("spec", width=150, anchor='center')
        self.sale_tree.column("unit", width=50, anchor='center')
        self.sale_tree.column("quantity", width=80, anchor='center')
        self.sale_tree.column("department", width=100, anchor='center')
        self.sale_tree.column("user", width=100, anchor='center')
        self.sale_tree.column("note", width=150, anchor='center')
        
        # 设置表头
        self.sale_tree.heading("id", text="ID")
        self.sale_tree.heading("date", text="领取日期")
        self.sale_tree.heading("product", text="品名")
        self.sale_tree.heading("spec", text="规格")
        self.sale_tree.heading("unit", text="单位")
        self.sale_tree.heading("quantity", text="数量")
        self.sale_tree.heading("department", text="领用部门")
        self.sale_tree.heading("user", text="使用人")
        self.sale_tree.heading("note", text="备注")
        
        # 添加滚动条
        scrollbar = ttk.Scrollbar(table_frame, orient="vertical", command=self.sale_tree.yview)
        self.sale_tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side="right", fill="y")
        self.sale_tree.pack(fill="both", expand=True)
        
        # 删除按钮
        delete_frame = ttk.Frame(table_frame)
        delete_frame.pack(fill='x', pady=5)
        ttk.Button(
            delete_frame,
            text="删除选中记录",
            command=self.delete_sale_record,
            style="Accent.TButton"
        ).pack(side='right', padx=10)
        
        # 加载数据
        self.load_sale_data()
   
    def create_inventory_tab(self):
        # 表格区域
        table_frame = ttk.LabelFrame(self.inventory_frame, text="库存信息", style="TLabelframe")
        table_frame.pack(fill='both', expand=True, padx=10, pady=5)
        
        columns = ("id", "product", "spec", "unit", "quantity")
        self.inventory_tree = ttk.Treeview(
            table_frame, columns=columns, show='headings', height=15, style="Treeview"
        )
        
        # 设置列宽
        self.inventory_tree.column("id", width=50, anchor='center')
        self.inventory_tree.column("product", width=200, anchor='center')
        self.inventory_tree.column("spec", width=200, anchor='center')
        self.inventory_tree.column("unit", width=80, anchor='center')
        self.inventory_tree.column("quantity", width=100, anchor='center')
        
        # 设置表头
        self.inventory_tree.heading("id", text="ID")
        self.inventory_tree.heading("product", text="品名")
        self.inventory_tree.heading("spec", text="规格")
        self.inventory_tree.heading("unit", text="单位")
        self.inventory_tree.heading("quantity", text="库存数量")
        
        # 添加滚动条
        scrollbar = ttk.Scrollbar(table_frame, orient="vertical", command=self.inventory_tree.yview)
        self.inventory_tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side="right", fill="y")
        self.inventory_tree.pack(fill="both", expand=True)
        
        # 按钮区域
        button_frame = ttk.Frame(self.inventory_frame)
        button_frame.pack(fill='x', padx=10, pady=5)
        ttk.Button(
            button_frame,
            text="刷新库存",
            command=self.load_inventory,
            style="Accent.TButton"
        ).pack(side='left', padx=5)
        
        # 加载数据
        self.load_inventory()
   
    def create_query_tab(self):
        # 查询条件区域
        query_frame = ttk.LabelFrame(self.query_frame, text="查询条件", style="TLabelframe")
        query_frame.pack(fill='x', padx=10, pady=5)
        
        # 年份选择
        ttk.Label(query_frame, text="选择年份:").grid(row=0, column=0, padx=5, pady=5, sticky='e')
        self.query_year = (query_frame, width=10, style="TCombobox")
        self.query_year.grid(row=0, column=1, padx=5, pady=5, sticky='w')
        self.query_year['values'] = [str(year) for year in range(2020, 2031)]
        self.query_year.set(str(datetime.now().year))
        
        # 查询类型
        ttk.Label(query_frame, text="查询类型:").grid(row=0, column=2, padx=5, pady=5, sticky='e')
        self.query_type = (query_frame, width=10, style="TCombobox")
        self.query_type.grid(row=0, column=3, padx=5, pady=5, sticky='w')
        self.query_type['values'] = ('进货记录', '出货记录', '库存')
        self.query_type.set('库存')
        
        # 查询按钮
        ttk.Button(query_frame, text="查询", command=self.execute_query, style="Accent.TButton").grid(row=0, column=4, padx=10, pady=5)
        
        # 操作按钮区域
        button_frame = ttk.Frame(self.query_frame)
        button_frame.pack(fill='x', padx=10, pady=5)
        
        ttk.Button(button_frame, text="导出Excel", command=self.export_excel, style="Accent.TButton").pack(side='left', padx=5)
        ttk.Button(button_frame, text="打印预览", command=self.print_preview, style="Accent.TButton").pack(side='left', padx=5)
        
        # 表格区域
        table_frame = ttk.LabelFrame(self.query_frame, text="查询结果", style="TLabelframe")
        table_frame.pack(fill='both', expand=True, padx=10, pady=5)
        
        self.query_tree = ttk.Treeview(
            table_frame, show='headings', height=15, style="Treeview"
        )
        
        # 添加滚动条
        scrollbar = ttk.Scrollbar(table_frame, orient="vertical", command=self.query_tree.yview)
        self.query_tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side="right", fill="y")
        self.query_tree.pack(fill="both", expand=True)
        
        # 初始加载库存数据
        self.execute_query()
   
    def select_date(self, date_var):
        # 解析当前日期
        try:
            current_date = datetime.strptime(date_var.get(), "%Y-%m-%d").date()
        except ValueError:
            current_date = date.today()
        
        # 创建日期选择对话框
        dialog = DatePickerDialog(self.main_root, "选择日期", current_date)
        
        # 更新日期变量
        date_var.set(dialog.selected_date.strftime("%Y-%m-%d"))
   
    def get_product_list(self):
        self.cursor.execute("SELECT DISTINCT product_name FROM inventory")
        return [row[0] for row in self.cursor.fetchall()]
   
    def select_purchase_record(self):
        # 创建选择进货记录的窗口
        select_window = tk.Toplevel(self.main_root)
        select_window.title("选择进货记录")
        select_window.geometry("800x500")
        select_window.transient(self.main_root)
        select_window.grab_set()
        
        # 表格区域
        table_frame = ttk.Frame(select_window)
        table_frame.pack(fill='both', expand=True, padx=10, pady=10)
        
        columns = ("id", "date", "product", "spec", "unit", "quantity", "note")
        tree = ttk.Treeview(
            table_frame, columns=columns, show='headings', height=15, style="Treeview"
        )
        
        # 设置列宽
        tree.column("id", width=50, anchor='center')
        tree.column("date", width=100, anchor='center')
        tree.column("product", width=150, anchor='center')
        tree.column("spec", width=150, anchor='center')
        tree.column("unit", width=50, anchor='center')
        tree.column("quantity", width=80, anchor='center')
        tree.column("note", width=200, anchor='center')
        
        # 设置表头
        tree.heading("id", text="ID")
        tree.heading("date", text="到货日期")
        tree.heading("product", text="品名")
        tree.heading("spec", text="规格")
        tree.heading("unit", text="单位")
        tree.heading("quantity", text="数量")
        tree.heading("note", text="备注")
        
        # 添加滚动条
        scrollbar = ttk.Scrollbar(table_frame, orient="vertical", command=tree.yview)
        tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side="right", fill="y")
        tree.pack(fill="both", expand=True)
        
        # 加载数据
        self.cursor.execute("SELECT * FROM purchase")
        rows = self.cursor.fetchall()
        for row in rows:
            tree.insert("", "end", values=row)
        
        # 选择按钮
        button_frame = ttk.Frame(select_window)
        button_frame.pack(fill='x', padx=10, pady=10)
        
        ttk.Button(
            button_frame,
            text="选择",
            command=lambda: self.fill_sale_form(tree, select_window),
            style="Accent.TButton"
        ).pack(side='right', padx=10)
        
        ttk.Button(
            button_frame,
            text="取消",
            command=select_window.destroy,
            style="Accent.TButton"
        ).pack(side='right', padx=5)
   
    def fill_sale_form(self, tree, window):
        selected = tree.selection()
        if not selected:
            messagebox.showerror("错误", "请选择一条记录!")
            return
        
        record = tree.item(selected[0], "values")
        self.sale_product.config(state='normal')
        self.sale_product.delete(0, tk.END)
        self.sale_product.insert(0, record[2])
        self.sale_product.config(state='readonly')
        
        self.sale_spec.config(state='normal')
        self.sale_spec.delete(0, tk.END)
        self.sale_spec.insert(0, record[3])
        self.sale_spec.config(state='readonly')
        
        self.sale_unit.config(state='normal')
        self.sale_unit.delete(0, tk.END)
        self.sale_unit.insert(0, record[4])
        self.sale_unit.config(state='readonly')
        
        self.sale_quantity.delete(0, tk.END)
        self.sale_quantity.insert(0, "1")
        
        window.destroy()
   
    def add_purchase(self):
        date = self.purchase_date.get()
        product = self.purchase_product.get()
        spec = self.purchase_spec.get()
        unit = self.purchase_unit.get()
        quantity = self.purchase_quantity.get()
        note = self.purchase_note.get()
        
        if not all([date, product, spec, unit, quantity]):
            messagebox.showerror("错误", "请填写所有必填字段!")
            return
        
        try:
            quantity = int(quantity)
            if quantity <= 0:
                messagebox.showerror("错误", "数量必须大于0!")
                return
        except ValueError:
            messagebox.showerror("错误", "数量必须是整数!")
            return
        
        # 添加到进货表
        self.cursor.execute(
            "INSERT INTO purchase (date, product_name, specification, unit, quantity, note) VALUES (?, ?, ?, ?, ?, ?)",
            (date, product, spec, unit, quantity, note)
        )
        
        # 更新库存
        self.cursor.execute(
            "SELECT id, quantity FROM inventory WHERE product_name=? AND specification=?",
            (product, spec)
        )
        result = self.cursor.fetchone()
        
        if result:
            # 更新现有库存
            new_quantity = result[1] + quantity
            self.cursor.execute(
                "UPDATE inventory SET quantity=? WHERE id=?",
                (new_quantity, result[0])
            )
        else:
            # 添加新库存
            self.cursor.execute(
                "INSERT INTO inventory (product_name, specification, unit, quantity) VALUES (?, ?, ?, ?)",
                (product, spec, unit, quantity)
            )
        
        self.()
        messagebox.showinfo("成功", "进货记录添加成功!")
        self.load_purchase_data()
        self.load_inventory()
        
        # 清空表单
        self.purchase_product.set('')
        self.purchase_spec.delete(0, tk.END)
        self.purchase_unit.set('')
        self.purchase_quantity.delete(0, tk.END)
        self.purchase_note.delete(0, tk.END)
   
    def add_sale(self):
        date = self.sale_date.get()
        product = self.sale_product.get()
        spec = self.sale_spec.get()
        unit = self.sale_unit.get()
        quantity = self.sale_quantity.get()
        department = self.sale_department.get()
        user = self.sale_user.get()
        note = self.sale_note.get()
        
        if not all([date, product, spec, unit, quantity, department, user]):
            messagebox.showerror("错误", "请填写所有必填字段!")
            return
        
        try:
            quantity = int(quantity)
            if quantity <= 0:
                messagebox.showerror("错误", "数量必须大于0!")
                return
        except ValueError:
            messagebox.showerror("错误", "数量必须是整数!")
            return
        
        # 检查库存
        self.cursor.execute(
            "SELECT id, quantity FROM inventory WHERE product_name=? AND specification=?",
            (product, spec)
        )
        result = self.cursor.fetchone()
        
        if not result:
            messagebox.showerror("错误", "该产品不存在于库存中!")
            return
        
        if result[1] < quantity:
            messagebox.showerror("错误", "库存不足!")
            return
        
        # 添加到出货表
        self.cursor.execute(
            "INSERT INTO sale (date, product_name, specification, unit, quantity, department, user, note) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
            (date, product, spec, unit, quantity, department, user, note)
        )
        
        # 更新库存
        new_quantity = result[1] - quantity
        self.cursor.execute(
            "UPDATE inventory SET quantity=? WHERE id=?",
            (new_quantity, result[0])
        )
        
        # 如果库存为0,删除库存记录
        if new_quantity <= 0:
            self.cursor.execute(
                "DELETE FROM inventory WHERE id=?",
                (result[0],)
            )
        
        self.()
        messagebox.showinfo("成功", "出货记录添加成功!")
        self.load_sale_data()
        self.load_inventory()
        
        # 清空表单
        self.sale_product.config(state='normal')
        self.sale_product.delete(0, tk.END)
        self.sale_product.config(state='readonly')
        
        self.sale_spec.config(state='normal')
        self.sale_spec.delete(0, tk.END)
        self.sale_spec.config(state='readonly')
        
        self.sale_unit.config(state='normal')
        self.sale_unit.delete(0, tk.END)
        self.sale_unit.config(state='readonly')
        
        self.sale_quantity.delete(0, tk.END)
        self.sale_department.delete(0, tk.END)
        self.sale_user.delete(0, tk.END)
        self.sale_note.delete(0, tk.END)
   
    def edit_purchase_record(self):
        selected = self.purchase_tree.selection()
        if not selected:
            messagebox.showerror("错误", "请选择要修改的记录!")
            return
        
        # 创建编辑窗口
        edit_window = tk.Toplevel(self.main_root)
        edit_window.title("编辑进货记录")
        edit_window.geometry("400x300")
        edit_window.transient(self.main_root)
        edit_window.grab_set()
        
        # 获取选中记录
        record_id = self.purchase_tree.item(selected[0], "values")[0]
        self.cursor.execute("SELECT * FROM purchase WHERE id=?", (record_id,))
        record = self.cursor.fetchone()
        
        if not record:
            messagebox.showerror("错误", "记录未找到!")
            edit_window.destroy()
            return
        
        # 表单区域
        form_frame = ttk.Frame(edit_window)
        form_frame.pack(fill='both', expand=True, padx=20, pady=20)
        
        # 日期
        ttk.Label(form_frame, text="到货日期:").grid(row=0, column=0, padx=5, pady=5, sticky='e')
        date_var = tk.StringVar(value=record[1])
        date_entry = ttk.Entry(form_frame, textvariable=date_var, width=15, state='readonly')
        date_entry.grid(row=0, column=1, padx=5, pady=5, sticky='w')
        ttk.Button(form_frame, text="选择日期", command=lambda: self.select_date(date_var)).grid(row=0, column=2, padx=5, pady=5)
        
        # 品名
        ttk.Label(form_frame, text="品名:").grid(row=1, column=0, padx=5, pady=5, sticky='e')
        product_var = tk.StringVar(value=record[2])
        product_entry = ttk.Entry(form_frame, textvariable=product_var, width=15)
        product_entry.grid(row=1, column=1, padx=5, pady=5, sticky='w')
        
        # 规格
        ttk.Label(form_frame, text="规格:").grid(row=2, column=0, padx=5, pady=5, sticky='e')
        spec_var = tk.StringVar(value=record[3])
        spec_entry = ttk.Entry(form_frame, textvariable=spec_var, width=15)
        spec_entry.grid(row=2, column=1, padx=5, pady=5, sticky='w')
        
        # 单位
        ttk.Label(form_frame, text="单位:").grid(row=3, column=0, padx=5, pady=5, sticky='e')
        unit_var = tk.StringVar(value=record[4])
        unit_entry = ttk.Entry(form_frame, textvariable=unit_var, width=15)
        unit_entry.grid(row=3, column=1, padx=5, pady=5, sticky='w')
        
        # 数量
        ttk.Label(form_frame, text="数量:").grid(row=4, column=0, padx=5, pady=5, sticky='e')
        quantity_var = tk.StringVar(value=record[5])
        quantity_entry = ttk.Entry(form_frame, textvariable=quantity_var, width=15)
        quantity_entry.grid(row=4, column=1, padx=5, pady=5, sticky='w')
        
        # 备注
        ttk.Label(form_frame, text="备注:").grid(row=5, column=0, padx=5, pady=5, sticky='e')
        note_var = tk.StringVar(value=record[6])
        note_entry = ttk.Entry(form_frame, textvariable=note_var, width=15)
        note_entry.grid(row=5, column=1, padx=5, pady=5, sticky='w')
        
        # 按钮区域
        button_frame = ttk.Frame(edit_window)
        button_frame.pack(fill='x', padx=10, pady=10)
        
        def save_changes():
            # 获取修改后的值
            date = date_var.get()
            product = product_var.get()
            spec = spec_var.get()
            unit = unit_var.get()
            quantity = quantity_var.get()
            note = note_var.get()
            
            if not all([date, product, spec, unit, quantity]):
                messagebox.showerror("错误", "请填写所有必填字段!")
                return
            
            try:
                quantity = int(quantity)
                if quantity <= 0:
                    messagebox.showerror("错误", "数量必须大于0!")
                    return
            except ValueError:
                messagebox.showerror("错误", "数量必须是整数!")
                return
            
            # 更新进货表
            self.cursor.execute(
                "UPDATE purchase SET date=?, product_name=?, specification=?, unit=?, quantity=?, note=? WHERE id=?",
                (date, product, spec, unit, quantity, note, record_id)
            )
            
            # 更新库存
            # 先删除旧库存
            self.cursor.execute(
                "SELECT quantity FROM inventory WHERE product_name=? AND specification=?",
                (record[2], record[3])
            )
            old_inventory = self.cursor.fetchone()
            if old_inventory:
                new_quantity = old_inventory[0] - record[5]
                if new_quantity <= 0:
                    self.cursor.execute(
                        "DELETE FROM inventory WHERE product_name=? AND specification=?",
                        (record[2], record[3])
                    )
                else:
                    self.cursor.execute(
                        "UPDATE inventory SET quantity=? WHERE product_name=? AND specification=?",
                        (new_quantity, record[2], record[3])
                    )
            
            # 添加新库存
            self.cursor.execute(
                "SELECT id, quantity FROM inventory WHERE product_name=? AND specification=?",
                (product, spec)
            )
            result = self.cursor.fetchone()
            
            if result:
                new_quantity = result[1] + quantity
                self.cursor.execute(
                    "UPDATE inventory SET quantity=? WHERE id=?",
                    (new_quantity, result[0])
                )
            else:
                self.cursor.execute(
                    "INSERT INTO inventory (product_name, specification, unit, quantity) VALUES (?, ?, ?, ?)",
                    (product, spec, unit, quantity)
                )
            
            self.()
            messagebox.showinfo("成功", "进货记录修改成功!")
            self.load_purchase_data()
            self.load_inventory()
            edit_window.destroy()
        
        ttk.Button(
            button_frame,
            text="保存",
            command=save_changes,
            style="Accent.TButton"
        ).pack(side='right', padx=10)
        
        ttk.Button(
            button_frame,
            text="取消",
            command=edit_window.destroy,
            style="Accent.TButton"
        ).pack(side='right', padx=5)
   
    def edit_sale_record(self):
        selected = self.sale_tree.selection()
        if not selected:
            messagebox.showerror("错误", "请选择要修改的记录!")
            return
        
        # 创建编辑窗口
        edit_window = tk.Toplevel(self.main_root)
        edit_window.title("编辑出货记录")
        edit_window.geometry("400x300")
        edit_window.transient(self.main_root)
        edit_window.grab_set()
        
        # 获取选中记录
        record_id = self.sale_tree.item(selected[0], "values")[0]
        self.cursor.execute("SELECT * FROM sale WHERE id=?", (record_id,))
        record = self.cursor.fetchone()
        
        if not record:
            messagebox.showerror("错误", "记录未找到!")
            edit_window.destroy()
            return
        
        # 表单区域
        form_frame = ttk.Frame(edit_window)
        form_frame.pack(fill='both', expand=True, padx=20, pady=20)
        
        # 日期
        ttk.Label(form_frame, text="领取日期:").grid(row=0, column=0, padx=5, pady=5, sticky='e')
        date_var = tk.StringVar(value=record[1])
        date_entry = ttk.Entry(form_frame, textvariable=date_var, width=15, state='readonly')
        date_entry.grid(row=0, column=1, padx=5, pady=5, sticky='w')
        ttk.Button(form_frame, text="选择日期", command=lambda: self.select_date(date_var)).grid(row=0, column=2, padx=5, pady=5)
        
        # 品名(不可修改)
        ttk.Label(form_frame, text="品名:").grid(row=1, column=0, padx=5, pady=5, sticky='e')
        product_var = tk.StringVar(value=record[2])
        product_entry = ttk.Entry(form_frame, textvariable=product_var, width=15, state='readonly')
        product_entry.grid(row=1, column=1, padx=5, pady=5, sticky='w')
        
        # 规格(不可修改)
        ttk.Label(form_frame, text="规格:").grid(row=2, column=0, padx=5, pady=5, sticky='e')
        spec_var = tk.StringVar(value=record[3])
        spec_entry = ttk.Entry(form_frame, textvariable=spec_var, width=15, state='readonly')
        spec_entry.grid(row=2, column=1, padx=5, pady=5, sticky='w')
        
        # 单位(不可修改)
        ttk.Label(form_frame, text="单位:").grid(row=3, column=0, padx=5, pady=5, sticky='e')
        unit_var = tk.StringVar(value=record[4])
        unit_entry = ttk.Entry(form_frame, textvariable=unit_var, width=15, state='readonly')
        unit_entry.grid(row=3, column=1, padx=5, pady=5, sticky='w')
        
        # 数量(可修改)
        ttk.Label(form_frame, text="数量:").grid(row=4, column=0, padx=5, pady=5, sticky='e')
        quantity_var = tk.StringVar(value=record[5])
        quantity_entry = ttk.Entry(form_frame, textvariable=quantity_var, width=15)
        quantity_entry.grid(row=4, column=1, padx=5, pady=5, sticky='w')
        
        # 按钮区域
        button_frame = ttk.Frame(edit_window)
        button_frame.pack(fill='x', padx=10, pady=10)
        
        def save_changes():
            # 获取修改后的值
            date = date_var.get()
            quantity = quantity_var.get()
            
            if not all([date, quantity]):
                messagebox.showerror("错误", "请填写所有必填字段!")
                return
            
            try:
                new_quantity = int(quantity)
                if new_quantity <= 0:
                    messagebox.showerror("错误", "数量必须大于0!")
                    return
            except ValueError:
                messagebox.showerror("错误", "数量必须是整数!")
                return
            
            # 获取原数量
            old_quantity = record[5]
            difference = new_quantity - old_quantity
            
            # 检查库存
            self.cursor.execute(
                "SELECT id, quantity FROM inventory WHERE product_name=? AND specification=?",
                (record[2], record[3])
            )
            inventory = self.cursor.fetchone()
            
            if not inventory:
                messagebox.showerror("错误", "该产品不存在于库存中!")
                return
            
            # 检查库存是否足够
            if inventory[1] < difference:
                messagebox.showerror("错误", "库存不足!")
                return
            
            # 更新出货表
            self.cursor.execute(
                "UPDATE sale SET date=?, quantity=? WHERE id=?",
                (date, new_quantity, record_id)
            )
            
            # 更新库存
            new_inventory_quantity = inventory[1] - difference
            self.cursor.execute(
                "UPDATE inventory SET quantity=? WHERE id=?",
                (new_inventory_quantity, inventory[0])
            )
            
            # 如果库存为0,删除库存记录
            if new_inventory_quantity <= 0:
                self.cursor.execute(
                    "DELETE FROM inventory WHERE id=?",
                    (inventory[0],)
                )
            
            self.()
            messagebox.showinfo("成功", "出货记录修改成功!")
            self.load_sale_data()
            self.load_inventory()
            edit_window.destroy()
        
        ttk.Button(
            button_frame,
            text="保存",
            command=save_changes,
            style="Accent.TButton"
        ).pack(side='right', padx=10)
        
        ttk.Button(
            button_frame,
            text="取消",
            command=edit_window.destroy,
            style="Accent.TButton"
        ).pack(side='right', padx=5)
   
    def delete_purchase_record(self):
        selected = self.purchase_tree.selection()
        if not selected:
            messagebox.showerror("错误", "请选择要删除的记录!")
            return
        
        # 获取选中记录的ID
        record_id = self.purchase_tree.item(selected[0], "values")[0]
        
        # 获取记录详情
        self.cursor.execute("SELECT * FROM purchase WHERE id=?", (record_id,))
        record = self.cursor.fetchone()
        
        if not record:
            messagebox.showerror("错误", "记录未找到!")
            return
        
        # 获取产品信息
        product_name = record[2]
        specification = record[3]
        quantity = record[5]
        
        # 从进货表中删除记录
        self.cursor.execute("DELETE FROM purchase WHERE id=?", (record_id,))
        
        # 更新库存
        self.cursor.execute(
            "SELECT id, quantity FROM inventory WHERE product_name=? AND specification=?",
            (product_name, specification)
        )
        inventory = self.cursor.fetchone()
        
        if inventory:
            new_quantity = inventory[1] - quantity
            if new_quantity <= 0:
                # 删除库存记录
                self.cursor.execute(
                    "DELETE FROM inventory WHERE id=?",
                    (inventory[0],)
                )
            else:
                # 更新库存数量
                self.cursor.execute(
                    "UPDATE inventory SET quantity=? WHERE id=?",
                    (new_quantity, inventory[0])
                )
        
        self.()
        messagebox.showinfo("成功", "进货记录已删除!")
        self.load_purchase_data()
        self.load_inventory()
   
    def delete_sale_record(self):
        selected = self.sale_tree.selection()
        if not selected:
            messagebox.showerror("错误", "请选择要删除的记录!")
            return
        
        # 获取选中记录的ID
        record_id = self.sale_tree.item(selected[0], "values")[0]
        
        # 获取记录详情
        self.cursor.execute("SELECT * FROM sale WHERE id=?", (record_id,))
        record = self.cursor.fetchone()
        
        if not record:
            messagebox.showerror("错误", "记录未找到!")
            return
        
        # 获取产品信息
        product_name = record[2]
        specification = record[3]
        quantity = record[5]
        
      
昨天 14:28
wyu8888
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2020-9-10
收藏
得分:0 
# 从出货表中删除记录
        self.cursor.execute("DELETE FROM sale WHERE id=?", (record_id,))
        
        # 更新库存
        self.cursor.execute(
            "SELECT id, quantity FROM inventory WHERE product_name=? AND specification=?",
            (product_name, specification)
        )
        inventory = self.cursor.fetchone()
        
        if inventory:
            new_quantity = inventory[1] + quantity
            self.cursor.execute(
                "UPDATE inventory SET quantity=? WHERE id=?",
                (new_quantity, inventory[0])
            )
        else:
            # 如果库存不存在,创建新库存
            self.cursor.execute(
                "INSERT INTO inventory (product_name, specification, unit, quantity) VALUES (?, ?, ?, ?)",
                (product_name, specification, record[4], quantity)
            )
        
        self.()
        messagebox.showinfo("成功", "出货记录已删除!")
        self.load_sale_data()
        self.load_inventory()
   
    def load_purchase_data(self):
        # 清空表格
        for row in self.purchase_tree.get_children():
            self.purchase_tree.delete(row)
        
        # 从数据库加载数据
        self.cursor.execute("SELECT * FROM purchase ORDER BY date DESC")
        rows = self.cursor.fetchall()
        
        # 添加到表格
        for row in rows:
            self.purchase_tree.insert("", "end", values=row)
   
    def load_sale_data(self):
        # 清空表格
        for row in self.sale_tree.get_children():
            self.sale_tree.delete(row)
        
        # 从数据库加载数据
        self.cursor.execute("SELECT * FROM sale ORDER BY date DESC")
        rows = self.cursor.fetchall()
        
        # 添加到表格
        for row in rows:
            self.sale_tree.insert("", "end", values=row)
   
    def load_inventory(self):
        # 清空表格
        for row in self.inventory_tree.get_children():
            self.inventory_tree.delete(row)
        
        # 从数据库加载数据
        self.cursor.execute("SELECT * FROM inventory WHERE quantity > 0")
        rows = self.cursor.fetchall()
        
        # 添加到表格
        for row in rows:
            self.inventory_tree.insert("", "end", values=row)
        
        # 更新产品列表
        self.purchase_product['values'] = self.get_product_list()
   
    def execute_query(self):
        year = self.query_year.get()
        query_type = self.query_type.get()
        
        # 清空表格
        for row in self.query_tree.get_children():
            self.query_tree.delete(row)
        
        # 清空列定义
        self.query_tree["columns"] = []
        
        if query_type == "进货记录":
            # 设置列
            columns = ("id", "date", "product", "spec", "unit", "quantity", "note")
            self.query_tree["columns"] = columns
            
            # 设置列宽
            for col in columns:
                self.query_tree.column(col, width=100, anchor='center')
            
            # 设置表头
            self.query_tree.heading("id", text="ID")
            self.query_tree.heading("date", text="到货日期")
            self.query_tree.heading("product", text="品名")
            self.query_tree.heading("spec", text="规格")
            self.query_tree.heading("unit", text="单位")
            self.query_tree.heading("quantity", text="数量")
            self.query_tree.heading("note", text="备注")
            
            # 执行查询
            self.cursor.execute(
                "SELECT id, date, product_name, specification, unit, quantity, note FROM purchase WHERE strftime('%Y', date)=?",
                (year,)
            )
        
        elif query_type == "出货记录":
            # 设置列
            columns = ("id", "date", "product", "spec", "unit", "quantity", "department", "user", "note")
            self.query_tree["columns"] = columns
            
            # 设置列宽
            for col in columns:
                self.query_tree.column(col, width=100, anchor='center')
            
            # 设置表头
            self.query_tree.heading("id", text="ID")
            self.query_tree.heading("date", text="领取日期")
            self.query_tree.heading("product", text="品名")
            self.query_tree.heading("spec", text="规格")
            self.query_tree.heading("unit", text="单位")
            self.query_tree.heading("quantity", text="数量")
            self.query_tree.heading("department", text="领用部门")
            self.query_tree.heading("user", text="使用人")
            self.query_tree.heading("note", text="备注")
            
            # 执行查询
            self.cursor.execute(
                "SELECT id, date, product_name, specification, unit, quantity, department, user, note FROM sale WHERE strftime('%Y', date)=?",
                (year,)
            )
        
        else:  # 库存
            # 设置列
            columns = ("id", "product", "spec", "unit", "quantity")
            self.query_tree["columns"] = columns
            
            # 设置列宽
            for col in columns:
                self.query_tree.column(col, width=150, anchor='center')
            
            # 设置表头
            self.query_tree.heading("id", text="ID")
            self.query_tree.heading("product", text="品名")
            self.query_tree.heading("spec", text="规格")
            self.query_tree.heading("unit", text="单位")
            self.query_tree.heading("quantity", text="库存数量")
            
            # 执行查询
            self.cursor.execute("SELECT * FROM inventory WHERE quantity > 0")
        
        # 添加数据到表格
        rows = self.cursor.fetchall()
        for row in rows:
            self.query_tree.insert("", "end", values=row)
   
    def export_excel(self):
        # 获取当前查询的数据
        items = self.query_tree.get_children()
        if not items:
            messagebox.showinfo("提示", "没有数据可导出!")
            return
        
        # 获取列名
        columns = self.query_tree["columns"]
        headers = [self.query_tree.heading(col)["text"] for col in columns]
        
        # 获取数据
        data = []
        for item in items:
            data.append(self.query_tree.item(item, "values"))
        
        # 创建Excel文件
        filename = filedialog.asksaveasfilename(
            defaultextension=".xlsx",
            filetypes=[("Excel 文件", "*.xlsx"), ("所有文件", "*.*")],
            title="保存为Excel文件"
        )
        
        if not filename:
            return
        
        wb = openpyxl.Workbook()
        ws = wb.active
        ws.title = "数据导出"
        
        # 设置标题
        ws.merge_cells('A1:H1')
        title_cell = ws['A1']
        title_cell.value = f"XXXXX{self.query_year.get()}年{self.query_type.get()}"
        title_cell.font = Font(size=16, bold=True)
        title_cell.alignment = Alignment(horizontal='center', vertical='center')
        
        # 设置单位信息
        ws['A2'] = "XXXXX"
        ws['H2'] = f"导出日期:{datetime.now().strftime('%Y-%m-%d')}"
        
        # 添加表头
        for col_idx, header in enumerate(headers, 1):
            cell = ws.cell(row=3, column=col_idx, value=header)
            cell.font = Font(bold=True)
            cell.alignment = Alignment(horizontal='center')
        
        # 添加数据
        for row_idx, row_data in enumerate(data, 4):
            for col_idx, cell_value in enumerate(row_data, 1):
                ws.cell(row=row_idx, column=col_idx, value=cell_value)
        
        # 设置列宽
        for col_idx in range(1, len(headers) + 1):
            col_letter = get_column_letter(col_idx)
            ws.column_dimensions[col_letter].width = 20
        
        # 添加边框
        thin_border = Border(
            left=Side(style='thin'),
            right=Side(style='thin'),
            top=Side(style='thin'),
            bottom=Side(style='thin')
        )
        
        for row in ws.iter_rows(min_row=3, max_row=len(data)+3, min_col=1, max_col=len(headers)):
            for cell in row:
                cell.border = thin_border
        
        try:
            wb.save(filename)
            messagebox.showinfo("导出成功", f"数据已成功导出到:\n{filename}")
        except Exception as e:
            messagebox.showerror("导出失败", f"导出过程中发生错误:\n{str(e)}")
   
    def print_preview(self):
        # 获取当前查询的数据
        items = self.query_tree.get_children()
        if not items:
            messagebox.showinfo("提示", "没有数据可打印!")
            return
        
        # 获取列名
        columns = self.query_tree["columns"]
        headers = [self.query_tree.heading(col)["text"] for col in columns]
        
        # 获取数据
        data = []
        for item in items:
            data.append(self.query_tree.item(item, "values"))
        
        # 创建标题
        title = f"X{self.query_year.get()}年{self.query_type.get()}"
        
        # 打开打印预览窗口
        PrintPreviewWindow(
            self.main_root,
            data,
            headers,
            title
        )
   
    def __del__(self):
        # 关闭数据库连接
        if hasattr(self, 'conn'):
            self.conn.close()

# 创建应用程序实例
app = InventorySystem()
昨天 14:28
wyu8888
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2020-9-10
收藏
得分:0 
论坛活跃度太低了
昨天 15:52
快速回复:python代码制作的进销存软件
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.211883 second(s), 10 queries.
Copyright©2004-2025, BC-CN.NET, All Rights Reserved