Please help with the Inventory management issue

INVENTORY.PY

import customtkinter as ctk
from PIL import Image
import tkinter as tk
from tkinter import ttk
import ttkbootstrap as tb
from database import Database  # Import the Database class

class InventoryManagement(ctk.CTkFrame):
    def __init__(self, parent, show_page_callback):
        super().__init__(parent)
        self.db = Database()  # Initialize the database
        self.show_page = show_page_callback
        self.load_data()  # Load medicines when the UI starts

        # Title Frame
        title_frame = ctk.CTkFrame(self, fg_color='#010c48', corner_radius=10)
        title_frame.pack(side='top', fill='x')

        # Logo/Image
        img = ctk.CTkImage(light_image=Image.open('icon2.png'), size=(60, 60))
        img_label = ctk.CTkLabel(title_frame, text='', image=img, bg_color='#010c48', corner_radius=10)
        img_label.grid(row=0, column=0, padx=15, pady=10, sticky="w")

        # Title Label
        title_label = ctk.CTkLabel(
            title_frame, 
            text="INVENTORY MANAGEMENT SYSTEM: inventory manager", 
            font=("Times New Roman", 24, "bold"), 
            text_color="powderblue", bg_color='#010c48', corner_radius=10
        )
        title_label.grid(row=0, column=1, padx=20, pady=20, sticky="w")

        # Back to Dashboard Button
        back_button = ctk.CTkButton(title_frame, text='Back to Dashboard', font=("Times New Roman", 24, "bold"), corner_radius=15, bg_color='#010c48', command=lambda: self.show_page('dashboard'))
        back_button.grid(row=0, column=2, padx=15, pady=10, sticky="e")

        # Make sure columns expand properly
        title_frame.columnconfigure(1, weight=1)  # Expands the title to take available space

        # Main Content Frame
        self.main_frame = ctk.CTkFrame(self)
        self.main_frame.pack(fill="both", expand=True, padx=20, pady=20)

        # Top Frame (Treeview)
        self.top_frame = ctk.CTkFrame(self.main_frame)
        self.top_frame.pack(side='top', fill='x', padx=5)
        
        # Tree Frame
        tree_frame = ctk.CTkFrame(self.top_frame)
        tree_frame.pack(fill='both', expand=True)
        tree_frame.columnconfigure(0, weight=1)
        tree_frame.columnconfigure(1, weight=0)

        # Treeview
        columns = ("ID", "Name", "Batch No", "Form", "Manufactured date", "Expiry Date", "Price", "Quantity", "Days remaining")
        self.tree = ttk.Treeview(tree_frame, columns=columns, show="headings", height=17)
        for col in columns:
            self.tree.heading(col, text=col)
            self.tree.column(col, anchor="center", width=120)

        self.tree.grid(row=0, column=0, sticky='nsew')
        
        scrollbar = ttk.Scrollbar(tree_frame, orient='vertical', command=self.tree.yview)
        self.tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.grid(row=0, column=1, sticky='ns')
        
        # Bottom Frame (Menu and Content)
        self.bottom_frame = ctk.CTkFrame(self.main_frame)
        self.bottom_frame.pack(fill="both", expand=True)

        # Left Panel - Side Menu
        self.menu_frame = ctk.CTkFrame(self.bottom_frame, width=200)
        self.menu_frame.grid(row=0, column=0, sticky="ns")
        
        # Operations Label
        ctk.CTkLabel(self.menu_frame, text="Operations", font=("Times New Roman", 20, "bold"), text_color='#010c48').pack(pady=(10, 5))
        
        # Menu Buttons
        buttons = {
            "Add": ctk.CTkButton(self.menu_frame, text="Add Medicines", command=lambda: self.show_panel("add"), font=("Times New Roman", 20, "bold"), width=330),
            "Modify": ctk.CTkButton(self.menu_frame, text="Modify Medicines", command=lambda: self.show_panel("modify"), font=("Times New Roman", 20, "bold"), width=330),
            "Delete": ctk.CTkButton(self.menu_frame, text="Delete Medicines", command=lambda: self.show_panel("delete"), font=("Times New Roman", 20, "bold"), width=330)
        }
        for btn in buttons.values():
            btn.pack(fill="both", pady=5, expand=True)

        # Right Panel - Dynamic Content
        self.content_frame = ctk.CTkFrame(self.bottom_frame)
        self.content_frame.grid(row=0, column=1, sticky="nsew")

        # Configure grid for content_frame
        self.content_frame.grid_rowconfigure(0, weight=0)  # Row for search entry
        self.content_frame.grid_rowconfigure(1, weight=1)  # Row for dynamic content
        self.content_frame.grid_columnconfigure(0, weight=1)  # Allow columns to expand

        # Search Entry at the top of the content frame
        search_frame = ctk.CTkFrame(self.content_frame)
        search_frame.grid(row=0, column=0, sticky="ew", padx=10, pady=10)
        self.search_entry = ctk.CTkEntry(search_frame, placeholder_text="Search Medicines")
        self.search_entry.pack(side="left", fill="x", expand=True, padx=(0, 5))
        ctk.CTkButton(search_frame, text="Search", command=self.search_medicine).pack(side="right")

        self.current_panel = None

    def show_panel(self, panel_name):
        """Show the selected panel (Add, Modify, Delete)."""
        if self.current_panel:
            self.current_panel.grid_forget()
        
        if panel_name == "add":
            self.current_panel = self.add_panel()
        elif panel_name == "modify":
            self.current_panel = self.modify_panel()
        elif panel_name == "delete":
            self.current_panel = self.delete_panel()

        self.current_panel.grid(row=1, column=0, sticky="nsew")

    def add_panel(self):
        """Create the Add Medicine panel."""
        panel = ctk.CTkFrame(self.content_frame)
        panel.grid(row=1, column=0, sticky="nsew")

        ctk.CTkLabel(panel, text="Add Medicine", font=("Arial", 20, "bold")).pack(pady=10)

        # Fields for adding a medicine
        fields = [
            ("Name", "Enter Medicine Name"),
            ("Batch No", "Enter Batch Number"),
            ("Form of Medicine", "Select Form of Med"),
            ("Manufactured Date", "Enter Manufactured Date"),
            ("Expiry Date", "Enter Expiry Date"),
            ("Price", "Enter Price"),
            ("Quantity", "Enter Quantity")
        ]

        self.add_entries = {}
        for field, placeholder in fields:
            frame = ctk.CTkFrame(panel)
            frame.pack(fill='x', padx=10, pady=5, expand=True)

            label = ctk.CTkLabel(frame, text=field, font=("Arial", 14))
            label.pack(side='left', padx=5)

            if field == 'Form of Medicine':
                combobox = ctk.CTkComboBox(
                    frame,
                    values=["Tablet", "Capsule", "Syrup", "Injection", "Cream", "Ointment", "Gel", "Inhaler", "Patch", "Drops", "Suppository", "IV Fluid"],
                    state='readonly'
                )
                combobox.pack(side='right', fill='x', expand=True, padx=5)
                self.add_entries[field] = combobox
            elif field in ['Manufactured Date', 'Expiry Date']:
                mydate = tb.DateEntry(frame, bootstyle='danger', dateformat='%d-%m-%Y')
                mydate.pack(side='right', fill='x', expand=True, padx=5)
                self.add_entries[field] = mydate
            else:
                entry = ctk.CTkEntry(frame, placeholder_text=placeholder, font=("Arial", 14))
                entry.pack(side='right', fill='x', expand=True, padx=5)
                self.add_entries[field] = entry

        # Submit button
        ctk.CTkButton(panel, text="Submit", font=("Arial", 16), fg_color="green", command=self.add_medicine).pack(fill='x', padx=10, pady=10)

        return panel

    def add_medicine(self):
        """Add a new medicine to the database."""
        try:
            values = {
                "name": self.add_entries["Name"].get(),
                "batch_no": self.add_entries["Batch No"].get(),
                "form": self.add_entries["Form of Medicine"].get(),
                "manufactured_date": self.add_entries["Manufactured Date"].get(),
                "expiry_date": self.add_entries["Expiry Date"].get(),
                "price": float(self.add_entries["Price"].get()),
                "quantity": int(self.add_entries["Quantity"].get())
            }

            if all(values.values()):  # Ensure all fields are filled
                self.db.add_medicine(**values)  # Add to database
                self.load_data()  # Refresh Treeview
            else:
                print("All fields are required!")
        except Exception as e:
            print(f"Error adding medicine: {e}")

    def load_data(self):
        """Fetch medicine records and update the treeview table."""
        for row in self.tree.get_children():
            self.tree.delete(row)  # Clear existing data

        records = self.db.fetch_medicines()  # Fetch data from the database
        for record in records:
            self.tree.insert("", "end", values=record)  # Insert into Treeview

    def search_medicine(self):
        """Search for medicines by name or batch number."""
        search_term = self.search_entry.get()**strong text**
        if search_term:
            records = self.db.search_medicine(search_term)
            self.load_data()  # Refresh Treeview with search results
        else:
            self.load_data()  # Reload all medicines if search term is empty

database.py

import sqlite3

class Database:
    def __init__(self, db_name='inventory.db'):
        self.conn = sqlite3.connect(db_name)
        self.cursor = self.conn.cursor()
        self.create_table()

    def create_table(self):
        self.cursor.execute(
            '''CREATE TABLE IF NOT EXISTS MEDICINES (
                ID INTEGER PRIMARY KEY AUTOINCREMENT,
                NAME TEXT NOT NULL,
                BATCH_NO TEXT NOT NULL,
                FORM TEXT NOT NULL,
                MANUFACTURED_DATE TEXT,
                EXPIRY_DATE TEXT NOT NULL,
                PRICE REAL,
                QUANTITY INTEGER
            )'''
        )
        self.conn.commit()

    def add_medicine(self, name, batch_no, form, manufactured_date, expiry_date, price, quantity):
        self.cursor.execute('''INSERT INTO MEDICINES (NAME, BATCH_NO, FORM, MANUFACTURED_DATE, EXPIRY_DATE, PRICE, QUANTITY)
                              VALUES (?, ?, ?, ?, ?, ?, ?)''',
                           (name, batch_no, form, manufactured_date, expiry_date, price, quantity))
        self.conn.commit()

    def fetch_medicines(self):
        self.cursor.execute('SELECT * FROM MEDICINES')
        return self.cursor.fetchall()

    def update_medicine(self, med_id, name, batch_no, form, manufactured_date, expiry_date, price, quantity):
        self.cursor.execute('''UPDATE MEDICINES 
                              SET NAME = ?, BATCH_NO = ?, FORM = ?, 
                                  MANUFACTURED_DATE = ?, EXPIRY_DATE = ?, 
                                  PRICE = ?, QUANTITY = ? 
                              WHERE ID = ?''', 
                           (name, batch_no, form, manufactured_date, expiry_date, price, quantity, med_id))
        self.conn.commit()

    def delete_medicine(self, med_id):
        self.cursor.execute('DELETE FROM MEDICINES WHERE ID = ?', (med_id,))
        self.conn.commit()

    def search_medicine(self, search_term):
        self.cursor.execute('''SELECT * FROM MEDICINES 
                              WHERE NAME LIKE ? OR BATCH_NO LIKE ?''', 
                           ('%' + search_term + '%', '%' + search_term + '%'))
        return self.cursor.fetchall()

    def close(self):
        self.conn.close()

You’ll have to provide some more information I think

yes, please ask me, shall i send provide all the files?! but how?! I am new to this forum, please help me

What do you need help with?

Try to explain with words what the problem is, what you’ve tried, etc.

I tried integrating the gui add, modify, update, delete operations with the database (sqlite3), which throws import errors…

You get errors? That’s good to know.

I wonder what the errors are? :thinking:

uhm, i wish i could share the files, so you could check it?! but how do I?

uhm, hey, you there?! please respond

I guess I’ll never know

oh, uhm, i did clear most of the errors, but still, some other errors are found now:

Database connection successful!
Traceback (most recent call last):
File “c:\Users\priya\Desktop\IMS\Pharmacy_Inventory\main.py”, line 49, in
db.close()
File “c:\Users\priya\Desktop\IMS\Pharmacy_Inventory\database.py”, line 54, in close
self.conn.close()
^^^^^^^^^
AttributeError: ‘Database’ object has no attribute ‘conn’

I’ve shared you the errors, uhm, is it possible to clear it all?! can we?!

I’ve edited your code for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (').

1 Like

where are you using this attribute conn?

NEVERMIND, THANK YOU SO MUCH FOR HELPING! I GOT IT SOLVED NOW :slight_smile:

1 Like