Document 1
Document 1
1
2
TABLE OF CONTENTS
2
3
CERTIFICATE
This is to certify that Ranveer Goda
of Class XII, Air Force School Jorhat,
has successfully completed the
Informatics Practices project titled
Restaurant Management System
during the academic session 2024-
25. This project has been submitted
in partial fulfillment of the
requirements for the Central Board
of Secondary Education AISSC
Examination 2025.
I further certify that the project has
been evaluated and is up to my
expectations and it adheres to the
guidelines provided by CBSE.
INTERNAL EXTERNAL
EXAMINER EXAMINER
3
4
Date :
PRINCIPAL
4
5
DECLARATION
I, Ranveer Goda hereby declare that I
own the full responsibility for the all the
information and results provided in the
project titled - “Restaurant
Management System”. It has been
developed successfully by using data
handling concepts like data
management, data visualization, etc.
provided in python programming
language and along with its required
libraries such as Pandas, NumPy,
SQLAlchemy, MySQL Connector, etc. at
AIR FORCE SCHOOL JORHAT in complete
fulfillment of project (curriculum of
Central Board of Secondary Education
CBSE of Informatics Practices conducted
by CBSE) for the academic session 2024-
25.
I also hereby declare that this project
work has neither been submitted to any
other board nor published at any time by
me in the past.
5
6
Ranveer Goda
Roll No.
Class XII
AIR FORCE SCHOOL
JORHAT
6
7
ACKNOWLEDGEMENT
7
8
INTRODUCTION
The “Restaurant Management
System” is a comprehensive software
solution designed to streamline and
optimize the financial operations of
restaurant businesses. This system
automates payment processes, tracks
transactions, generates detailed
receipts, and maintains an extensive
record of customer orders and financial
history.
By simplifying financial and operational
processes, it minimizes administrative
workload, ensures accuracy in
transactions, and fosters clear
communication between the
management and customers. The
“Restaurant Management System”
plays a crucial role in enhancing the
operational efficiency of restaurants,
promoting accountability and ensuring a
smooth management experience.
Additionally, the “Restaurant
Management System”is designed with
an intuitive and user-friendly interface
tailored for both restaurant staff and
8
9
9
10
PROBLEM STATEMENT
10
11
11
12
OBJECTIVE
The objective of the project is to build an application
program to:
Facilitate accurate tracking of financial transactions,
ensuring timely payments and minimizing the risk of
discrepancies in restaurant operations.
Provide reporting tools and analytics to help
administrators analyze sales trends, revenue data, and
customer preferences.
Offer a robust search facility based on various factors,
such as order details, transaction history, and customer
data.
Reduce paperwork and manual labor by automating
essential tasks such as billing, order management, and
report generation.
Enhance transparency in financial and operational
transactions for both staff and customers.
Ensure increased accuracy and reliability of operational
data through automated processes.
Promote data consistency across various operational
workflows.
Strengthen financial and operational data security to
safeguard sensitive information.
Minimize data redundancy by integrating and managing
information efficiently within the system.
12
13
13
14
OVERVIEW OF PYTHON
Python is a general purpose, dynamic, high-
level, and interpreted programming
language. It supports Object-Oriented
Programming approach to developed
applications. It is simple and easy to learn
and provides lots of high- level data
structures. Guido Van Rossum is known as
the founder of Python programming.
Features of Python:
14
15
15
16
OVERVIEW OF MYSQL
MySQL is a relational database
management system (RDBMS). It is
pronounced as “My Sequel”. MySQL was
originally founded and developed in
Sweden by David Axmark, Allan Larsson
and Michael Widenius, who had worked
together since the 1980s.
Characteristics of MySQL:
MySQL is released under an open-
source license, so it is customizable.
It requires no cost or payment for its
usage.
MySQL has superior speed, is easy to
use and is reliable.
MySQL uses a standard form of the
well-known ANSI-SQL standards.
MySQL is a platform independent
application which works on many
operating systems like Windows,
UNIX, LINUX, etc. and has
compatibility with many languages
including JAVA, C++, PHP, PERL, etc.
MySQL is an easy to install RDBMS
and is capable of handling large data
sets. Since MySQL is released under
any open-source license, it does not
16
17
17
18
PROJECT SCOPE
The Restaurant Management System project aims to
revolutionize and streamline restaurant operations by
automating key processes and improving efficiency. The
application offers the following scope:
18
19
1. Title: Restaurant Management System using Python, Pandas, Matplotlib, and MySQL
2. Objective:
The aim of this project is to create a Restaurant Management System that allows users to
manage restaurant operations, including order management, menu display, billing, and sales
reporting. This project will utilize Python for the core logic and interface, Pandas for
handling data manipulation, Matplotlib for generating visual reports, and MySQL as the
database for storing information such as menu items, orders, and sales.
3. Project Description:
4. Technology Tools:
5. Features:
Menu Display: The user can view the available dishes with prices and categories.
Order Placement: Customers can place orders by selecting items from the menu.
Billing System: A bill is generated after placing an order, calculating the total with
taxes.
19
20
Admin Panel: The admin can manage the menu (add, remove, or update items) and
view sales data.
Sales Reports: Using Matplotlib, the admin can generate sales reports, including total
revenue, most ordered items, and daily/weekly sales trends.
6. Functional Requirements:
User Functions:
o View menu items with details (price, category)
o Place orders by selecting items
o View the bill with itemized details and total cost
Admin Functions:
o Add new menu items
o Remove or update existing menu items
o View sales reports (total orders, revenue, top-selling items) through graphical
representations
7. Non-Functional Requirements:
Performance: The system must quickly process orders and handle multiple
transactions without delay.
Security: Admin access to menu updates and sales reports must be restricted.
User Experience: The interface should be easy to navigate, providing clear menu-
driven options.
1. Main Menu:
View Menu
o Display all available dishes along with their prices and categories
(e.g., appetizers, main courses, desserts, drinks).
Place Order
o Select items from the menu by item ID
o Enter quantity for each item
o Display the order summary
Generate Bill
o Display the final bill with a breakdown of items, quantity, individual prices,
and total cost including tax.
Admin Login
o Enter admin credentials to access the admin menu.
Generate Report
Data Visualisation
Export/Import Data
User & Password Management
Exit
2. Admin Menu:
20
21
1. Table: menu_items
Column
Data Type Constraints Description
Name
PRIMARY KEY, Unique ID for each menu
item_id INT
AUTO_INCREMENT item.
item_name VARCHAR(100) NOT NULL Name of the dish.
The category of the dish (e.g.,
category VARCHAR(50) NOT NULL
appetizer, main course).
DECIMAL(10,
price NOT NULL Price of the dish.
2)
Indicates if the item is
available BOOLEAN DEFAULT 1
available.
2. Table: orders
Column
Data Type Constraints Description
Name
PRIMARY KEY,
order_id INT Unique ID for each order.
AUTO_INCREMENT
Date and time when the
order_date DATETIME NOT NULL
order was placed.
Contact Number of a
Mobile CHAR(10) NOT NULL
Customer
Total amount for the
total_amount DECIMAL(10, 2) NOT NULL
order.
21
22
3. Table: order_items
This table stores individual items within each order, representing the many-to-many
relationship between orders and menu items.
4. Table: sales_reports
Column
Data Type Constraints Description
Name
PRIMARY KEY, Unique ID for each
report_id INT
AUTO_INCREMENT report.
report_date DATE NOT NULL Date of the report.
DECIMAL(10, Total revenue for the
total_sales NOT NULL
2) day.
Total number of orders
total_orders INT NOT NULL
for the day.
Menu DataFrame: Pandas will be used to create and manipulate a menu DataFrame,
which can be queried and filtered by category, price, and availability.
Orders DataFrame: An orders DataFrame will be used to store orders temporarily
before committing them to the database, and to perform quick analyses (e.g., total
revenue per customer).
Sales Reports: Daily sales data will be stored in a Pandas DataFrame, allowing for
easy analysis and visualization using Matplotlib.
22
23
Conclusion:
23
24
PYTHON
MODULES
import pandas as pd
import mysql.connector
from datetime import datetime
from tabulate import tabulate
import matplotlib.pyplot as plt
24
25
Restaurant Management
System (PYTHON)
import pandas as pd
import mysql.connector
from datetime import datetime
from tabulate import tabulate
import matplotlib.pyplot as plt
elif userinput=="4":
print("-->>Exiting...")
break
else:
print(" Invalid Option!")
#Place Orders:
def place_order():
print(" Placing an Order...")
mobile_no = input(" >>Enter Your Mobile no. :")
order_details = []
order_total = 0
mycursor.execute("""
SELECT order_id, total_amount
FROM orders
WHERE mobile = %s AND DATE(order_date) = DATE(NOW())
""", (mobile_no,))
existing_order = mycursor.fetchone()
if existing_order:
last_id = existing_order[0]
order_total = existing_order[1]
else:
mycursor.execute("""
INSERT INTO orders (order_date, mobile, total_amount)
VALUES (NOW(), %s, 0);
""", (mobile_no,))
mydb.commit()
last_id = mycursor.lastrowid
if last_id is None:
print("Error: Failed to retrieve a valid order ID. Please try again.")
1
while True: 2
item_id = int(input(" >>Enter the Item ID to order (or 0 to finish): "))
if item_id == 0:
break
else:
quantity = int(input(" >>Enter Quantity to order :"))
mycursor.execute("SELECT item_name, ROUND(price, 2) FROM
menu_items WHERE item_id = %s and available='yes';", (item_id,))
item = mycursor.fetchone()
if item:
item_name, price = item
total_price = float(price) * quantity
2
#Bill Generation: 3
def generate_bill():
print("\n")
print(" ~~~~~~~~~~~~~~~~~~ ")
print("┍<<-------------->>| ITEMS MENU |<<-------------->>┒ ")
print("| ~~~~~~~~~~~~~~~~~~ | ")
mobileno = int(input("--->>| Enter Mobile no.: "))
if len(str(mobileno)) != 10 :
print("!!| Invalid phone number! It must be a 10-digit number.|!!")
Return
mycursor.execute("SELECT mobile FROM orders WHERE mobile = %s;", (mobileno,))
data = mycursor.fetchall()
while True:
if data:
print(" -------------------------------------- ")
print(" 1. Today's Bill 2. Previous Bill ")
print(" 3. Exit")
userinput = input("--->>| Enter Your choice : ")
# Define the common query to fetch bill details for today's or previous orders
if userinput == "1":
query = """
SELECT m.item_name, o.quantity, m.price, o.total_price, DATE(r.order_date)
FROM order_items o
JOIN orders r ON r.order_id = o.order_id
JOIN menu_items m ON m.item_id = o.item_id
WHERE r.mobile = %s
AND DATE(r.order_date) = CURDATE();
"""
total_query = """
SELECT SUM(total_price)
FROM order_items o
JOIN orders r ON r.order_id = o.order_id
WHERE r.mobile = %s AND DATE(r.order_date) = CURDATE();
"""
elif userinput == "2":
query = """
SELECT m.item_name, o.quantity, m.price, o.total_price, DATE(r.order_date)
FROM order_items o
JOIN orders r ON r.order_id = o.order_id
JOIN menu_items m ON m.item_id = o.item_id
WHERE r.mobile = %s
AND DATE(r.order_date) < CURDATE();
"""
total_query = """
SELECT SUM(total_price)
FROM order_items o
JOIN orders r ON r.order_id = o.order_id
WHERE r.mobile = %s AND DATE(r.order_date) < CURDATE();
"""
elif userinput=="3":
print(" Exiting Bill Generation...")
break
else:
print(" Invalid Choice. Try again later")
return
mycursor.execute(query, (mobileno,))
bill = mycursor.fetchall()
if bill:
mycursor.execute(total_query, (mobileno,))
subtotal = mycursor.fetchone()[0]
3
if subtotal is not None: 4
gst_amt = subtotal * 5 / 100 # Standard GST imposed on billing: 5%
subtotal += gst_amt # Total amount after GST
# Get the current date
mycursor.execute("SELECT DATE(NOW());")
current_date = mycursor.fetchone()[0]
formatted_date = current_date.strftime("%d-%m-%Y")
print("-------- TAX INVOICE ---------")
print("\nDate:", formatted_date)
# Print the bill summary
print(tabulate(bill, headers=['Particulars', 'Qty', 'Rate', 'Amount',
'Order date'], tablefmt='plain'))
print(' ---------------------')
print(" Sub Total: ₹", subtotal - gst_amt)
print(" GST @5%: ₹", gst_amt)
print("----------------------------------------------")
print(f" Total amount : ₹{subtotal}\n")
else:
print("No orders found for the selected date range")
else:
print("No orders found for this mobile number.")
else:
print("No orders found for this mobile number.") # This is the fallback if
no data is returned
break
def add_item():
print("Adding new Menu item...")
category=input("Enter the category to be entered :")
item_name=input("Enter Item Name :")
description=input("Enter Description :")
price=float(input("Enter Item Price :"))
item_type=input("Is This Item Vegetarian? (yes/no) :")
availability="Yes" #default to available
#item_type=item_type.lower()
if price<=0:
print("Price cannot be zero or negative.")
if item_type.lower()=='yes':
item_type='VEG'
elif item_type.lower()=='no':
item_type='NON VEG'
else:
print('Invalid Choice.try again later')
4
#defining updatation of item 5
def update_menu():
item_id=input("\nEnter Item Id to be updated :")
mycursor.execute("Select *from menu_items where item_id= %s", (item_id,))
check1= mycursor.fetchone()
if check1:
print("\nWhat Do You want to Update")
print("\n1.Category")
print("2.Price")
print("3.Availability")
userinput=input("Select an Option :")
if userinput=="1":
category=input("Enter new category :")
query="Select*from menu_items where item_id=%s;"
val=(item_id,)
mycursor.execute(query,val)
data=mycursor.fetchone()
header=['Item_Id','Category','Item_Name','Description','Price(₹)','Available']
print(tabulate([data],header,tablefmt='pretty'))
print("\nIs The data inserted correct.(yes/no): ")
choice=input("Enter a Choice: ")
if choice.lower()=='yes':
query="update menu_items set category=%s where item_id=%s;"
val=(category,item_id)
mycursor.execute(query,val)
mydb.commit()
print("Updatation Completed...")
elif choice.lower()=='no':
update_menu()
else:
print("Not a valid Option!")
admin_menu()
elif userinput=="2":
price=int(input("Enter New Price :"))
query="Select*from menu_items where item_id=%s;"
val=(item_id,)
mycursor.execute(query,val)
data=mycursor.fetchone()
header=['Item_Id','Category','Item_Name','Description','Price(₹)','Available']
print(tabulate([data],header,tablefmt='pretty'))
print("\nIs The data inserted correct.(yes/no): ")
choice=input("Enter a Choice: ")
if choice.lower()=='yes' and price>0:
query="update menu_items set price=%s where item_id=%s;"
val=(price,item_id)
mycursor.execute(query,val)
mydb.commit()
print("Updatation Completed...")
elif choice.lower()=='no':
update_menu()
else:
print("Price Cannot be Zero or Negative")
5
elif userinput=="3":
availability=input("Is it Available? (yes/no)6 :")
query="Select*from menu_items where item_id=%s;"
val=(item_id,)
mycursor.execute(query,val)
data=mycursor.fetchone()
header=['Item_Id','Category','Item_Name','Description','Price(₹)','Available']
print(tabulate([data],header,tablefmt='pretty'))
print("\nIs The data inserted correct.(yes/no): ")
choice=input("Enter a Choice: ")
if choice.lower()=='yes' and availability.lower()=='yes':
query="update menu_items set available='yes' where item_id=%s;"
val=(item_id,)
mycursor.execute(query,val)
mydb.commit()
print("\nUpdatation Completed...")
elif choice.lower()=='yes' and availability.lower()=='no':
query="update menu_items set available='no' where item_id=%s;"
val=(item_id,)
mycursor.execute(query,val)
mydb.commit()
print("\nUpdatation Completed...")
elif choice.lower()=='no':
update_menu()
else:
print("Invalid choice!!")
else:
print("Invalid Option!!")
else:
print("Invalid Item Id ...")
def weekly_orders():
query="""select year(report_date) as sale_year,week(report_date) as
sale_week,
sum(total_orders) as total_orders
from sales_reports
GROUP BY sale_year, sale_week
order by sale_year,sale_week;"""
mycursor.execute(query)
weekly_orders = mycursor.fetchall()
if weekly_orders:
col = ['Sale_Year', 'Sale_Week', 'Total_Orders']
d_sales = pd.DataFrame(weekly_orders, columns=col)
d_sales['Total_Orders'] = pd.to_numeric(d_sales['Total_Orders'])
sale_dates = []
for i in range(len(d_sales)):
year = d_sales.loc[i, 'Sale_Year']
week = d_sales.loc[i, 'Sale_Week']
sale_date = datetime.strptime(f"{year}-W{week}-1", "%Y-W%U-%w")
sale_dates.append(sale_date)
7
d_sales['Sale_Date'] = sale_dates
d_sales['Sale_Date_Str'] = d_sales['Sale_Date'].dt.strftime('Week
8
%U-%b-%Y')
print(tabulate(d_sales[['Sale_Date_Str', 'Total_Orders']],
headers=['Sale Date', 'Total Orders'], tablefmt='pretty'))
print("\n")
d_sales.plot(x='Sale_Date_Str', y='Total_Orders', kind='bar',
color='skyblue', linewidth=2, rot=30)
plt.title('Weekly Orders')
plt.xlabel('Sale Date')
plt.ylabel('Total Orders')
plt.show()
else:
print("No Weekly order Record")
def monthly_sales():
query="""select year(report_date) as
sale_year,MONTH(report_date) as sale_month,
sum(total_sales) as total_sales
from sales_reports
GROUP BY sale_year, sale_month
order by sale_year,sale_month;"""
mycursor.execute(query)
monthly_sales=mycursor.fetchall()
if monthly_sales:
col = ['Sale_Year', 'Sale_Month', 'Total_Sales']
d_sales = pd.DataFrame(monthly_sales, columns=col)
d_sales['Total_Sales'] = pd.to_numeric(d_sales['Total_Sales'])
sale_dates = []
for i in range(len(d_sales)):
year = d_sales.loc[i, 'Sale_Year']
month = d_sales.loc[i, 'Sale_Month']
sale_date = datetime.strptime(f"{year}-{month}-1","%Y-%m-
%d")
sale_dates.append(sale_date)
d_sales['Sale_Date'] = sale_dates
d_sales['Sale_Date_Str'] = d_sales['Sale_Date'].dt.strftime('%b-
%Y' )
print(tabulate(d_sales[['Sale_Date_Str', 'Total_Sales']],
headers=['Sale Date', 'Total Sales'], tablefmt='pretty'))
print("\n")
d_sales.plot(x='Sale_Date_Str', y='Total_Sales', kind='bar',
color='skyblue', linewidth=2, rot=45)
plt.title('Monthly Sales')
plt.xlabel('Sales Date')
plt.ylabel('Total Sales(₹)')
plt.show()
else: 8
print("No Monthly Sales Record ")
#Monthly Orders Plot: 9
def monthly_orders():
query="""select Year(report_date) as sale_year,month(report_date)
as sale_month,
sum(total_orders) as total_orders
from sales_reports
GROUP BY sale_year, sale_month
order by sale_year,sale_month;"""
mycursor.execute(query)
monthly_orders = mycursor.fetchall()
if monthly_orders:
col = ['Sale_Year', 'Sale_Month', 'Total_Orders']
d_sales = pd.DataFrame(monthly_orders, columns=col)
d_sales['Total_Orders'] = pd.to_numeric(d_sales['Total_Orders'])
sale_dates = []
for i in range(len(d_sales)):
year = d_sales.loc[i, 'Sale_Year']
month = d_sales.loc[i, 'Sale_Month']
sale_date = datetime.strptime(f"{year}-{month}-1","%Y-%m-
%d")
sale_dates.append(sale_date)
d_sales['Sale_Date'] = sale_dates
d_sales['Sale_Date_Str'] = d_sales['Sale_Date'].dt.strftime('%b-
%Y' )
print(tabulate(d_sales[['Sale_Date_Str', 'Total_Orders']],
headers=['Sale Date', 'Total Sales'], tablefmt='pretty'))
print("\n")
d_sales.plot(x='Sale_Date_Str', y='Total_Orders', kind='bar',
color='skyblue', linewidth=2, rot=45)
plt.title('Monthly Orders')
plt.xlabel('Sales Date')
plt.ylabel('Total Orders')
plt.show()
else:
print("No Monthly Order Record")
def most_ordered():
query="SELECT m.item_name as name,\
sum(quantity) as total_Quantity\
from menu_items m,order_items o\
where m.item_id=o.item_id\
group by m.item_id;"
mycursor.execute(query)
data=mycursor.fetchall()
if data:
col=['Item_Name','Quantity_ordered']
df=pd.DataFrame(data,columns=col)
9
plt.pie(df['Quantity_ordered'],labels=df['Item_Name'],autopct='%1.1f
10
%%',shadow=True,startangle=160,
textprops={'fontsize': 7,'weight':'bold'},
wedgeprops={'linewidth': 1, 'edgecolor': 'white'})
plt.title("Total Quantity Ordered for Each Item")
plt.show()
else:
print("No Data Found")
#Average Revenue:
def Avg_revenue():
query="select
count(order_item_id),sum(total_price),round(avg(total_price))
Average from order_items;"
mycursor.execute(query)
AVG=mycursor.fetchone()
if AVG:
print(f"Average Revenue Per Customer is:₹{AVG}")
print(">> Details:")
print(tabulate([AVG],headers=['Total_orders','Total_Sales','Average
Revenue'],tablefmt='pretty'))
else:
print("No Data Found")
#Prime Hours:
def Prime_hours():
query="SELECT HOUR(order_date) AS Hour,\
COUNT(order_id) AS total_orders\
FROM orders\
group by HOUR(order_date)\
order by Hour;"
mycursor.execute(query)
Hours=mycursor.fetchall()
if Hours:
header=['Prime Hours','Total orders']
print(tabulate(Hours,headers=header,tablefmt='pretty'))
10
for i in range(len(df)): 11
df.loc[i, 'Prime Hours'] = str(df.loc[i, 'Prime Hours']) + " O'
Clock"
df.plot(x='Prime Hours',y='Total
orders',kind='bar',linewidth=2,rot=0)
plt.title('Prime Hours and Total Orders')
plt.xlabel('Total Orders Orders')
plt.ylabel('Hours')
plt.show()
else:
print("NO DATA FOUND")
def report_menu():
while True:
print("\n")
print("
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ")
print("┍<<--------->>| REPORT MANAGEMENT MENU |<<--------
>>┒ ")
print("|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ")
print("| 1. Sales Report 2. Orders Report | ")
print("| 3. Revenue per customer 4. Prime Hours report |
")
print("| 5. Exit |\n ")
userinput=input("\n--->>| Enter your Selection: ")
if userinput=="1":
print("<<--->>| Sales Menu |<<--->>")
Sales_report_menu()
elif userinput=="2":
print("<<--->>| Orders Menu |<<--->>")
Orders_report_menu()
elif userinput=="3":
print("<<--->>| Average Revenue |<<--->>")
Avg_revenue()
elif userinput=="4":
Prime_hours()
elif userinput=="5":
print("\nExiting Report Menu...")
break
else:
print("\nInvalid selection")
#Admin Login
def Admin_login():
username=input(" >>Enter Username :")
password=input(" >>Enter Password :")
if username=='abc' and password=='abc123':
print("Login successfull")
admin_menu()
else:
print("\nInvalid credentials. Access denied.")
12
#Admin menu: 13
def admin_menu():
while True:
print("\n")
print(" ~~~~~~~~~~~~~~~~~~~~ ")
print("┍<<----------->>| Admin Menu |<<----------->>┒ ")
print("| ~~~~~~~~~~~~~~~~~~~~ | ")
print("| 1. View Menu 2.Add Menu Item | ")
print("| 3. Update Menu Item 4. Delete Menu Item | ")
print("| 5. View Sales Reports 6.Exit Admin Menu | ")
userinput=input("--->>| Select an Option :")
if userinput=="1":
menu_items()
elif userinput=="2":
add_item()
elif userinput=="3":
update_menu()
elif userinput=="4":
remove_item()
elif userinput=="5":
report_menu()
elif userinput=="6":
break
else:
print('Invalid Option')
13
elif userinput=="4": 14
Admin_login() #Function for Admin
menu(Restricted)
elif userinput=="5":
print("Exiting The System...")
break
else:
print("Invalid option. Please try again.")
main_menu()
14
15
15
16
16
17
17