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()