How to design a Restaurant Bill using Python Tkinter

by Apr 21, 2020Python Tkinter Examples

In this article, we will learn how to create a restaurant bill management system with python using basic widgets in Tkinter library. If you are new to Tkinter library I recommend you go through this first because without a basic understanding of these widgets which we are going to use in this article it is difficult to analyze and understand it. Also, you can check out the official documentation for the Tkinter library here.

contents:

  1. Introduction
  2. Generating your bill
  3. Saving your bill via text file
  4. Emailing your bill
  5. Final code

Introduction

This article is we will learn how to create a restaurant bill inform of a text file and send it to the client.

There are three basic steps of this project

  1. First, generate your bill
  2. Save your bill as a. text file
  3. Send your bill to your client via email

Let us dive into the first step if the process -generating the bill


Generating the bill

There are many steps involved in the generation of the bill so don’t be scared by the size of code but try to understand and analyze the code.

from Tkinter import *
import time
from random import randint
root = Tk()
root.geometry("1150x700+0+0")
root.title("Restaurant Billing System")
Tops = Frame(root, width=1350, height=50, bd=8,bg='blue', relief="raise")
Tops.pack(side=TOP)
Bottoms = Frame(root, width=1350, height=50, bd=8, relief="raise")
Bottoms.pack(side=BOTTOM)
f1 = Frame(root, width=900, height=650, bd=8, relief="raise")
f1.pack(side=LEFT)
f1a = Frame(f1, width=900, height=330, bd=8, relief="raise")
f1a.pack(side=TOP)
f2a = Frame(f1, width=900, height=320, bd=8, relief="raise")
f2a.pack(side=BOTTOM)
f1aa = Frame(f1a, width=400, height=430, bd=8, relief="raise")
f1aa.pack(side=LEFT)
f1ab = Frame(f1a, width=400, height=430, bd=8, relief="raise")
f1ab.pack(side=RIGHT)
f2aa = Frame(f2a, width=450, height=330, bd=8, relief="raise")
f2aa.pack(side=LEFT)
f2ab = Frame(f2a, width=450, height=330, bd=8, relief="raise")
f2ab.pack(side=LEFT)
#f2 = Frame(root, width=440, height=650, bd=8, relief="raise")
#f2.pack(side=BOTTOM)
lblInfo = Label(Tops, font=('arial', 25, 'bold'), text="Restaurant Billing System", bd=10, anchor='w')
lblInfo.grid(row=0, column=0)
# ==============================Variables=====================
PaymentRef = StringVar()
idly = StringVar()
biryani = StringVar()
paneer_butter_masala = StringVar()
nimbu_pani = StringVar()
costidly = StringVar()
costbiryani = StringVar()
costpaneer_butter_masala = StringVar()
costnimbu_pani = StringVar()
dateRef = StringVar()
subTotal = StringVar()
vat = StringVar()
totalPrice = StringVar()
text_Input = StringVar()
dateRef.set(time.strftime("%d/%m/%y"))
operator = ""
vat.set(0)
idly.set(0)
biryani.set(0)
paneer_butter_masala.set(0)
nimbu_pani.set(0)
subTotal.set(0)
totalPrice.set(0)
costidly.set(30)
costbiryani.set(180)
costnimbu_pani.set(20)
costpaneer_butter_masala.set(180)
# =============================Functions==================
def tPrice():
    cBprice = int(costidly.get())
    bBprice = int(costbiryani.get())
    fFprice = int(costpaneer_butter_masala.get())
    sDprice = int(costnimbu_pani.get())
    cBno = int(idly.get())
    bBno = int(biryani.get())
    fFno = int(paneer_butter_masala.get())
    sDno = int(nimbu_pani.get())
    tempVat = int(vat.get())
    subPrice = (cBprice * cBno + bBprice * bBno + fFprice * fFno + sDprice * sDno)
    totalCost = str('%d' % subPrice)
    totalCostwithVat = str('%d' % (subPrice + (subPrice * tempVat) / 100))
    subTotal.set(totalCost)
    totalPrice.set(totalCostwithVat)
def iExit():
    qexit = messagebox.askyesno("Billing System", "Do you want to exit?")
    if qexit > 0:
        root.destroy()
        return
def reset():
    global x
    x = x + 1
    PaymentRef.set("")
    idly.set(0)
    biryani.set(0)
    paneer_butter_masala.set(0)
    nimbu_pani.set(0)
    subTotal.set(0)
    totalPrice.set(0)
def refNo():
    global x
    y = str(x)
    randomRef = str(y)
    PaymentRef.set("BILL" + randomRef)
def btnClearDisplay():
    global operator
    operator = ""
    text_Input.set("")
def btnEqualsInput():
    global operator
    sumup = str(eval(operator))
    text_Input.set(sumup)
    operator = ""
# ==================================Order Info===========================
lblRef = Label(f1aa, font=('arial', 16, 'bold'), fg="red", text="Reference No", bd=16, justify='left')
lblRef.grid(row=0, column=0)
txtRef = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=PaymentRef, bd=10, insertwidth=2, justify='left')
txtRef.grid(row=0, column=1)
# --------------
lblCb = Label(f1aa, font=('arial', 16, 'bold'), text="Idly", bd=16, justify='left')
lblCb.grid(row=1, column=0)
txtCb = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=idly, bd=10, insertwidth=2, justify='left')
txtCb.grid(row=1, column=1)
# --------------
lblBb = Label(f1aa, font=('arial', 16, 'bold'), text="Biryani", bd=16, justify='left')
lblBb.grid(row=2, column=0)
txtBb = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=biryani, bd=10, insertwidth=2, justify='left')
txtBb.grid(row=2, column=1)
# --------------
lblFf = Label(f1aa, font=('arial', 16, 'bold'), text="Paneer butter masala", bd=16, justify='left')
lblFf.grid(row=3, column=0)
txtFf = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=paneer_butter_masala, bd=10, insertwidth=2, justify='left')
txtFf.grid(row=3, column=1)
# --------------
lblSd = Label(f1aa, font=('arial', 16, 'bold'), text="Nimbu pani", bd=16, justify='left')
lblSd.grid(row=4, column=0)
txtSd = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=nimbu_pani, bd=10, insertwidth=2, justify='left')
txtSd.grid(row=4, column=1)
# ===================================Payment Info==========================
lbldate = Label(f1ab, font=('arial', 16, 'bold'), text="Date", bd=16, justify='left')
lbldate.grid(row=0, column=0)
txtdate = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=dateRef, bd=10, insertwidth=2, justify='left')
txtdate.grid(row=0, column=1)
# --------------
lblCcb = Label(f1ab, font=('arial', 16, 'bold'), text="Price of Idly", bd=16, justify='left')
lblCcb.grid(row=1, column=0)
txtCcb = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=costidly, bd=10, insertwidth=2, justify='left')
txtCcb.grid(row=1, column=1)
# --------------
lblCbb = Label(f1ab, font=('arial', 16, 'bold'), text="Price of Biryani", bd=16, justify='left')
lblCbb.grid(row=2, column=0)
txtCbb = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=costbiryani, bd=10, insertwidth=2, justify='left')
txtCbb.grid(row=2, column=1)
# --------------
lblCff = Label(f1ab, font=('arial', 16, 'bold'), text="Price of Paneer butter masala", bd=16, justify='left')
lblCff.grid(row=3, column=0)
txtCff = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=costpaneer_butter_masala, bd=10, insertwidth=2,
               justify='left')
txtCff.grid(row=3, column=1)
# --------------
lblCsd = Label(f1ab, font=('arial', 16, 'bold'), text="Price of Nimbu pani", bd=16, justify='left')
lblCsd.grid(row=4, column=0)
txtCsd = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=costnimbu_pani, bd=10, insertwidth=2, justify='left')
txtCsd.grid(row=4, column=1)
# ==========================Total Payment Info======
lblPrice = Label(f2aa, font=('arial', 16, 'bold'), text="Price", bd=16, justify='left')
lblPrice.grid(row=0, column=0)
txtPrice = Entry(f2aa, font=('arial', 16, 'bold'), textvariable=subTotal, bd=10, insertwidth=2, justify='left')
txtPrice.grid(row=0, column=1)
# --------------
lblVat = Label(f2aa, font=('arial', 16, 'bold'), text="VAT", bd=16, justify='left')
lblVat.grid(row=1, column=0)
txtVat = Entry(f2aa, font=('arial', 16, 'bold'), textvariable=vat, bd=10, insertwidth=2, justify='left')
txtVat.grid(row=1, column=1)
# --------------
lblTp = Label(f2aa, font=('arial', 16, 'bold'), text="Total Price", bd=16, justify='left')
lblTp.grid(row=2, column=0)
txtTp = Entry(f2aa, font=('arial', 16, 'bold'), textvariable=totalPrice, bd=10, insertwidth=2, justify='left')
txtTp.grid(row=2, column=1)
#updatelabel=Label(Bottoms,font=('arial',16,'bold'),text="Total Price")
#updatelabel.pack(fill='both' )
# ==============Buttons==========
btnTotal = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=15,
                  text="Total Price", command=tPrice).grid(row=0, column=1)
btnRefer = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=15,
                  text="Sales Reference", command=refNo).grid(row=0, column=0)
btnCrtb = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=10,
                 text="Generate bill", command=create_bill).grid(row=0, column=2)
btnReset = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=15,
                  text="Reset", command=reset).grid(row=1, column=0)
btnExit = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=15,
                 text="Exit", command=iExit).grid(row=1, column=1)
btnSndb = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=10,
                 text="Send bill", command=send_bill).grid(row=1, column=2)
root.mainloop()

Importing modules

Ok now let us analyze the code .first importing modules needed tkinter ,time,randint(for bill ref number)

from Tkinter import *
import time
from random import randint

Setting up the window

Next up is setting up the big screen and adding frames to it for our bill for reference check out layout management.

root = Tk()
root.geometry("1150x700+0+0")
root.title("Restaurant Billing System")
Tops = Frame(root, width=1350, height=50, bd=8,bg='blue', relief="raise")
Tops.pack(side=TOP)
Bottoms = Frame(root, width=1350, height=50, bd=8, relief="raise")
Bottoms.pack(side=BOTTOM)
f1 = Frame(root, width=900, height=650, bd=8, relief="raise")
f1.pack(side=LEFT)
f1a = Frame(f1, width=900, height=330, bd=8, relief="raise")
f1a.pack(side=TOP)
f2a = Frame(f1, width=900, height=320, bd=8, relief="raise")
f2a.pack(side=BOTTOM)
f1aa = Frame(f1a, width=400, height=430, bd=8, relief="raise")
f1aa.pack(side=LEFT)
f1ab = Frame(f1a, width=400, height=430, bd=8, relief="raise")
f1ab.pack(side=RIGHT)
f2aa = Frame(f2a, width=450, height=330, bd=8, relief="raise")
f2aa.pack(side=LEFT)
f2ab = Frame(f2a, width=450, height=330, bd=8, relief="raise")
f2ab.pack(side=LEFT)
lblInfo = Label(Tops, font=('arial', 25, 'bold'), text="Restaurant Billing System", bd=10, anchor='w')
lblInfo.grid(row=0, column=0)

Declaring the variables

here I am taking the main window in Tk and put up my frames for my interface to look good. You can also do this without these frames using.grid(). Next up is declaring variables for our bill here you will declare the items in the menu along with the price also lay the foundation for reset buttons.

PaymentRef = StringVar()
idly = StringVar()
biryani = StringVar()
paneer_butter_masala = StringVar()
nimbu_pani = StringVar()
costidly = StringVar()
costbiryani = StringVar()
costpaneer_butter_masala = StringVar()
costnimbu_pani = StringVar()
dateRef = StringVar()
subTotal = StringVar()
vat = StringVar()
totalPrice = StringVar()
text_Input = StringVar()
dateRef.set(time.strftime("%d/%m/%y"))
operator = ""
vat.set(0)
idly.set(0)
biryani.set(0)
paneer_butter_masala.set(0)
nimbu_pani.set(0)
subTotal.set(0)
totalPrice.set(0)
costidly.set(30)
costbiryani.set(180)
costnimbu_pani.set(20)
costpaneer_butter_masala.set(180)

Here the variables are all in strvar() format which means string variables and you can also see. Set functions that set the functions to 0 initially. We can also even set the cost of items in the final part of the code.

Defining the functions

Next is declaring what kind of functions you want to use. An easy trick for declaring functions is the first analyzing what tasks your program needs to perform after that defining the functions.

Idef tPrice():
    cBprice = int(costidly.get())
    bBprice = int(costbiryani.get())
    fFprice = int(costpaneer_butter_masala.get())
    sDprice = int(costnimbu_pani.get())
    cBno = int(idly.get())
    bBno = int(biryani.get())
    fFno = int(paneer_butter_masala.get())
    sDno = int(nimbu_pani.get())
    tempVat = int(vat.get())
    subPrice = (cBprice * cBno + bBprice * bBno + fFprice * fFno + sDprice * sDno)
    totalCost = str('%d' % subPrice)
    totalCostwithVat = str('%d' % (subPrice + (subPrice * tempVat) / 100))
    subTotal.set(totalCost)
    totalPrice.set(totalCostwithVat)
def iExit():
    qexit = messagebox.askyesno("Billing System", "Do you want to exit?")
    if qexit > 0:
        root.destroy()
        return
def reset():
    global x
    x = x + 1
    PaymentRef.set("")
    idly.set(0)
    biryani.set(0)
    paneer_butter_masala.set(0)
    nimbu_pani.set(0)
    subTotal.set(0)
    totalPrice.set(0)
def refNo():
    global x
    y = str(x)
    randomRef = str(y)
    PaymentRef.set("BILL" + randomRef)
def btnClearDisplay():
    global operator
    operator = ""
    text_Input.set("")
def btnEqualsInput():
    global operator
    sumup = str(eval(operator))
    text_Input.set(sumup)
    operator = ""

In the above code i defined 6 functions

  1. we use price for calculating the total price. I used the get() function for calling the values written in the entry boxes. convert them to int for mathematical applications.
  2. The second one is we use I exit to close the window. We use destroy function to do that.
  3. Next up is reset part of the function we are resetting everything so, we use set function for resetting
  4. We use ref no function for generating a random number.
  5. We use The last two functions for mathematical operations.

Arranging the widgets

Here I already used frames so I have to carefully put the widgets in their respective positions.for that I used the grid() method.

lblRef = Label(f1aa, font=('arial', 16, 'bold'), fg="red", text="Reference No", bd=16, justify='left')
lblRef.grid(row=0, column=0)
txtRef = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=PaymentRef, bd=10, insertwidth=2, justify='left')
txtRef.grid(row=0, column=1)
# --------------
lblCb = Label(f1aa, font=('arial', 16, 'bold'), text="Idly", bd=16, justify='left')
lblCb.grid(row=1, column=0)
txtCb = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=idly, bd=10, insertwidth=2, justify='left')
txtCb.grid(row=1, column=1)
# --------------
lblBb = Label(f1aa, font=('arial', 16, 'bold'), text="Biryani", bd=16, justify='left')
lblBb.grid(row=2, column=0)
txtBb = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=biryani, bd=10, insertwidth=2, justify='left')
txtBb.grid(row=2, column=1)
# --------------
lblFf = Label(f1aa, font=('arial', 16, 'bold'), text="Paneer butter masala", bd=16, justify='left')
lblFf.grid(row=3, column=0)
txtFf = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=paneer_butter_masala, bd=10, insertwidth=2, justify='left')
txtFf.grid(row=3, column=1)
# --------------
lblSd = Label(f1aa, font=('arial', 16, 'bold'), text="Nimbu pani", bd=16, justify='left')
lblSd.grid(row=4, column=0)
txtSd = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=nimbu_pani, bd=10, insertwidth=2, justify='left')
txtSd.grid(row=4, column=1)
# ===================================Payment Info==========================
lbldate = Label(f1ab, font=('arial', 16, 'bold'), text="Date", bd=16, justify='left')
lbldate.grid(row=0, column=0)
txtdate = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=dateRef, bd=10, insertwidth=2, justify='left')
txtdate.grid(row=0, column=1)
# --------------
lblCcb = Label(f1ab, font=('arial', 16, 'bold'), text="Price of Idly", bd=16, justify='left')
lblCcb.grid(row=1, column=0)
txtCcb = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=costidly, bd=10, insertwidth=2, justify='left')
txtCcb.grid(row=1, column=1)
# --------------
lblCbb = Label(f1ab, font=('arial', 16, 'bold'), text="Price of Biryani", bd=16, justify='left')
lblCbb.grid(row=2, column=0)
txtCbb = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=costbiryani, bd=10, insertwidth=2, justify='left')
txtCbb.grid(row=2, column=1)
# --------------
lblCff = Label(f1ab, font=('arial', 16, 'bold'), text="Price of Paneer butter masala", bd=16, justify='left')
lblCff.grid(row=3, column=0)
txtCff = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=costpaneer_butter_masala, bd=10, insertwidth=2,
               justify='left')
txtCff.grid(row=3, column=1)
# --------------
lblCsd = Label(f1ab, font=('arial', 16, 'bold'), text="Price of Nimbu pani", bd=16, justify='left')
lblCsd.grid(row=4, column=0)
txtCsd = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=costnimbu_pani, bd=10, insertwidth=2, justify='left')
txtCsd.grid(row=4, column=1)
# ==========================Total Payment Info======
lblPrice = Label(f2aa, font=('arial', 16, 'bold'), text="Price", bd=16, justify='left')
lblPrice.grid(row=0, column=0)
txtPrice = Entry(f2aa, font=('arial', 16, 'bold'), textvariable=subTotal, bd=10, insertwidth=2, justify='left')
txtPrice.grid(row=0, column=1)
# --------------
lblVat = Label(f2aa, font=('arial', 16, 'bold'), text="VAT", bd=16, justify='left')
lblVat.grid(row=1, column=0)
txtVat = Entry(f2aa, font=('arial', 16, 'bold'), textvariable=vat, bd=10, insertwidth=2, justify='left')
txtVat.grid(row=1, column=1)
# --------------
lblTp = Label(f2aa, font=('arial', 16, 'bold'), text="Total Price", bd=16, justify='left')
lblTp.grid(row=2, column=0)
txtTp = Entry(f2aa, font=('arial', 16, 'bold'), textvariable=totalPrice, bd=10, insertwidth=2, justify='left')
txtTp.grid(row=2, column=1)
#updatelabel=Label(Bottoms,font=('arial',16,'bold'),text="Total Price")
#updatelabel.pack(fill='both' )
# ==============Buttons==========
btnTotal = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=15,
                  text="Total Price", command=tPrice).grid(row=0, column=1)
btnRefer = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=15,
                  text="Sales Reference", command=refNo).grid(row=0, column=0)
btnCrtb = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=10,
                 text="Generate bill", command=create_bill).grid(row=0, column=2)
btnReset = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=15,
                  text="Reset", command=reset).grid(row=1, column=0)
btnExit = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=15,
                 text="Exit", command=iExit).grid(row=1, column=1)
btnSndb = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=10,
                 text="Send bill", command=send_bill).grid(row=1, column=2)

Here I categorized the labels buttons and different parts of code for better understanding.once take a look at the above code.

Output

After integrating all the code snippets expalined above we get the following output


Saving the bill

Path declaration

Now we have successfully generated the bill we need . Now we need to convert the bill into text file.

so, first we need to give the path where i need to store the bill code snippet is given below.

from tkinter import *
import time
x = randint(99, 200)
path = 'D:\\New folder (2)\\New folder' 

Note: you need to change the the path in your computer since the same file may not exist in your computer .

Defining function

Next you need to define functions to write the text in txt file for reference look below

def create_bill():
    global x
    refno = str(x)
    title = refno + ".txt"
    global path
    with open(os.path.join(path, title), "w") as file1:
        toFile = output()
        file1.write(toFile)
    qmsg = messagebox.showinfo("Information", "Bill Generated")
def output():
    global x
    refno = str(x)
    list0 = "\t\t\t\t\t\t\tReference.no :" + refno
    list1 = "\n\n" + "Item\t\t\tQuantity\t\tCost\n"
    list7 = "____\t\t\t_______\t\t        ____\n\n"
    list2 = "Idly\t\t\t" + idly.get() + "\t\t\t" + str(int(idly.get()) * int(costidly.get())) + "\n"
    list3 = "Biryani\t\t\t" + biryani.get() + "\t\t\t" + str(int(biryani.get()) * int(costbiryani.get())) + "\n"
    list4 = "PaneerButterMasala\t" + paneer_butter_masala.get() + "\t\t\t" + str(
        int(costpaneer_butter_masala.get()) * int(paneer_butter_masala.get())) + "\n"
    list5 = "NimbuPani\t\t" + nimbu_pani.get() + "\t\t\t" + str(
        int(nimbu_pani.get()) * int(costnimbu_pani.get())) + "\n\n"
    list6 = "\t\t\t   " + "total     = Rs " + subTotal.get() + "/-" + "\n"
    list8 = "\t\t\t   " + "Vat       = Rs " + str(int(totalPrice.get()) - int(subTotal.get())) + "/-" + "\n"
    list9 = "\t\t\t   " + "GrandTotal= Rs " + totalPrice.get()[:] + "/-" + "\n"
    String = list0 + list1 + list7 + list2 + list3 + list4 + list5 + list6 + list8 + list9
    return String

I defined the above two functions along with others. create bill creates a txt file .output function writes the data onto a text file.

Creating button

Now we create a button to create bill and save it .

btnCrtb = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=10,
                 text="Generate bill", command=create_bill).grid(row=0, column=2)

Putting it along with the other buttons will make the code more clear.


Emailing your bill

Importing required libraries

Now we have our bill in txt form now we. we SMTP lib module which is already inbuilt in your python program. we import, os,smtplib and email message for this to work.

import os
import smtplib
from email.message import EmailMessage

Defining require variables

EMAIL_ADDRESS = os.environ.get('EMAIL_USER')  #  enter your email address
EMAIL_PASSWORD = os.environ.get('EMAIL_PASS')  # enter password

You have to give your email address in the place of Email_user , Email password in place of email_pass

Defining required functions

def send_bill():
    msg = EmailMessage()
    msg['Subject'] = 'Your bill '
    msg['From'] = EMAIL_ADDRESS
    msg['To'] = EMAIL_ADDRESS       #receiver email
    global x
    fileref = str(x) + '.txt'
    msg.set_content('This is your Total bill\nyour Reference.No is: Bill' + str(x))
    with open(os.path.join(path, fileref), "rb") as f:
        file_data = f.read()
        file_name = "RestaurentBill"
    msg.add_attachment(file_data, maintype='application', subtype='octet-stream', filename=file_name)
    qsend = messagebox.askyesno("Billing System", "Do you want to send the bill?")
    if qsend > 0:
        with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
            smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD)
            smtp.send_message(msg)
        qsmsg = messagebox.showinfo("Information", "Bill send successfully")
    else:
        qnmsg = messagebox.showinfo("Information", "Bill not send")

Creating button for sending email

btnSndb = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=10,
                 text="Send bill", command=send_bill).grid(row=1, column=2)

Put it in buttons columns fo code for better customization


Final code

After integrating all the code snippets above and then changing colors of buttons, labels we get the following code.

from tkinter import *
import time
from tkinter import messagebox
import os
import smtplib
from email.message import EmailMessage
from random import randint
color='#87918c'
color1='#757d79'
color3='#bf5454'      #exit button
color4='#87918c'
color5='#87918c'
color6='#87918c'
EMAIL_ADDRESS = os.environ.get('EMAIL_USER')  # your email address
EMAIL_PASSWORD = os.environ.get('EMAIL_PASS')  # password
x = randint(99, 200)
path = 'C:\\Users\\gayatri\\Desktop\\billls'  # path to the folder
root = Tk()
root.geometry("1150x750+0+0")
root.title("Restaurant Billing System")
Tops = Frame(root, width=1350, height=50, bd=8, bg=color, relief="raise")
Tops.pack(side=TOP)
Bottoms = Frame(root, width=1350, height=50, bd=8, bg=color, relief="raise")
Bottoms.pack(side=BOTTOM)
f1 = Frame(root, width=900, height=650, bd=8, bg=color, relief="raise")
f1.pack(side=LEFT)
f1a = Frame(f1, width=900, height=330, bd=8, bg=color, relief="raise")
f1a.pack(side=TOP)
f2a = Frame(f1, width=900, height=320, bd=8, bg=color, relief="raise")
f2a.pack(side=BOTTOM)
f1aa = Frame(f1a, width=400, height=430, bd=8, bg=color4, relief="raise")
f1aa.pack(side=LEFT)
f1ab = Frame(f1a, width=400, height=430, bd=8, bg=color5, relief="raise")
f1ab.pack(side=RIGHT)
f2aa = Frame(f2a, width=450, height=330, bd=8, bg=color6, relief="raise")
f2aa.pack(side=LEFT)
f2ab = Frame(f2a, width=450, height=330, bd=8, bg=color4, relief="raise")
f2ab.pack(side=LEFT)
lblInfo = Label(Tops, font=('arial', 25, 'bold'), text="Restaurant Billing System", bg=color,bd=15,padx=12, anchor='w')
lblInfo.grid(row=0, column=0)
# ==============================Variables=====================
PaymentRef = StringVar()
emailID = StringVar()
idly = StringVar()
biryani = StringVar()
paneer_butter_masala = StringVar()
nimbu_pani = StringVar()
costidly = StringVar()
costbiryani = StringVar()
costpaneer_butter_masala = StringVar()
costnimbu_pani = StringVar()
dateRef = StringVar()
subTotal = StringVar()
vat = StringVar()
totalPrice = StringVar()
text_Input = StringVar()
dateRef.set(time.strftime("%d/%m/%y"))
operator = ""
vat.set(0)
idly.set(0)
biryani.set(0)
paneer_butter_masala.set(0)
nimbu_pani.set(0)
subTotal.set(0)
totalPrice.set(0)
costidly.set(30)
costbiryani.set(180)
costnimbu_pani.set(20)
costpaneer_butter_masala.set(180)
emailID.set("Enter_EmailID")
# =============================Functions==================
def tPrice():
    cBprice = int(costidly.get())
    bBprice = int(costbiryani.get())
    fFprice = int(costpaneer_butter_masala.get())
    sDprice = int(costnimbu_pani.get())
    cBno = int(idly.get())
    bBno = int(biryani.get())
    fFno = int(paneer_butter_masala.get())
    sDno = int(nimbu_pani.get())
    tempVat = int(vat.get())
    subPrice = (cBprice * cBno + bBprice * bBno + fFprice * fFno + sDprice * sDno)
    totalCost = str('%d' % subPrice)
    totalCostwithVat = str('%d' % (subPrice + (subPrice * tempVat) / 100))
    subTotal.set(totalCost)
    totalPrice.set(totalCostwithVat)
def iExit():
    qexit = messagebox.askyesno("Billing System", "Do you want to exit?")
    if qexit > 0:
        root.destroy()
        return
def reset():
    global x
    x = x + 1
    PaymentRef.set("")
    idly.set(0)
    biryani.set(0)
    paneer_butter_masala.set(0)
    nimbu_pani.set(0)
    subTotal.set(0)
    totalPrice.set(0)
    emailID.set("Enter EmailID")
def refNo():
    global x
    y = str(x)
    randomRef = str(y)
    PaymentRef.set("BILL" + randomRef)
def create_bill():
    global x
    refno = str(x)
    pakodi = refno + ".txt"
    global path
    with open(os.path.join(path, pakodi), "w") as file1:
        toFile = output()
        file1.write(toFile)
    qmsg = messagebox.showinfo("Information", "Bill Generated")
def send_bill():
    #
    msg = EmailMessage()
    msg['Subject'] = 'Your bill '
    msg['From'] = EMAIL_ADDRESS
    msg['To'] = emailID.get()+'@gmail.com' # receiver email
    print(emailID.get())
    global x
    fileref = str(x) + '.txt'
    msg.set_content('This is your Total bill\nyour Reference.No is: Bill' + str(x))
    with open(os.path.join(path, fileref), "rb") as f:
        file_data = f.read()
        file_name = "RestaurentBill"
    msg.add_attachment(file_data, maintype='application', subtype='octet-stream', filename=file_name)
    qsend = messagebox.askyesno("Billing System", "Do you want to send the bill?")
    if qsend > 0:
        with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
            smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD)
            smtp.send_message(msg)
        qsmsg = messagebox.showinfo("Information", "Bill send successfully")
    else:
        qnmsg = messagebox.showinfo("Information", "Bill  will not send")
def output():
    global x
    refno = str(x)
    list0 = "\t\t\t\t\tReference.no :" + refno
    list02='\t\t\t\tEmailID :'+emailID.get()+'@gmail.com'
    list1 = "\n\n" + "Item\t\t\tQuantity\t\tCost\n"
    list7 = "____\t\t\t_______\t\t        ____\n\n"
    list2 = "Idly\t\t\t" + idly.get() + "\t\t\t" + str(int(idly.get()) * int(costidly.get())) + "\n"
    list3 = "Biryani\t\t\t" + biryani.get() + "\t\t\t" + str(int(biryani.get()) * int(costbiryani.get())) + "\n"
    list4 = "PaneerButterMasala\t" + paneer_butter_masala.get() + "\t\t\t" + str(
        int(costpaneer_butter_masala.get()) * int(paneer_butter_masala.get())) + "\n"
    list5 = "NimbuPani\t\t" + nimbu_pani.get() + "\t\t\t" + str(
        int(nimbu_pani.get()) * int(costnimbu_pani.get())) + "\n\n"
    list6 = "\t\t\t   " + "total     = Rs " + subTotal.get() + "/-" + "\n"
    list8 = "\t\t\t   " + "Vat       = Rs " + str(int(totalPrice.get()) - int(subTotal.get())) + "/-" + "\n"
    list9 = "\t\t\t   " + "GrandTotal= Rs " + totalPrice.get()[:] + "/-" + "\n"
    String = list0 +list02+ list1 + list7 + list2 + list3 + list4 + list5 + list6 + list8 + list9
    return String
def btnClearDisplay():
    global operator
    operator = ""
    text_Input.set("")
def btnEqualsInput():
    global operator
    sumup = str(eval(operator))
    text_Input.set(sumup)
    operator = ""
# ==================================Order Info===========================
lblRef = Label(f1aa, font=('arial', 16, 'bold'), fg="red", text="Reference No", bd=16, bg=color4, justify='left')
lblRef.grid(row=0, column=0)
txtRef = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=PaymentRef, bd=10, insertwidth=2, justify='left')
txtRef.grid(row=0, column=1)
# --------------
lblCb = Label(f1aa, font=('arial', 16, 'bold'), text="Idly", bd=16, bg=color4, justify='left')
lblCb.grid(row=1, column=0)
txtCb = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=idly, bd=10, insertwidth=2, justify='left')
txtCb.grid(row=1, column=1)
# --------------
lblBb = Label(f1aa, font=('arial', 16, 'bold'), text="Biryani", bd=16, bg=color4, justify='left')
lblBb.grid(row=2, column=0)
txtBb = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=biryani, bd=10, insertwidth=2, justify='left')
txtBb.grid(row=2, column=1)
# --------------
lblFf = Label(f1aa, font=('arial', 16, 'bold'), text="Paneer butter masala", bd=16, bg=color4, justify='left')
lblFf.grid(row=3, column=0)
txtFf = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=paneer_butter_masala, bd=10, insertwidth=2, justify='left')
txtFf.grid(row=3, column=1)
# --------------
lblSd = Label(f1aa, font=('arial', 16, 'bold'), text="Nimbu pani", bd=16, bg=color4, justify='left')
lblSd.grid(row=4, column=0)
txtSd = Entry(f1aa, font=('arial', 16, 'bold'), textvariable=nimbu_pani, bd=10, insertwidth=2, justify='left')
txtSd.grid(row=4, column=1)
# ===================================Payment Info==========================
lbldate = Label(f1ab, font=('arial', 16, 'bold'), text="Date", bd=16, bg=color5, justify='left')
lbldate.grid(row=0, column=0)
txtdate = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=dateRef, bd=10, insertwidth=2, justify='left')
txtdate.grid(row=0, column=1)
# --------------
lblCcb = Label(f1ab, font=('arial', 16, 'bold'), text="Price of Idly", bd=16, bg=color5, justify='left')
lblCcb.grid(row=1, column=0)
txtCcb = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=costidly, bd=10, insertwidth=2, justify='left')
txtCcb.grid(row=1, column=1)
# --------------
lblCbb = Label(f1ab, font=('arial', 16, 'bold'), text="Price of Biryani", bd=16, bg=color5, justify='left')
lblCbb.grid(row=2, column=0)
txtCbb = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=costbiryani, bd=10, insertwidth=2, justify='left')
txtCbb.grid(row=2, column=1)
# --------------
lblCff = Label(f1ab, font=('arial', 16, 'bold'), text="Price of Paneer butter masala", bd=16, bg=color5,
               justify='left')
lblCff.grid(row=3, column=0)
txtCff = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=costpaneer_butter_masala, bd=10, insertwidth=2,
               justify='left')
txtCff.grid(row=3, column=1)
# --------------
lblCsd = Label(f1ab, font=('arial', 16, 'bold'), text="Price of Nimbu pani", bd=16, bg=color5, justify='left')
lblCsd.grid(row=4, column=0)
txtCsd = Entry(f1ab, font=('arial', 16, 'bold'), textvariable=costnimbu_pani, bd=10, insertwidth=2, justify='left')
txtCsd.grid(row=4, column=1)
# ==========================Total Payment Info======
lblPrice = Label(f2aa, font=('arial', 16, 'bold'), text="Price", bd=16, bg=color6, justify='left')
lblPrice.grid(row=0, column=0)
txtPrice = Entry(f2aa, font=('arial', 16, 'bold'), textvariable=subTotal, bd=10, insertwidth=2, justify='left')
txtPrice.grid(row=0, column=1)
# --------------
lblVat = Label(f2aa, font=('arial', 16, 'bold'), text="VAT", bd=16, bg=color6, justify='left')
lblVat.grid(row=1, column=0)
txtVat = Entry(f2aa, font=('arial', 16, 'bold'), textvariable=vat, bd=10, insertwidth=2, justify='left')
txtVat.grid(row=1, column=1)
# --------------
lblTp = Label(f2aa, font=('arial', 16, 'bold'), text="Total Price", bd=16, bg=color6, justify='left')
lblTp.grid(row=2, column=0)
txtTp = Entry(f2aa, font=('arial', 16, 'bold'), textvariable=totalPrice, bd=10, insertwidth=2, justify='left')
txtTp.grid(row=2, column=1)
# ----------------
lblTp = Label(f2aa, font=('arial', 16, 'bold'), text="EMAIL-ID", bd=16, bg=color6, justify='left')
lblTp.grid(row=3, column=0)
txtTp = Entry(f2aa, font=('arial', 16, 'bold'), textvariable=emailID, bd=10, insertwidth=2, justify='left')
txtTp.grid(row=3, column=1)
# ==============Buttons==========
btnTotal = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=15,
                  text="Total Price", bg=color, command=tPrice).grid(row=1, column=0)
btnRefer = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=15,
                  text="Sales Reference", bg=color, command=refNo).grid(row=0, column=0)
btnCrtb = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=10,
                 text="Generate bill", bg=color1, command=create_bill).grid(row=0, column=2)
btnReset = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=15,
                  text="Reset", bg=color, command=reset).grid(row=0, column=1)
btnExit = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=15,
                 text="Exit", bg=color3, command=iExit).grid(row=1, column=1)
btnSndb = Button(f2ab, padx=16, pady=16, bd=8, fg="black", font=('arial', 16, 'bold'), width=10,
                 text="Send bill", bg=color1, command=send_bill).grid(row=1, column=2)
root.mainloop()

I have already put a few color codes in the above code for you to edit.


video output:

video output

Note: You need to disable less secure app access for your mail to be sent successfully.

You can also use this module to create something else like an addmission form or application form and many more

I hope you had fun coding this project. Well, that’s about it. Now go create something more fun, and I hope my tutorial has helped you out somewhat.

Creating a multiplication Skill in Alexa using python

Written By Monisha Macharla

Hi, I'm Monisha. I am a tech blogger and a hobbyist. I am eager to learn and explore tech related stuff! also, I wanted to deliver you the same as much as the simpler way with more informative content. I generally appreciate learning by doing, rather than only learning. Thank you for reading my blog! Happy learning!

RELATED POSTS

Tkinter based GUI- Application form

Tkinter based GUI- Application form

Hello everyone! Today we are going to make a Tkinter based GUI that will be an Application Form . We will ask some details by the user and then will be saving that with a default extension of .yaml, which can be changed at the time of saving the file. Let's go ahead!...

Look and Feel Customization on Python Tkinter

In this tutorial, you will learn about how to customize the look and feel of a python GUI created using tkinter. This is third part of tkinter tutorial course. To begin with, we will look at how to create message boxes. Contents: Creating MessageboxesCreate...

Layout Management using Python Tkinter

Layout Management using Python Tkinter

In this tutorial, you will be learning “How to layout your GUI using Python”. The following are the topics that will be covered in this article. Python Tkinter Label FramesTkinter Geometry MatrixCreating menu barsCreating tabbed widgets 1. Python Tkinter Label Frames:...

VIDEOS – FOLLOW US ON YOUTUBE

EXPLORE OUR IOT PROJECTS

IoT Smart Gardening System – ESP8266, MQTT, Adafruit IO

Gardening is always a very calming pastime. However, our gardens' plants may not always receive the care they require due to our active lifestyles. What if we could remotely keep an eye on their health and provide them with the attention they require? In this article,...

How to Simulate IoT projects using Cisco Packet Tracer

In this tutorial, let's learn how to simulate the IoT project using the Cisco packet tracer. As an example, we shall build a simple Home Automation project to control and monitor devices. Introduction Firstly, let's quickly look at the overview of the software. Packet...

All you need to know about integrating NodeMCU with Ubidots over MQTT

In this tutorial, let's discuss Integrating NodeMCU and Ubidots IoT platform. As an illustration, we shall interface the DHT11 sensor to monitor temperature and Humidity. Additionally, an led bulb is controlled using the dashboard. Besides, the implementation will be...

All you need to know about integrating NodeMCU with Ubidots over Https

In this tutorial, let's discuss Integrating NodeMCU and Ubidots IoT platform. As an illustration, we shall interface the DHT11 sensor to monitor temperature and Humidity. Additionally, an led bulb is controlled using the dashboard. Besides, the implementation will be...

How to design a Wireless Blind Stick using nRF24L01 Module?

Introduction Let's learn to design a low-cost wireless blind stick using the nRF24L01 transceiver module. So the complete project is divided into the transmitter part and receiver part. Thus, the Transmitter part consists of an Arduino Nano microcontroller, ultrasonic...

Sending Temperature data to ThingSpeak Cloud and Visualize

In this article, we are going to learn “How to send temperature data to ThingSpeak Cloud?”. We can then visualize the temperature data uploaded to ThingSpeak Cloud anywhere in the world. But "What is ThingSpeak?” ThingSpeak is an open-source IoT platform that allows...

Amaze your friend with latest tricks of Raspberry Pi and Firebase

Introduction to our Raspberry Pi and Firebase trick Let me introduce you to the latest trick of Raspberry Pi and Firebase we'll be using to fool them. It begins with a small circuit to connect a temperature sensor and an Infrared sensor with Raspberry Pi. The circuit...

How to implement Machine Learning on IoT based Data?

Introduction The industrial scope for the convergence of the Internet of Things(IoT) and Machine learning(ML) is wide and informative. IoT renders an enormous amount of data from various sensors. On the other hand, ML opens up insight hidden in the acquired data....

Smart Display Board based on IoT and Google Firebase

Introduction In this tutorial, we are going to build a Smart Display Board based on IoT and Google Firebase by using NodeMCU8266 (or you can even use NodeMCU32) and LCD. Generally, in shops, hotels, offices, railway stations, notice/ display boards are used. They are...

Smart Gardening System – GO GREEN Project

Automation of farm activities can transform agricultural domain from being manual into a dynamic field to yield higher production with less human intervention. The project Green is developed to manage farms using modern information and communication technologies....