Calculate subtotal, sales tax, and order total - c#

Okay, so I'm sure this has been asked before but I can't seem to find anything in relation. I'm trying to create an assignment for school. It's a lunch order menu where you can place your order. We have to calculate the subtotal, the sales tax, and the order total. I can't seem to figure out the right code to use and I'm not 100% sure on what to try here.
public partial class Form1 : Form
{
decimal subtotal = 0m;
decimal salesTax = 0m;
decimal orderTotal = 0m;
public Form1()
{
InitializeComponent();
rdoBurger.Checked = true;
rdoPizza.Checked = true;
rdoSalad.Checked = true;
}
private void btnExit_Click(object sender, EventArgs e)
{
Close();
}
private void clearTotals()
{
}
private void btnPlaceOrder_Click(object sender, EventArgs e)
{
if (sender is RadioButton)
{
clearTotals();
}
if (rdoBurger.Checked)
{
decimal subtotal = 6.95m;
subtotal = Convert.ToDecimal(lblSubtotal.Text);
}
This is what I have but it's not showing the actual subtotal, it's still blank. What am I missing here?

It's not a bad start. This is more like what I'd expect to see:
private void btnPlaceOrder_Click(object sender, EventArgs e)
{
// only ONE of these can be checked, so "else if" is used
if (rdoBurger.Checked)
{
subtotal = 6.95m;
}
else if (rdoPizza.Checked)
{
subtotal = 5.95m;
}
else if (rdoSalad.Checked)
{
subtotal = 4.95m;
}
// multiple of these could be checked, so only "if" is used
if (checkBox1.Checked)
{
subtotal = subtotal + 100.00m; // whatever this item costs
}
if (checkBox2.Checked)
{
subtotal = subtotal + 4.99m; // whatever this item costs
}
if (checkBox3.Checked)
{
subtotal = subtotal + 10.99m; // whatever this item costs
}
// compute the tax and the total:
salesTax = subtotal * 0.0775m;
orderTotal = subtotal + salesTax;
// output it to your labels/textboxes?
lblSubtotal.Text = "$" + subtotal.ToString("F2");
lblSalesTax.Text = "$" + salesTax.ToString("F2");
lblOrderTotal.Text = "$" + orderTotal.ToString("F2");
}

Radio buttons can only have a single button selected at a time in a container. In this case it appears that the GroupBox is the container. If you had several groups of radio buttons you could use GroupBox as a container and have one radio button selected in each GroupBox. So, you cannot set all the radio buttons checked property to true.
In your btnPlaceOrder_Click the sender can not posibly be a radio button. The sender is the button that was clicked to run the event code.
private void button1_Click(object sender, EventArgs e)
{
//Find the radio button that is selected
RadioButton rButton = groupBox1.Controls.OfType<RadioButton>().FirstOrDefault(r => r.Checked == true);
switch (rButton.Text)
{
case "Hamburger - $6.95":
subTotal = 6.95m;
break;
case "Pizza - $5.95":
subTotal = 5.95m;
break;
case "Salad - $4.95":
subTotal = 4.95m;
break;
}
//Add code to handle Add-on items
//For example - The first check box is "Add Onions" - $0.50
if (checkBox1.Checked)
subTotal += .5m;
lblSubTotal.Text = subTotal.ToString();
decimal tax = subTotal * .0775m;
lblTax.Text = tax.ToString();
decimal total = subTotal + tax;
lblTotal.Text = total.ToString();
}

Related

C# Program is Getting Stuck in a void Method

I'm writing a C# program using windows forms that acts as a cash register where the user enters in the item, quantity, and cost. It then displays the entry in a listbox and display the subtotal, calculated tax, and calculated total in 3 other text boxes. It works fine on the first entry, even though I notice it goes through the method to calculate and display subtotal twice when I run in debug. When I go to enter a second item and recalculate the subtotal the program will crash, and when ran in debug will continually loop through the method to calculate and update the text box I'm using for subtotal. It does calculate the new subtotal in the variables as it loops through the method, it just doesn't leave the method. I call this method inside the method that handles the button click event to add items to the list. I've included the code, any suggestions would be greatly appreciated.
private void textBox4_TextChanged(object sender, EventArgs e)
{
itemTotal = Decimal.Multiply(quantityValue, costValue);
if (itemCount == 1)
{
subtotal = itemTotal;
}
if (itemCount > 1)
{
subtotal = Decimal.Add(itemTotal, subtotal);
}
textBox4.Text = subtotal.ToString();
}
double total =0;
double subtotal = 0;
double tax = 0;
double taxrate = 0.14;
private void button1_Click(object sender, EventArgs e)
{
int qnt = int.Parse(qnttextBox.Text);
double price = double.Parse(pricetextBox.Text);
subtotal = subtotal +(qnt * price);
subtextBox.Text = subtotal.ToString();
tax = subtotal * taxrate;
taxtextBox.Text = tax.ToString();
total = subtotal + tax;
totaltextBox.Text = total.ToString();
StringBuilder builder = new StringBuilder(nametextBox.Text + " " + qnttextBox.Text + " " + pricetextBox.Text);
listBox1.Items.Add(builder);
}

How do I display the contents of an array without having the "0"'s in the display using a foreach loop?

public partial class frmEnhancedInvoiceTotal : Form
{
public frmEnhancedInvoiceTotal()
{
InitializeComponent();
}
private void BtnExit_Click(object sender, EventArgs e)
{
Close();
}
decimal[] decTotalofInvoicesArray = new decimal[5];
int intNumberOfInvoices = 0; //global variables
decimal decTotalOfInvoicesVariable = 0m;
decimal decAverageOfInvoices = 0m;
private void BtnCalculate_Click(object sender, EventArgs e)
{
//Convert = Class, .ToDecimal = method,
//when the user clicks the calulate button,
//we collect the subtotal, determine the appropriate discount,
//calculate the total and output the result to the screen.
//***EARN PARTIAL CREDIT PUT COMMENTS***
//Input
try
{
decimal decSubtotal = 0m; //initialize subtotal with a value of zero. We'll collect from the user later.
if (Decimal.TryParse(txtSubtotal.Text,
System.Globalization.NumberStyles.Currency, //now can type a $ sign and now break the code
System.Globalization.CultureInfo.CurrentCulture,
out decSubtotal)) //.tryparse attempts to convert but is a fail safe
//parse does 2 things - does something and tells you if works
decTotalofInvoicesArray[intNumberOfInvoices] = decSubtotal;
{
//Processing
decimal decDiscountPercent = 0m; //defining a new variable (discount percent) allow for real #, giving it a intial value of 0. Decimal variables you have to add m
if (decSubtotal >= 500m) //if my subtotal is 500 or more
{
decDiscountPercent = 0.2m; //inside braces is what will happen to the question above
//set discount rate to 20%
}
else if (decSubtotal < 500m && decSubtotal >= 250m) //if subtotal is between 250 & 500
//^^redundant because < 500 is already stated in the first if statement
//could just right else if(decSubtotal >=250m)
{
decDiscountPercent = 0.15m; //set discount rate to 15%
}
else if (decSubtotal < 250m && decSubtotal >= 100m) //if subtotal is between 100 and 250
{
decDiscountPercent = 0.1m; //set discount to 10%
}
//if subtotal is less than 100, dicounter percent is 0%
decimal decDiscountAmount = decDiscountPercent * decSubtotal;
decimal decTotal = decSubtotal - decDiscountAmount; //He is going so fast
//Aggregate Processing - across mutliple clicks of the calculate button
//old way of doing it = intNumberOfInvoices = intNumberOfInvoices + 1;
intNumberOfInvoices++; //value of variable plus one
//old way of doing it decTotalOfInvoices = decTotalOfInvoices + decTotal;
decimal decSum = 0m;
for (int intColIndex = 0; intColIndex < decTotalofInvoicesArray.Length; intColIndex++)
{
decSum += decTotalofInvoicesArray[intColIndex];
}
decTotalOfInvoicesVariable = decSum;
decAverageOfInvoices = decSum / decTotalofInvoicesArray.Length;
//Output
txtSubtotal.Text = decSubtotal.ToString("c");
txtDiscountPercent.Text = decDiscountPercent.ToString("p2"); //sending a numeric value and sending it to text = gives error
txtDiscountAmount.Text = decDiscountAmount.ToString("c"); //dot ToString makes value a text value and sends to textbox in form
//c=currency //"p2" - 2 = how many decimal places
//P = percentage
txtTotal.Text = decTotal.ToString("c");
//aggregate output
txtNumberOfInvoices.Text = intNumberOfInvoices.ToString();
txtTotalOfInvoices.Text = decTotalOfInvoicesVariable.ToString("c");
txtAverageOfInvoices.Text = decAverageOfInvoices.ToString("c");
//breakpoint analysis = click on the grey side bar and slowly work through the code to find the error. Essentially pause the code and run the code one point at a time
}
}
catch (FormatException) //you do not know what went wrong in the try part. It just errors anyways because SOMETHING went wrong
{
MessageBox.Show("Please enter valid numeric values.", "Entry Error");
}
catch (OverflowException) //something is to big
{
MessageBox.Show("Please try smaller numbers", "Entry Error");
}
catch //generic error code because why not
{
MessageBox.Show("An unexpected error has occured. Please try again.", "Entry Error");
}
}
private void BtnClearTotals_Click(object sender, EventArgs e)
{
//When resetting aggregate/global info - need to reset the variables AND the visual interface
intNumberOfInvoices = 0;
decTotalOfInvoicesVariable = 0m;
decAverageOfInvoices = 0m;
// txtNumberOfInvoices.Text = ""; //setting the variable to nothing. Erase the information in the text box
txtNumberOfInvoices.Clear();
txtTotalOfInvoices.Clear();
txtAverageOfInvoices.Clear();
}
private void TxtSubtotal_TextChanged(object sender, EventArgs e)
{
txtDiscountPercent.Clear();
txtDiscountAmount.Clear();
txtTotal.Clear();
}
private void BtnDisplayTotals_Click(object sender, EventArgs e)
{
String strOrderTotals = "";
//for (int intColIndex = 0; intColIndex < intNumberOfInvoices; intColIndex++)
//{
// strOrderTotals += decTotalofInvoicesArray[intColIndex] + "\n";
//}
foreach (decimal decTotalInvoices in decTotalofInvoicesArray)
{
if (strOrderTotals == "0")
{
strOrderTotals += decTotalInvoices + "\n";
}
}
MessageBox.Show(strOrderTotals.ToString());
}
private bool IsValidData()
{
return
IsPresent(txtSubtotal) && //did you type anyting
IsDecimal(txtSubtotal) && //make sure you types a real number
IsWithinRange(txtSubtotal, 0m, 1000m); //is the number in the range
}
private bool IsPresent(TextBox textBox) //send an entire textbox into method
{
if (textBox.Text == "")
{
MessageBox.Show(textBox.Tag.ToString() + " is a required field.", "Missing Entry"); //textbox is whatever is in the (TextBox textBox)
textBox.Focus();
return false;
}
return true;
}
private bool IsDecimal(TextBox textBox)
{
decimal decTestValue = 0m;
if (!Decimal.TryParse(textBox.Text, out decTestValue)) //! - dont succusfully tryparse
{
MessageBox.Show(textBox.Tag.ToString() + " must be a numeric value", "Entry Error"); //textbox is whatever is in the (TextBox textBox)
textBox.Focus();
return false;
}
return true;
}
private bool IsInteger(TextBox textBox)
{
int intTestValue = 0;
if (!Int32.TryParse(textBox.Text, out intTestValue)) //! - dont succusfully tryparse
{
MessageBox.Show(textBox.Tag.ToString() + " must be a whole number.", "Missing Entry"); //textbox is whatever is in the (TextBox textBox)
textBox.Focus();
return false;
}
return true;
}
private bool IsWithinRange(TextBox textBox, decimal decMin, decimal decMax)
{
decimal decTestValue = Convert.ToDecimal(textBox.Text);
if (decTestValue < decMin || decTestValue > decMax) //to small or to big
{
MessageBox.Show(textBox.Tag.ToString() + " must be between " + decMin.ToString() + " and " + decMax.ToString() + "." + "Out of Range"); //textbox is whatever is in the (TextBox textBox)
textBox.Focus();
return false;
}
return true;
}
}
}
Basically I have a invoice total windows form were the user inputs a subtotal value and total value is calculated based on the discount percent. In the assignment is says to create an array that hold up to five invoice totals. My problem is when I type lets say 2 subtotal values and click display totals the 2 number I typed in are displayed along with 3 zeros. I am wanting to know how to only display the number I inputted and not the zeros using a foreach loop.
It does not look like you are adding anything in your foreach.
foreach (decimal decTotalInvoices in decTotalofInvoicesArray)
{
if (strOrderTotals == "0")
{
strOrderTotals += decTotalInvoices + "\n";
}
}
MessageBox.Show(strOrderTotals.ToString());
Am I reading this right that you want to have each invoice shown, and do you want the total too? This code with a for loop should work. I
strOrderTotals = "My Invoices\n";
decimal decOrderTotals = 0;
for (int i = 0; i < decTotalofInvoicesArray.Length; i++)
{
if (decTotalofInvoicesArray[i] != 0)
{
strOrderTotals += "Invoice : " + decTotalofInvoicesArray[i] + "\n";
decOrderTotals += decTotalofInvoicesArray[i];
}
}
strOrderTotals += "Total of invoices: " + decOrderTotals;
MessageBox.Show(strOrderTotals.ToString());

How to make a condition out of the selected listbox item?

I can't believe I got drained by this small problem trying to find the solution playing with the intellisense. No luck Just starting c# GUI. Just need a quick answer please.
if (listBox1.SelectedValue== "Chicken")
{
total += 15;
ord += " Chicken";
label4.Text = "chicken selected";
}
what the hell is wrong with this.
I want to execute the statements when the user selected the item "chicken" from listbox1.
public partial class Form1 : Form
{
double total = 0;
int x = 0;
string ord = "";
private void placeToolStripMenuItem_Click(object sender, EventArgs e)
{
checkBox1.Checked = false;
radioButton1.Checked = false;
radioButton2.Checked = false;
radioButton3.Checked = false;
radioButton4.Checked = false;
listBox1.SelectedItems.Clear();
if (checkBox1.Checked)
{
total += 1;
ord += " Water";
}
if (checkBox1.Text == "Extra Meat")
{
total += 1;
ord += ord+" Extra Meat ";
}
if (comboBox1.Text == "Extra Rice")
{
total += 1;
ord += " Extra Rice";
}
if (comboBox1.Text == "Extra Veggies")
{
total += 1;
ord +=" Extra Veggies";
}
if (listBox1.SelectedValue== "Chicken")
{
total+=15;
ord+=" Chicken";
label4.Text = "chicken selected";
}
if (listBox1.Text == "Pizza $8") //< my pathetic attempt to figure it out with intelisense
{
total+=8;
ord+="Pizza ";
label4.Text = "qwe";
}
if (listBox1.SelectedItem == "Spaghetti $12")//< my pathetic attempt to figure it out with intelisense
{
total+=12;
ord+=" Spaghetti";
}
if (listBox1.SelectedItem == "Fries $8")
{
total+=8;
ord+=" Fries";
}
if (listBox1.SelectedItem == "Burger $10")
{
total+=10;
ord+=" Burger";
}
//radiobutton
if (radioButton1.Checked)
{
total+=5;
ord += " Pineapple Juice";
}
if (radioButton2.Checked)
{
total+=6;
ord += " Mango Juice";
}
if (radioButton3.Checked)
{
total+=7;
ord += " Apple Juice";
}
if (radioButton4.Checked)
{
total+=8;
ord += " Orange Juice";
}
MessageBox.Show("Order Done");
}
private void clearToolStripMenuItem_Click(object sender, EventArgs e)
{
ord = "";
total = 0;
}
private void displayToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Order: " + ord+"\nTotal: "+total);
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
}
You code cannot work, since you clear all the selections before you are processing the order. Move this code to the very end of the placeToolStripMenuItem_Click method:
// Process the order here ...
MessageBox.Show("Order Done");
checkBox1.Checked = false;
radioButton1.Checked = false;
radioButton2.Checked = false;
radioButton3.Checked = false;
radioButton4.Checked = false;
listBox1.SelectedItems.Clear();
I think that your approach is wrong. You should not have to make all these if-statements. Instead create a Product class
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
public override ToString()
{
return String.Format("{0} ${1}", Name, Price);
}
}
Then add products to your listbox:
listbox1.Items.Add(new Product{ Name = "Chicken", Price = 15 });
listbox1.Items.Add(new Product{ Name = "Pizza", Price = 8 });
...
Then you can work with the selected item like this:
var product = listBox1.SelectedItem as Product;
if (product != null) {
total += product.Price;
ord += " " + product.Name;
label4.Text = product.Name + " selected";
}
Also declare total as decimal. Doubles are good for scientific calculations, but can easily yield results like 7.49999999 instead of 7.5. Decimals have been introduced especially for currency calculations. They are not very fast but they don't convert decimal numbers into binary numbers internally, instead the decimal digits are preserved. The problem with binary numbers is that for instance 1/10 cannot be represented accurately just like 1/3 cannot be represented accurately in the decimal system.
You can even add products to your radio buttons
radioButton3.Tag = new Product{ Name = "Apple Juice", Price = 7 };
A more advanced method would be to create your own radio button control with a Product property, but this solution will do it for now.
Then you can loop through all your radio buttons like this
foreach (var radioButton in Controls.OfType<RadioButton>()) {
if (radioButton.Checked) {
var p = (Product)radioButton.Tag;
total += p.Price;
ord += " " + p.Name;
}
}
You need to use SelectedItem.
if (listBox1.SelectedItem == "Chicken")
My program is throwing a Nullreferenceexception on me.
on this line:
if (listBox1.SelectedItem.ToString() == "Chicken $15")
I have to initialize it i guess but i have no idea how to initialize a listBox.
First Method:
if (listBox1.SelectedIndex != -1) //first check if any item is selected
if (listBox1.SelectedItem.ToString() == "Chicken")
Second Method:
if (listBox1.Text == "Chicken")
and just remove the line:
private void placeToolStripMenuItem_Click(object sender, EventArgs e)
{
listBox1.SelectedItems.Clear(); //remove this line
It clears your selected items, that's why you are not getting into any if condition.

C# form - Checkboxes

I'm wondering how to restrict my checkbox from adding to my listbox. At the moment when the user checks the checkbox it will add "Anchovies" to the listbox. What I don't want to happen is when the user deselects the checkbox and re selects it again, "Anchovies" is added to the listbox again (showing two lots of "Anchovies").
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
listBox1.Items.Add("Anchovies");
double total = Convert.ToDouble(textBox2.Text);
total = total + .5;
textBox2.Text = Convert.ToString(total);
}
}
The key is to check if Anchovies already exists on the listBox1 items.
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
//If the item is already there, we don't do anything.
if (!listBox1.Items.Contains("Anchovies")) {
listBox1.Items.Add("Anchovies");
double total = Convert.ToDouble(textBox2.Text);
total = total + .5;
textBox2.Text = Convert.ToString(total);
}
}
}
Do it this way
if (checkBox1.Checked)
{
if(!listBox1.Items.Contains("Anchovies"))
listBox1.Items.Add("Anchovies");
double total = Convert.ToDouble(textBox2.Text);
total = total + .5;
textBox2.Text = Convert.ToString(total);
}
To fix this issue, you need to check your list box(for this value, either it is already there or not) before inserting any value in it.
e.g
foreach (var item in listBox1.Items )
{
if(item.ToString() != "Anchovies")
{
listBox1.Items.Add("Anchovies");
}
// other code here.
}

Output label shows only part of what I want to display

I have this program that I am working on for class, I think the problem is in my if statements. When I run the program and make my selection and click the total button and I get this as a display "for your appetizer, for your entree, and for dessert" in the order label and the price for the steak dinner in the order total label. I think I may have to use switch statements, but I'm not sure any suggestions would be of great help, thanks.
namespace Restaurant
{
public partial class frmRestaurant : Form
{
decimal AppetizerPrice = 0.0m;
decimal EntreePrice = 0.0m;
decimal DessertPrice = 0.0m;
decimal total = 0.0m;
string AppetizerOrder = "", EntreeOrder = "", DessertOrder = "", order = "";
public frmRestaurant()
{
InitializeComponent();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btnTotal_Click(object sender, EventArgs e)
{
CalculateTotal();
Order();
lblOrder.Text = order;
lblTotal.Text = total.ToString();
}
private void grpAppetizer_Enter(object sender, EventArgs e)
{
if (radCheeseSticks.Checked)
{
AppetizerPrice = 5.99m;
AppetizerOrder = "Cheese Sticks";
}
else if (radGarlicBread.Checked)
{
AppetizerPrice = 4.50m;
AppetizerOrder = "Garlic Bread";
}
else if (radChipsnSalsa.Checked)
{
AppetizerPrice = 3.50m;
AppetizerOrder = "Chips and Salsa";
}
}
private void grpEntree_Enter(object sender, EventArgs e)
{
if (radSteakDinner.Checked)
{
EntreePrice = 12.50m;
EntreeOrder = "Steak Dinner";
}
else if (radChickenParm.Checked)
{
EntreePrice = 10.99m;
EntreeOrder = "Chicken Parmigiana";
}
else if (radChipsnSalsa.Checked)
{
EntreePrice = 3.50m;
EntreeOrder = "Chips and Salsa";
}
}
private void grpDessert_Enter(object sender, EventArgs e)
{
if (radSteakDinner.Checked)
{
DessertPrice = 12.50m;
DessertOrder = "Steak Dinner";
}
else if (radChickenParm.Checked)
{
DessertPrice = 10.99m;
DessertOrder = "Chicken Parmigiana";
}
else if (radChipsnSalsa.Checked)
{
DessertPrice = 3.50m;
DessertOrder = "Chips and Salsa";
}
}
public decimal CalculateTotal()
{
total = AppetizerPrice + EntreePrice + DessertPrice;
return total;
}
public string Order()
{
order = AppetizerOrder + "for your appetizer," + EntreeOrder + "for your entree, and " + DessertOrder + "for dessert";
return order;
}
}
}
I think the GroupBox.Enter event is not useful for your use case. The enter event is invoked sometime during the control activation, but not when the value is changed.
One way to fix your problem is to set the appetizer/entree/dessert price and text only when the "Total" button is clicked. You do not need it before that in the current form right now.
Another way to fix it is to use the correct event: Just handle the RadioButton.CheckedChanged event for all of those radio buttons, for example:
private void radGarlicBread_CheckedChanged(object sender, EventArgs e)
{
if (radGarlicBread.Checked)
{
AppetizerPrice = 4.50m;
AppetizerOrder = "Garlic Bread";
}
}
First of all, you probably want to use String.Format(), because it'll look a bit cleaner than a bunch of concatenation--it'll also help you catch things like the lack of spaces here (your output seems like it would be, e.g. 'Chips and Salsafor your appetizer...')
It might also be better to just find whichever item is checked in the Order method rather than update it every time the user checks.
I'm not sure what is wrong, but maybe you can do a Debug.WriteLine() every time each of the Enter() methods is called to see what is going on.
For example:
Debug.WriteLine("grpDesert_Enter");
Debug.WriteLine(radSteakDinner.Checked);
Debug.WriteLine(radChickenPark.Checked);
Debug.WriteLine(radChipsnSalsa.Checked);

Categories

Resources