The Pizza Delivery Project
The pizza delivery project has often been the subject of student programming assignments because it offers opportunities to explore a diverse range of controls, use program loops, and even incorporate some database programming and print routines. And, although the application is not intended for commercial use, there is certainly scope for further development - I have seen similar applications offered on the Internet, perhaps written by former students!
- Using the Windows Forms App (.Net Framework) template as we did for the "AddressBook" and "AddressBook02" projects, open a new project called "PizzaDelivery". Save your project immediately to create the program folder.
- Download the file pizza_delivery.zip using the link below, unzip the file, and copy or save the contents into your project folder's /bin/Debug subdirectory.
- Create an interface like the one illustrated below. Note that you will also need two PrintDocument controls (see below for details). The zipped file pizza_delivery.zip contains the database and program icon for the application, which should now be in your project's \bin\Debug\ subfolder.
The PizzaDelivery program interface
- Set the properties of the controls as shown in the table below (properties not shown should be left at their default values). Note: if a control appears within a panel, it should be created as a child of the panel control (make sure the panel is selected before creating each child control). The locations given for these controls are relative to the top left-hand corner of the panel control.
Control | Name | Additional Properties |
---|---|---|
Form | frmPizzaDelivery | BackColor: Dark Orange Icon: pizza.ico Size: 775, 600 Text: "Pete's Pizza Delivery" |
Label | lblHeader | Font: Arial Rounded MT Bold, 14pt ForeColor: White Location: 10, 10 Text: "Pete's Pizza Delivery - Order Form" |
Label | lblTelephone | Autosize: False ForeColor: White Location: 472, 13 Size: 66, 20 Text: "Telephone:" TextAlign: MiddleRight |
TextBox | txtTel | Location: 544, 14 Size: 120, 20 |
Button | cmdContinue | Location: 670, 12 Text: "Continue" |
Panel | pnlLeft | BackColor: Yellow BorderStyle: FixedSingle Enabled: False Location: 10, 50 Size: 325, 500 |
Label | lblSurname | Autosize: False Location: 10, 10 Size: 66, 20 Text: "Surname:" TextAlign: MiddleRight |
Label | lblForename | Autosize: False Location: 10, 35 Size: 66, 20 Text: "Forename:" TextAlign: MiddleRight |
Label | lblAddress | Autosize: False Location: 10, 60 Size: 66, 20 Text: "Address:" TextAlign: MiddleRight |
Label | lblTown | Autosize: False Location: 10, 110 Size: 66, 20 Text: "Town:" TextAlign: MiddleRight |
Label | lblPostcode | Autosize: False Location: 10, 135 Size: 66, 20 Text: "Postcode:" TextAlign: MiddleRight |
Label | lblOrderDetails | Autosize: False Location: 10, 175 Size: 100, 20 Text: "Order details:" TextAlign: MiddleLeft |
Button | cmdSave | Enabled: False Location: 216, 10 Size: 94, 23 Text: "Save Customer" |
TextBox | txtSurname | Location: 80, 11 Size: 120, 20 |
TextBox | txtForename | Location: 80, 36 Size: 120, 20 |
TextBox | txtAddress01 | Location: 80, 61 Size: 230, 20 |
TextBox | txtAddress02 | Location: 80, 86 Size: 230, 20 |
TextBox | txtTown | Location: 80, 111 Size: 120, 20 |
TextBox | txtPostcode | Location: 80, 136 Size: 60, 20 |
TextBox | txtOrder | Location: 13, 200 Multiline: True ScrollBars: Vertical Size: 300, 280 |
Panel | pnlRight | BackColor: Yellow BorderStyle: FixedSingle Enabled: False Location: 345, 50 Size: 400, 500 |
Panel | pnlTopping | BackColor: PapayaWhip BorderStyle: FixedSingle Location: 10, 10 Size: 120, 150 |
Label | lblTopping | Font: Microsoft Sans Serif, 10pt, style=Bold Location: 26, 10 Text: "Topping" |
RadioButton | radTop00 | Location: 15, 40 Text: "Margherita" |
RadioButton | radTop01 | Location: 15, 60 Text: "Four Seasons" |
RadioButton | radTop02 | Location: 15, 80 Text: "Meat Feast" |
Panel | pnlBase | BackColor: PapayaWhip BorderStyle: FixedSingle Location: 140, 10 Size: 120, 150 |
Label | lblBase | Font: Microsoft Sans Serif, 10pt, style=Bold Location: 37, 10 Text: "Base" |
RadioButton | radBas00 | Location: 15, 40 Text: "25 cm/10 in." |
RadioButton | radBas01 | Location: 15, 60 Text: "30 cm/12 in." |
RadioButton | radBas02 | Location: 15, 80 Text: "35 cm/14 in." |
Panel | pnlExtras | BackColor: PapayaWhip BorderStyle: FixedSingle Location: 270, 10 Size: 120, 150 |
Label | lblExtras | Font: Microsoft Sans Serif, 10pt, style=Bold Location: 34, 10 Text: "Extras" |
CheckBox | chkExt00 | Location: 15, 40 Text: "Mushrooms" |
CheckBox | chkExt01 | Location: 15, 60 Text: "Green Peppers" |
CheckBox | chkExt02 | Location: 15, 80 Text: "Anchovies" |
CheckBox | chkExt03 | Location: 15, 100 Text: "Cheese" |
Button | cmdAddItem | Location: 140, 166 Size: 120, 23 Text: "Add Item" |
Panel | pnlDrinks | BackColor: GreenYellow BorderStyle: FixedSingle Enabled: False Location: 10, 200 Size: 250, 150 |
Label | lblDrinks | Font: Microsoft Sans Serif, 10pt, style=Bold Location: 10, 10 Text: "Drinks" |
Label | lblQty | Font: Microsoft Sans Serif, 10pt, style=Bold Location: 184, 10 Text: "Qty" |
Label | lblCola | Location: 12, 41 Text: "Cola" |
Label | lblLemonade | Location: 12, 66 Text: "Lemonade" |
Label | lblOrange | Location: 12, 91 Text: "Orange" |
Label | lblWater | Location: 12, 116 Text: "Mineral Water" |
NumericUpDown | nudDrk00 | Autosize: False Location: 187, 39 Size: 40, 20 |
NumericUpDown | nudDrk01 | Autosize: False Location: 187, 64 Size: 40, 20 |
NumericUpDown | nudDrk02 | Autosize: False Location: 187, 89 Size: 40, 20 |
NumericUpDown | nudDrk03 | Autosize: False Location: 187, 114 Size: 40, 20 |
Button | cmdClear | Location: 10, 428 Size: 120, 23 Text: "Clear Order" |
Button | cmdPrint | Location: 10, 457 Size: 120, 23 Text: "Print Delivery Note" |
Label | lblOrdVal | Autosize: False Location: 220, 404 Size; 100, 13 Text: "Order value:" TextAlign: MiddleRight |
Label | lblDelChg | Autosize: False Location: 220, 429 Size; 100, 13 Text: "Delivery charge:" TextAlign: MiddleRight |
Label | lblOrdTot | Autosize: False Location: 220, 454 Size; 100, 13 Text: "Order total:" TextAlign: MiddleRight |
Label | lblOrderValue | Autosize: False BackColor: White BorderStyle: Fixed3D Location: 326,400 Size: 60, 20 Text: none TextAlign: MiddleRight |
Label | lblDeliveryCharge | Autosize: False BackColor: White BorderStyle: Fixed3D Location: 326, 425 Size: 60, 20 Text: noneTextAlign: MiddleRight |
Label | lblOrderTotal | Autosize: False BackColor: White BorderStyle: Fixed3D Location: 326, 450 Size: 60, 20 Text: none TextAlign: MiddleRight |
PrintDocument | prtDeliveryNote | - |
PrintDocument | prtContinuation | - |
The commented program code is reproduced in its entirety below. Hopefully the comments, together with the explanatory notes that follow, will be sufficient to inform the reader how the code works. Most of the code is relatively straightforward, and the program essentially brings together various elements that have been the subject of other pages in this section.
The PizzaDelivery project code:
Public Class frmPizzaDelivery
'Declare database object variables
Dim con As New OleDb.OleDbConnection
Dim ds As New DataSet
Dim da As OleDb.OleDbDataAdapter
Dim sql As String
Dim cmd As OleDb.OleDbCommand
'Declare control arrays
Dim RadioArrayTopping(0 To 2) As RadioButton
Dim RadioArrayBase(0 To 2) As RadioButton
Dim CheckArrayExtras(0 To 3) As CheckBox
'Declare module variables
Dim Topping() As String = {"Margherita", "Four Seasons", "Meat Feast"}
Dim Base() As String = {"9""", "12""", "14"""}
Dim Extras() As String = {"Mushrooms", "Green Peppers", "Anchovies", "Cheese"}
Dim Drinks() As String = {"Cola", "Lemonade", "Orange", "Mineral Water"}
Dim PizzaPrice(,) As Single = {{3.0, 4.0, 5.5}, {3.5, 4.5, 6.0}, {4.0, 5.0, 6.5}}
Dim ExtraPrice() As Single = {0.5, 0.4, 0.6, 0.5}
Dim DrinkPrice() As Single = {1.0, 1.0, 1.0, 0.9}
Dim itemNo As Integer = -1
Dim strOrder01 As String = ""
Dim strOrder02 As String = ""
Dim strDrinks As String = ""
Dim pizzaVal, drinkVal, orderVal, delivery, total As Single
'Structure to hold options for each pizza ordered
Structure pizzaStruct
Dim Topp As Integer
Dim Base As Integer
Dim Ex00 As Boolean
Dim Ex01 As Boolean
Dim Ex02 As Boolean
Dim Ex03 As Boolean
End Structure
'Structure to hold drink selection
Structure drinkStruct
Dim Drink00 As Integer
Dim Drink01 As Integer
Dim Drink02 As Integer
Dim Drink03 As Integer
End Structure
'Declare module structure variables
Dim pizzaArray(-1) As pizzaStruct
Dim drinkSelection As drinkStruct
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Set up control arrays
RadioArrayTopping(0) = radTop00
RadioArrayTopping(1) = radTop01
RadioArrayTopping(2) = radTop02
RadioArrayBase(0) = radBas00
RadioArrayBase(1) = radBas01
RadioArrayBase(2) = radBas02
CheckArrayExtras(0) = chkExt00
CheckArrayExtras(1) = chkExt01
CheckArrayExtras(2) = chkExt02
CheckArrayExtras(3) = chkExt03
'Initialise order
clearOrder()
End Sub
Function checkTelNum() As Boolean
'Make sure telephone number is valid
Dim strAllowedChars As String = "0123456789() -+ "
If Len(txtTel.Text) < 5 Then
Return False
Else
For i = 0 To Len(txtTel.Text) - 1
If InStr(1, strAllowedChars, txtTel.Text(i)) = 0 Then
Return False
End If
Next
Return True
End If
End Function
Private Sub cmdContinue_Click(sender As Object, e As EventArgs) Handles cmdContinue.Click
'Check for valid telephone number before proceeding
If checkTelNum() = False Then
MsgBox("You have not entered a valid telephone number.")
txtTel.Focus()
Exit Sub
End If
'If telephone number is valid, disable telephone number input
'and enable main form functionality
cmdContinue.Enabled = False
txtTel.Enabled = False
pnlLeft.Enabled = True
pnlRight.Enabled = True
enableCustomerInput()
'Open database and check for existing customer using telephone number
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=PizzaDelivery.accdb;"
con.ConnectionString &= " Persist Security Info=False;"
con.Open()
sql = "SELECT * FROM Customer WHERE TelephoneNo = '" & txtTel.Text & "'"
da = New OleDb.OleDbDataAdapter (sql, con)
da.Fill(ds, "CustInfo")
con.Close()
If ds.Tables("CustInfo").Rows.Count = 0 Then
'If customer telephone number not found, inform user
'and move focus to customer surname input box
MsgBox("Number not found in database.")
cmdSave.Enabled = True
txtSurname.Focus()
Exit Sub
Else
'Otherwise add customer details to form
txtTel.Text = ds.Tables("CustInfo").Rows(0).Item(0)
txtSurname.Text = ds.Tables("CustInfo").Rows(0).Item(1)
txtForename.Text = ds.Tables("CustInfo").Rows(0).Item(2)
txtAddress01.Text = ds.Tables("CustInfo").Rows(0).Item(3)
txtAddress02.Text = ds.Tables("CustInfo").Rows(0).Item(4)
txtTown.Text = ds.Tables("CustInfo").Rows(0).Item(5)
txtPostcode.Text = ds.Tables("CustInfo").Rows(0).Item(6)
'Protect customer details from changes
disableCustomerInput()
End If
End Sub
Function checkCustomer() As Boolean
'Make sure customer details are complete
If txtSurname.Text = "" Then
MsgBox("Please enter the customer's surname.")
Return False
ElseIf txtAddress01.Text = "" Then
MsgBox("Please enter the customer's address.")
Return False
ElseIf txtPostcode.Text = "" Then
MsgBox("Please enter the customer's postcode.")
Return False
Else
Return True
End If
End Function
Function addItem() As Boolean
'Declare local variables
Dim toppingSelected As Boolean = False
Dim baseSelected As Boolean = False
Dim top, bas As Integer
'Check that a base and a topping are selected and get choices
For i = 0 To 2
If RadioArrayTopping(i).Checked = True Then
toppingSelected = True
top = i
End If
If RadioArrayBase(i).Checked = True Then
baseSelected = True
bas = i
End If
Next
'If either base or topping not selected, prompt user
If toppingSelected = False Then
MsgBox("You have not selected a topping.")
Return False
End If
If baseSelected = False Then
MsgBox("You have not selected a base.")
Return False
Else
'Increment item number
itemNo += 1
'If this is first pizza item enable drinks panel
If itemNo = 0 Then pnlDrinks.Enabled = True
'Increase the size of the pizza item array dynamically
ReDim Preserve pizzaArray(itemNo)
'Save user choices
pizzaArray(itemNo).Topp = top
pizzaArray(itemNo).Base = bas
pizzaArray(itemNo).Ex00 = CheckArrayExtras(0).Checked
pizzaArray(itemNo).Ex01 = CheckArrayExtras(1).Checked
pizzaArray(itemNo).Ex02 = CheckArrayExtras(2).Checked
pizzaArray(itemNo).Ex03 = CheckArrayExtras(3).Checked
End If
pizzaVal = 0 'Reset pizza item value
For i = 0 To itemNo
'Calculate total value of pizzas currently selected
pizzaVal += PizzaPrice(pizzaArray(i).Topp, pizzaArray(i).Base)
If pizzaArray(itemNo).Ex00 = True Then pizzaVal += ExtraPrice(0)
If pizzaArray(itemNo).Ex01 = True Then pizzaVal += ExtraPrice(1)
If pizzaArray(itemNo).Ex02 = True Then pizzaVal += ExtraPrice(2)
If pizzaArray(itemNo).Ex03 = True Then pizzaVal += ExtraPrice(3)
Next
orderVal = pizzaVal + drinkVal 'Calculate order value
If orderVal >= 10.0 Then
'If order value is £10.00 or more delivery is free
delivery = 0.0
Else
'If order value is less than £10.00 delivery is £2.00
delivery = 2.0
End If
total = orderVal + delivery 'Calculate total to pay
'Update order display
txtOrder.Text = strOrder01
lblOrderValue.Text = Format(orderVal, "currency")
lblDeliveryCharge.Text = Format(delivery, "currency")
lblOrderTotal.Text = Format(total, "currency")
clearItem() 'clear pizza selection ready for next selection
If itemNo > 14 Then
'Number of items per order is limited to 15 - disable input of further items
MsgBox("You have reached the maximum number of items for a single order.")
cmdAddItem.Enabled = False
pnlTopping.Enabled = False
pnlBase.Enabled = False
pnlExtras.Enabled = False
End If
Return True 'Item was added to order
End Function
Sub addDrinks()
'Get quantities of each drink selected
drinkSelection.Drink00 = nudDrk00.Value
drinkSelection.Drink01 = nudDrk01.Value
drinkSelection.Drink02 = nudDrk02.Value
drinkSelection.Drink03 = nudDrk03.Value
drinkVal = 0 'Initialise value of drinks to zero
'Calculate total value of drinks selected
drinkVal += DrinkPrice(0) * drinkSelection.Drink00
drinkVal += DrinkPrice(1) * drinkSelection.Drink01
drinkVal += DrinkPrice(2) * drinkSelection.Drink02
drinkVal += DrinkPrice(3) * drinkSelection.Drink03
orderVal = pizzaVal + drinkVal 'calculate order value
'Determine whether delivery charge should be applied
If orderVal >= 10.0 Then
delivery = 0.0
Else
delivery = 2.0
End If
total = orderVal + delivery 'calculate total to pay
'Update order details and clear current pizza item
txtOrder.Text = strOrder01
lblOrderValue.Text = Format(orderVal, "currency")
lblDeliveryCharge.Text = Format(delivery, "currency")
lblOrderTotal.Text = Format(total, "currency")
clearItem()
End Sub
Sub writeOrder()
'Construct order string - if order has more than 7 items not including drinks,
'create a second order string to enable printing of delivery note on two pages
Dim limit As Integer
txtOrder.Text = ""
strOrder01 = ""
strOrder02 = ""
If itemNo > -1 Then
If itemNo > 6 Then
limit = 6 'Limit first page of delivery note to 7 items
Else
limit = itemNo
End If
For i = 0 To limit 'Create order string for first page of delivery note
strOrder01 &= "1 x "
strOrder01 &= Base(pizzaArray(i).Base) & " "
strOrder01 &= Topping(pizzaArray(i).Topp)
If(pizzaArray(i).Ex00 = False And pizzaArray(i).Ex01 = False And _
pizzaArray(i).Ex02 = False And pizzaArray(i).Ex03 = False) Then
strOrder01 &= ", no extras."
Else
strOrder01 &= ", with extra: "
End If
If pizzaArray(i).Ex00 = True Then strOrder01 &= vbNewLine & " " & Extras(0)
If pizzaArray(i).Ex01 = True Then strOrder01 &= vbNewLine & " " & Extras(1)
If pizzaArray(i).Ex02 = True Then strOrder01 &= vbNewLine & " " & Extras(2)
If pizzaArray(i).Ex03 = True Then strOrder01 &= vbNewLine & " " & Extras(3)
strOrder01 &= vbNewLine & vbNewLine
Next
If itemNo > 6 Then 'Create order string for second page of delivery note
For i = 7 To itemNo
strOrder02 &= "1 x "
strOrder02 &= Base(pizzaArray(i).Base) & " "
strOrder02 &= Topping(pizzaArray(i).Topp)
If(pizzaArray(i).Ex00 = False And pizzaArray(i).Ex01 = False And _
pizzaArray(i).Ex02 = False And pizzaArray(i).Ex03 = False) Then
strOrder02 &= ", no extras."
Else
strOrder02 &= ", with extra: "
End If
If pizzaArray(i).Ex00 = True Then strOrder02 &= vbNewLine & " " & Extras(0)
If pizzaArray(i).Ex01 = True Then strOrder02 &= vbNewLine & " " & Extras(1)
If pizzaArray(i).Ex02 = True Then strOrder02 &= vbNewLine & " " & Extras(2)
If pizzaArray(i).Ex03 = True Then strOrder02 &= vbNewLine & " " & Extras(3)
strOrder02 &= vbNewLine & vbNewLine
Next
End If
End If
writeDrinks() 'Call procedure to create list of drinks ordered
txtOrder.Text = strOrder01 & strOrder02 & strDrinks 'Concatenate strings for screen output
'Update display values for goods value, delivery charge and total order value
lblOrderValue.Text = Format(orderVal, "currency")
lblDeliveryCharge.Text = Format(delivery, "currency")
lblOrderTotal.Text = Format(total, "currency")
End Sub
Sub writeDrinks()
'Construct list of drinks and quantities ordered (appended to order string)
If drinkSelection.Drink00 = 0 And drinkSelection.Drink01 = 0 And _
drinkSelection.Drink02 = 0 And drinkSelection.Drink03 = 0 Then
Exit Sub
End If
strDrinks = "Drinks:" & vbNewLine
If drinkSelection.Drink00 > 0 Then
strDrinks &= " " & drinkSelection.Drink00 & " x " & Drinks(0) & vbNewLine
End If
If drinkSelection.Drink01 > 0 Then
strDrinks &= " " & drinkSelection.Drink01 & " x " & Drinks(1) & vbNewLine
End If
If drinkSelection.Drink02 > 0 Then
strDrinks &= " " & drinkSelection.Drink02 & " x " & Drinks(2) & vbNewLine
End If
If drinkSelection.Drink03 > 0 Then
strDrinks &= " " & drinkSelection.Drink03 & " x " & Drinks(3) & vbNewLine
End If
strDrinks &= vbNewLine & vbNewLine
End Sub
Private Sub cmdAdd_Click(sender As Object, e As EventArgs) Handles cmdAddItem.Click
'If user has selected a pizza base and topping, add item to order and update order strings
If addItem() = False Then
Exit Sub
Else
writeOrder()
End If
End Sub
Private Sub cmdClear_Click(sender As Object, e As EventArgs) Handles cmdClear.Click
'Clear the current order to cancel, or in readiness for next order
clearOrder()
cmdContinue.Enabled = True
txtTel.Enabled = True
pnlLeft.Enabled = False
pnlRight.Enabled = False
End Sub
Sub clearOrder()
'Reset program variables and restore display to initial state
ds.Clear()
nudDrk00.Value = 0
nudDrk01.Value = 0
nudDrk02.Value = 0
nudDrk03.Value = 0
txtTel.Clear()
txtSurname.Clear()
txtForename.Clear()
txtAddress01.Clear()
txtAddress02.Clear()
txtTown.Clear()
txtPostcode.Clear()
strOrder01 = ""
txtOrder.Text = ""
lblOrderValue.Text = ""
lblDeliveryCharge.Text = ""
lblOrderTotal.Text = ""
itemNo = -1
orderVal = 0
delivery = 0
total = 0
enablePizzaInput()
clearItem()
End Sub
Sub disableCustomerInput()
'Prevent customer details being accidentally changed
cmdSave.Enabled = False
txtSurname.Enabled = False
txtForename.Enabled = False
txtAddress01.Enabled = False
txtAddress02.Enabled = False
txtTown.Enabled = False
txtPostcode.Enabled = False
End Sub
Sub enableCustomerInput()
'Allow new customer details to be entered
cmdSave.Enabled = True
txtSurname.Enabled = True
txtForename.Enabled = True
txtAddress01.Enabled = True
txtAddress02.Enabled = True
txtTown.Enabled = True
txtPostcode.Enabled = True
End Sub
Sub enablePizzaInput()
'Allow further pizza selections to be made
cmdAddItem.Enabled = True
pnlTopping.Enabled = True
pnlBase.Enabled = True
pnlExtras.Enabled = True
End Sub
Sub clearItem()
'Clear current pizza selection
For i = 0 To 2
RadioArrayTopping(i).Checked = False
RadioArrayBase(i).Checked = False
Next
For i = 0 To 3
CheckArrayExtras(i).Checked = False
Next
End Sub
'update order details and program display if the drink selection changes
Private Sub nudDrk00_ValueChanged(sender As Object, e As EventArgs) Handles nudDrk00.ValueChanged
addDrinks()
writeOrder()
End Sub
Private Sub nudDrk01_ValueChanged(sender As Object, e As EventArgs) Handles nudDrk01.ValueChanged
addDrinks()
writeOrder()
End Sub
Private Sub nudDrk02_ValueChanged(sender As Object, e As EventArgs) Handles nudDrk02.ValueChanged
addDrinks()
writeOrder()
End Sub
Private Sub nudDrk03_ValueChanged(sender As Object, e As EventArgs) Handles nudDrk03.ValueChanged
addDrinks()
writeOrder()
End Sub
Private Sub cmdSave_Click(sender As Object, e As EventArgs) Handles cmdSave.Click
'Save new customer details to database
Dim custString As String
Dim count As Integer = 0
If checkCustomer() = False Then Exit Sub
custString = "'" & Replace (txtTel.Text, "'", "''") & "', '" & Replace (txtSurname.Text, "'", "''") _
& "', '" & Replace (txtForename.Text, "'", "''") & "', '" & Replace (txtAddress01.Text, "'", "''") _
& "', '" & Replace (txtAddress02.Text, "'", "''") & "', '" & Replace (txtTown.Text, "'", "''") _
& "', '" & Replace (txtPostcode.Text, "'", "''") & "'"
con.Open()
sql = "INSERT into Customer values (" & custString & ") "
cmd = New OleDb.OleDbCommand (sql, con)
count = cmd.ExecuteNonQuery
If count > 0 Then
MsgBox("Customer record created.")
disableCustomerInput()
End If
con.Close()
End Sub
Private Sub cmdPrint_Click(sender As Object, e As EventArgs) Handles cmdPrint.Click
If checkCustomer() = False Then Exit Sub
prtDeliveryNote.Print()
If itemNo > 6 Then
prtContinuation.Print()
End If
End Sub
Private Sub prtDeliveryNote_PrintPage(sender As Object, e As Drawing.Printing.PrintPageEventArgs) _
Handles prtDeliveryNote.PrintPage
'Declare variables for delivery note print procedure (fonts, brushes, print coordinates etc.)
Dim headerFont As Font = New Font("Arial", 24, GraphicsUnit.Point)
Dim detailFontBold As Font = New Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Point)
Dim detailFont As Font = New Font("Arial", 10, GraphicsUnit.Point)
Dim headerBrush As Brush = Brushes.Blue
Dim detailBrush As Brush = Brushes.Black
Dim x As Single
Dim y As Single
Dim strOutput As String
e.Graphics.PageUnit = GraphicsUnit.Inch 'Set print units
'Most of the code below is setting up parameters for printing various
'parts of the delivery note and then calling the e.Graphics.DrawString()
'method to send them to the printer
strOutput = "Pete's Pizza Delivery Service"
x = (e.MarginBounds.Left / e.Graphics.DpiX) + 0.5
y = (e.MarginBounds.Top / e.Graphics.DpiY) + 0.5
e.Graphics.DrawString(strOutput, headerFont, headerBrush, x, y)
y += 1
strOutput = "Delivery address:"
e.Graphics.DrawString(strOutput, detailFontBold, detailBrush, x, y)
x += 1.5
strOutput = txtForename.Text & " " & txtSurname.Text
e.Graphics.DrawString(strOutput, detailFont, detailBrush, x, y)
strOutput = txtAddress01.Text
y += (e.Graphics.MeasureString(strOutput, detailFont).Height)
e.Graphics.DrawString(strOutput, detailFont, detailBrush, x, y)
If txtAddress02.Text <> "" Then
strOutput = txtAddress02.Text
y += (e.Graphics.MeasureString(strOutput, detailFont).Height)
e.Graphics.DrawString(strOutput, detailFont, detailBrush, x, y)
End If
strOutput = txtTown.Text & " " & txtPostcode.Text
y += (e.Graphics.MeasureString(strOutput, detailFont).Height)
e.Graphics.DrawString(strOutput, detailFont, detailBrush, x, y)
y += 0.5
x -= 1.5
strOutput = "Telephone:"
e.Graphics.DrawString(strOutput, detailFontBold, detailBrush, x, y)
x += 1.5
strOutput = txtTel.Text
e.Graphics.DrawString(strOutput, detailFont, detailBrush, x, y)
y += 0.5
x -= 1.5
strOutput = "Order:"
e.Graphics.DrawString(strOutput, detailFontBold, detailBrush, x, y)
x += 1.5
If itemNo <= 6 Then
strOutput = strOrder01 & strDrinks
Else
strOutput = strOrder01 & vbNewLine & vbNewLine & "continued ..."
End If
e.Graphics.DrawString(strOutput, detailFont, detailBrush, x, y)
y = 9
x = 5.5
strOutput = "Order value:"
e.Graphics.DrawString(strOutput, detailFontBold, detailBrush, x, y)
x += 1.5
strOutput = "£" & CStr(Format(orderVal, "Fixed")).PadLeft(4)
e.Graphics.DrawString(strOutput, detailFont, detailBrush, x, y)
y += 0.5
x -= 1.5
strOutput = "Delivery:"
e.Graphics.DrawString(strOutput, detailFontBold, detailBrush, x, y)
x += 1.5
strOutput = "£" & CStr(Format(delivery, "Fixed")).PadLeft(4)
e.Graphics.DrawString(strOutput, detailFont, detailBrush, x, y)
y += 0.5
x -= 1.5
strOutput = "Total to pay:"
e.Graphics.DrawString(strOutput, detailFontBold, detailBrush, x, y)
x += 1.5
strOutput = "£" & CStr(Format(total, "Fixed")).PadLeft(4)
e.Graphics.DrawString(strOutput, detailFontBold, detailBrush, x, y)
'Return False when no more pages....
e.HasMorePages = False
End Sub
Private Sub prtContinuation_PrintPage(sender As Object, e As Drawing.Printing.PrintPageEventArgs) _
Handles prtContinuation.PrintPage
'Print continuation page if more than 7 items ordered (not including drinks)
Dim headerFont As Font = New Font("Arial", 24, GraphicsUnit.Point)
Dim detailFontBold As Font = New Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Point)
Dim detailFont As Font = New Font("Arial", 10, GraphicsUnit.Point)
Dim headerBrush As Brush = Brushes.Blue
Dim detailBrush As Brush = Brushes.Black
Dim x As Single
Dim y As Single
Dim strOutput As String
e.Graphics.PageUnit = GraphicsUnit.Inch
strOutput = "Pete's Pizza Delivery Service"
x = (e.MarginBounds.Left / e.Graphics.DpiX) + 0.5
y = (e.MarginBounds.Top / e.Graphics.DpiY) + 0.5
e.Graphics.DrawString(strOutput, headerFont, headerBrush, x, y)
y += 1
strOutput = "Order continued:"
e.Graphics.DrawString(strOutput, detailFontBold, detailBrush, x, y)
x += 1.5
strOutput = strOrder02 & strDrinks
e.Graphics.DrawString(strOutput, detailFont, detailBrush, x, y)
e.HasMorePages = False
End Sub
End Class
General Notes
This is probably one of the longest pieces of coding featured on these pages to date, which reflects the relative complexity of the program and the large number of controls used. When the program starts, the only active control is the text box that allows the user to enter a customer's telephone number. This hopefully prevents any duplication of effort by making sure that, if the customer details are already stored in the database, they will automatically be displayed in the left-hand panel of the application. If this is the case, the customer information fields are populated using the stored details, and the fields are disabled to prevent inadvertent changes.
If the caller is a new customer, the user is informed, and may enter the new details in the text fields provided. They can also add the new customer details to the database at any point before the order is cleared, so long as the information entered is complete. Once the customer details have been saved, the input boxes will be disabled to prevent further changes.
Note that the application does not currently include an administrative function to allow customer data to be deleted or updated - this is a program feature that could be added (there are no doubt many improvements that could be made!).
Radio buttons are used to allow the user to select exactly one topping and one base per item, and a pizza cannot be added to the order until both have been selected. These parameters must be specified for each pizza item ordered, and will determine the pizza's basic price. The extras are of course optional (by definition) , so if the user does not select any extras the item can still be added to the order.
Because each customer may want a selection of extras (or even all four options), the choices are determined using check boxes. This allows the user to select any of the four extras, regardless of whether or not other extras have already been selected.
Drinks can be added to the order at any time, and are dealt with separately from the pizza items (although note that until at least one pizza item has been added to the order, no drinks may be selected). Drinks are selected using the NumericUpDown control.
The controls for each type of selection are grouped on their own panel, allowing the selection for drinks (for example) to be enabled or disabled independently of the other controls. It is also important for the radio button controls, since it creates a control group in which only one radio button may be checked at any one time; selecting a different radio button will de-select any previously selected radio button automatically.
The other point of interest concerning the controls is that each group of controls has been set up as a control array with similar characteristics to the control arrays found in Visual Basic 6, allowing them to be accessed and manipulated using program loops. The declarations and initialisation statements for the control arrays can be seen at the top of the form's class definition.
Another interesting feature of the code is the use of a structure to group together the variables that store the pizza selection for each pizza item. The choice of topping and base are both stored as integers, while the extras (which are either selected or not selected) are stored as Boolean variables.
The order details displayed to the user are updated in real time as pizza items or drinks are added to the order, including the order value, delivery charge (if applicable) and order total. One fairly obvious shortcoming with the programming as it stands is that, once added to the order, a pizza item cannot be deleted, which means that if the customer changes their mind half way through an order the user must clear the order and start again. Thanks to the fact that each pizza item is stored in a structure, this shortcoming could be remedied relatively easily (I leave this to those of you with the enthusiasm to develop the program further!). The selection of drinks can be changed dynamically, without requiring the user to start again from scratch.
The only feature of the program that introduces anything radically new to these pages is the ability to print a delivery note (which is after all very important for a pizza delivery program!) The code I have used here is perhaps not the most elegant solution, but it appears to work in the (admittedly limited) tests that I have carried out.
The program has deliberately been limited to 15 pizza items in order to reduce the complexity of the print procedure, which allows for up to seven pizza items (plus drinks) to be printed on a single A4 delivery note. More items (up to fifteen in total not including drinks) can be ordered, and the additional items will be printed on a continuation sheet.
The subject of printing with Visual Basic seems to be the cause of some consternation for some student programmers. Hopefully the code provided here, while it may not be the most efficient solution, will at least provide a starting point for those with similar programming problems to solve.
On a final note, the colour scheme chosen by me is purely arbitrary and will probably give those of you that have studied graphic design nightmares. All I can say is that it seemed like a good idea at the time, and I don't really have much incentive at the present time to go back and redesign the interface. My primary interest, after all, is in the code and making it work. I am under no illusions about my prowess (or lack thereof) as a graphic designer, and gladly defer to those better qualified in this respect.