Restaurant Bill Program

Started by
4 comments, last by Geodude487 14 years, 1 month ago
Hey everybody, I was wondering if somebody could help me out here. I have a restaurant bill program, where the user selects the food from comboboxes and it puts it into a listbox. As it adds to the listbox it updates in realtime the subtotal, the tax amount, and the final total. Well I need to be able to remove these items which I have just my items.remove() to remove it from the listbox but my question is what would be the easiest way to go about trying to update the price given the way I wrote my program b/c I can't figure it out. I'm thinking to get it to work properly I'll have to redesign my code, but I'm asking you guys to try to avoid having to do that. Thanks to anybody who can help me, here is my code.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace RestaurantBill
{
    public partial class frmRestaurantBill : Form
    {
        decimal subTotal = 0.00M;
        decimal taxTotal = 0.00M;
        decimal tax = .07M;
        decimal price = 0.00M;
        decimal total = 0;

        public frmRestaurantBill()
        {
            InitializeComponent();
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void cmbBeverage_SelectedIndexChanged(object sender, EventArgs e)
        {
            string beverage = cmbBeverage.SelectedItem.ToString();

            switch (cmbBeverage.SelectedIndex)
            {
                case 0:
                    lsbMenu.Items.Add(beverage);
                    price = 1.95m;
                    break;
                case 1:
                    lsbMenu.Items.Add(beverage);
                    price = 1.50m;
                    break;
                case 2:
                    lsbMenu.Items.Add(beverage);
                    price = 1.25m;
                    break;
                case 3:
                    lsbMenu.Items.Add(beverage);
                    price = 2.95m;
                    break;
                case 4:
                    lsbMenu.Items.Add(beverage);
                    price = 2.50m;
                    break;
                case 5:
                    lsbMenu.Items.Add(beverage);
                    price = 1.50m;
                    break;
            }

            billTotal(price);
        }//end of cmbBeverage Index Change

        private void cmbAppetizer_SelectedIndexChanged(object sender, EventArgs e)
        {
            string appetizer = cmbAppetizer.SelectedItem.ToString();

            switch (cmbAppetizer.SelectedIndex)
            {
                case 0:
                    lsbMenu.Items.Add(appetizer);
                    price = 5.95m;
                    break;
                case 1:
                    lsbMenu.Items.Add(appetizer);
                    price = 6.95m;
                    break;
                case 2:
                    lsbMenu.Items.Add(appetizer);
                    price = 8.95m;
                    break;
                case 3:
                    lsbMenu.Items.Add(appetizer);
                    price = 8.95m;
                    break;
                case 4:
                    lsbMenu.Items.Add(appetizer);
                    price = 10.95m;
                    break;
                case 5:
                    lsbMenu.Items.Add(appetizer);
                    price = 12.95m;
                    break;
                case 6:
                    lsbMenu.Items.Add(appetizer);
                    price = 6.95m;
                    break;
            }

            billTotal(price);
        }//end of cmbAppetizer Index Change

        private void cmbMainCourse_SelectedIndexChanged(object sender, EventArgs e)
        {
            string mainCourse = cmbMainCourse.SelectedItem.ToString();

            switch (cmbMainCourse.SelectedIndex)
            {
                case 0:
                    lsbMenu.Items.Add(mainCourse);
                    price = 15.95m;
                    break;
                case 1:
                    lsbMenu.Items.Add(mainCourse);
                    price = 13.95m;
                    break;
                case 2:
                    lsbMenu.Items.Add(mainCourse);
                    price = 13.95m;
                    break;
                case 3:
                    lsbMenu.Items.Add(mainCourse);
                    price = 11.95m;
                    break;
                case 4:
                    lsbMenu.Items.Add(mainCourse);
                    price = 19.95m;
                    break;
                case 5:
                    lsbMenu.Items.Add(mainCourse);
                    price = 20.95m;
                    break;
                case 6:
                    lsbMenu.Items.Add(mainCourse);
                    price = 18.95m;
                    break;
                case 7:
                    lsbMenu.Items.Add(mainCourse);
                    price = 13.95m;
                    break;
                case 8:
                    lsbMenu.Items.Add(mainCourse);
                    price = 14.95m;
                    break;
            }

            billTotal(price);
        }

        private void cmbDessert_SelectedIndexChanged(object sender, EventArgs e)
        {
            string dessert = cmbDessert.SelectedItem.ToString();

            switch (cmbMainCourse.SelectedIndex)
            {
                case 0:
                    lsbMenu.Items.Add(dessert);
                    price = 5.95m;
                    break;
                case 1:
                    lsbMenu.Items.Add(dessert);
                    price = 3.95m;
                    break;
                case 2:
                    lsbMenu.Items.Add(dessert);
                    price = 5.95m;
                    break;
                case 3:
                    lsbMenu.Items.Add(dessert);
                    price = 4.95m;
                    break;
                case 4:
                    lsbMenu.Items.Add(dessert);
                    price = 5.95m;
                    break;
            }

            billTotal(price);

        }

        public void billTotal(decimal price)
        {
            subTotal += price;
            txtSubtotal.Text = subTotal.ToString("c");
            taxTotal += subTotal * tax;
            txtTax.Text = taxTotal.ToString("c");
            total = subTotal + taxTotal;
            txtTotal.Text = total.ToString("c");
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            lsbMenu.Items.Clear();
            cmbBeverage.Text = "";
            cmbAppetizer.Text = "";
            cmbMainCourse.Text = "";
            cmbDessert.Text = "";
            txtSubtotal.Text = "$0.00";
            txtTax.Text = "0.00";
            txtTotal.Text = "0.00";
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            lsbMenu.Items.Remove(lsbMenu.SelectedItem);
        }
    }
}
Advertisement
Short answer: Since you're passing around just strings and hard-coded the prices, it's not that straightforward to remedy your problem. You're right, I think it is a good idea to rethink your approach. You have to do an abstraction and group things that belong together. That will make your life much easier.

Long answer:
Since I assume homework/assignment I will give you only hints.

1. Group things together, namely the foods name, its category and its price. In your approach a foods name and its price are separated. This will make it hard to change a foods price.
For that you use a class for instance this way (very bare, and here done lazily, I just want to give you a start):

    public class Food    {        public Food(string name, string category, decimal price)        {            Name = name;            Category = category;            Price = price;        }        public string Name;        public string Category;        public decimal Price;    }


2. Initialize your whole food assortment in one place, for instance in frmRestaurantBills constructor (after InitializeComponent(); ) and fill your controls accordingly.

3. The GUI control you are using actually accept any object in their collections, so you do not need to revert to switch statements and index numbers. This is prone to errors. For the food items to display properly take a look at the documentation of these controls and especially what object.ToString() is for and how you can use it in the Food class.

4. As soon as you are able to move Food objects around (and remove them), you can always (re-)calculate the total sum or do any other computation by iterating over the whole collection. Trigger this with a Change event or manually.

Hope that helps

PS: I hope I did not underestimate you. Please tell us more about your experience with programming. And for further posts, do not only post source code but also describe more detailed what you had in mind when writing it.
You are correct it is a homework assignment, and I had the code working perfectly until my teacher looked at it after he gave us an extension and told me I forgot a way to remove a food item. It is an Advanced C# class, but my thinking with the case statements (this was before I knew we needed to have a way to remove them) was to have it update in real time. Which is why I hard coded the prices and had it choosing the index, looking back at it now probably isn't the best scenario for later upkeep (if needed) but I was trying to finish a quick lab. The lab in the book doesn't even say to have a way to delete it he just added it in. I can't say I quite understand your hint though. What you mean but grouping them together. Before I saw your response I completely altered it so that each group has it's own button (also probably not the best for keeping it neat lol) but from that I was gonna be able to also have a delete button. Not sure how to still get the price which I think I'm still in the same boat I was in before but I don't know lol, and as it is a homework assignment not asking for anybody to do it for me just point me in the right direction b/c if I can't get the remove button to work I'll just turn it in and loose only like 2pts or so. Thank you.
Hmmm, sounds like a programming lessing about GUI's then.

Deleting items from a list box collection is as easy as adding (the usage applies to other collection classes in the .NET Framework as well):
someListBox.Items.Remove(someObejct)

or
someListBox.Items.RemoveAt(index)


To make a button "work" you already have an example in your code (btnExit).

No more clues, these are your 2 points.

Quote:
...was to have it update in real time. Which is why I hard coded the prices...


Let me give you an advice: Optimize last. Not only because computers nowadays are ludicrously fast, but if you focus on speed from the very beginning of solving a problem you lose yourself (which probably actually happened here: you ran into a design flaw). Solve the problem first, concern about speed later, if speed is a problem. By the way: I think in this case you probably gain little that way, you might even lose.
I made exactly this sort of program a few years ago, and apart from important features (logging every order to a database and printing slips) it had some important advantages over yours:

- It loaded food prices, groups and descriptions from a simple text file on startup, creating the sort of objects unbird suggests: there is no reason to modify code for such volatile information.
The only code that is allowed to contain "price = 5.95m;" is that of unit tests, and even unit tests can load such boring data from external files.

- It maintained a proper order data model with the ordered quantity of every item in the menu, without piggybacking on particular GUI widgets; the menu itself was represented by an Order object with all quantities set to 0.
A collection of what has been ordered is a poor data model because finding items to remove or alter is awkward.

- It dynamically built a practical and space-efficient GUI in which every food (grouped in arbitrary categories represented by tabbed panels) had a combination of a large button (containing the description and linked to the command of ordering one), a text field with a spinner for the currently ordered quantity (both display and input) and a read-only label with the unit price. In other words, several redundant ways to change the ordered quantity of an item on the menu, not to select or add it somewhere.
A separate read-only table listed the whole order, a label near the "print" button the total.
Listboxes trade reduced size for increased clicking and fumbling, which might be a good deal in crowded forms or with very long sorted lists but not for this application.

An example of the menu file format I used:

BeveragesKrug 95.00Veuve Clicquot (magnum) 144.00Sparkling water 75 cl 2.20Gratuitous caloriesSmall French Fries 3.00Large French Fries 4.50Chocolate Milkshake 4.00

Empty lines are ignored; if there is a number at the end of the line it is the price and everything before is a food description; if there isn't a number the whole line is the name of a section; sections and items within a section are kept in the order in which they appear.

Omae Wa Mou Shindeiru

turns out there was a whole lot eaiser way to do this program, (at least for what I needed it to do) I just took the selected lstBox item turned to a string, substring split it at "$" and parsed the number because after the $ all thats left is the price then I can do all my arithmetic from that since that's the price that I would want to delete. thank you to everybody who helped out and gave advice.

This topic is closed to new replies.

Advertisement