SHOPIING CART UI/ CREDIT CARD VALIDATION I have the code below,i cant get it to
ID: 3689539 • Letter: S
Question
SHOPIING CART UI/ CREDIT CARD VALIDATION
I have the code below,i cant get it to run. need help fixing the problem. i am not sure why it is not working. Please help me find out why it is not running.
Point of Sale UI
Point of sale interfaces are designed to simplify the process of making transactions, often in a retail environment. We often see them used in restaurants where managers can input the menu and waiters can quickly enter customer orders, which are transmitted to the kitchen and recorded. Modern systems usually include a touchscreen interface, which we will simulate with a mouse-based GUI.
The program you should design and build will read a menu from a text file formatted with a menu item and a price separated by a |. To simplify your text-parsing code, we will omit the dollar sign from the price.
For example:
The program should load the file at launch and create a panel full of large buttons (ideal for a touchscreen) for each menu item. A waiter should be able to click on each menu item to add it to the current order. This should add the item to a receipt panel which displays the full order and the total cost. The total cost should be accurate at all times, updated as each item is added (not only when the order is finalized).
The system only takes credit card as payment type however it can handle/validate multiple types of credit cards. (Please see credit card section below).
The waiter should be able to click a “Place Order” button that simulates transmitting the order to the kitchen by printing the order to System.out (in addition to showing the confirmation on screen). You should also include a “Clear” button that will clear the current order (used when a waiter makes a mistake and needs to start over).
Credit Card
In your system you have the following class structure for the credit cards:
a class CreditCard,
classes VisaCC, MasterCC, AmExCC that are all subclasses of CreditCard,
you assume more subclasses for other credit card types will be added later on.
You now have to design the method(s) (and maybe additional classes) that verifies that the credit card number is a possible account number, and creates an instance of the appropriate credit card class.
Important details: Credit card numbers cannot exceed 19 digits, including a single check digit in the rightmost position. The exact algorithm for calculating the check digit as defined in ISO 2894/ANSI 4.13 is not important for this assignment. You can also determine the card issuer based on the credit card number:
Explanation / Answer
McPatterns.java
public class McPatterns {
public static void main(String[] args) {
McPatternsGUI gui = new McPatternsGUI(new McPatternsPresenter(args));
}
}
McPatternsGUI.java
import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
class McPatternsGUI extends JFrame {
private McPatternsPresenter presenter;
private JTextArea currentOrder;
private static final String NO_MENU = "If you are reading this message, that means no menu file was read, and it's probably your fault.";
/**
* Disabling the default constructor.
*/
private McPatternsGUI() {}
/**
* Constructor attaching a presenter, setting up the window and showing it.
*/
public McPatternsGUI(McPatternsPresenter presenter) {
this.presenter = presenter;
presenter.attachView(this);
presenter.loadMenuItems();
makeGUI();
showGUI();
}
/**
* Make GUI elements. Set window layout. Title, menu, order panel.
*/
private void makeGUI() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new BorderLayout());
makeTitle();
makeMenu(presenter.getItems());
makeOrderPanel();
}
/**
* Makes and adds a title at the top of the screen.
*/
private void makeTitle() {
JPanel title = new JPanel(new FlowLayout());
title.add(new JLabel("Welcome to McPatterns"));
this.add(title, BorderLayout.NORTH);
}
/**
* Makes order item buttons from a Set of Strings.
* Attches an ActionListener for click and arranges in a grid.
*/
private void makeMenu(Set<String> items) {
JPanel panel;
// If no items are loaded, notify user.
if (items.size() == 0) {
panel = new JPanel(new GridLayout(3,3));
String label = "<html><body>" + NO_MENU + "</body></html>";
for (int i = 0; i < 9; i++)
panel.add(new JLabel(label));
}
// Otherwise, make grid panel, add buttons.
else {
int cols = (int)Math.ceil(Math.sqrt(items.size()));
panel = new JPanel(new GridLayout(cols, cols));
// One listener fits all.
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
presenter.addToOrder(((JButton)e.getSource()).getText());
}
};
// Add the buttons.
for (String item : items) {
JButton btn = new JButton(item);
btn.addActionListener(listener);
panel.add(btn);
}
}
// Add to window.
this.add(panel, BorderLayout.CENTER);
this.pack();
}
/**
* Build the order panel. Add title, TextArea, and two buttons.
*/
private void makeOrderPanel() {
// Submit button.
JPanel orderButtons = new JPanel(new GridLayout(1,2));
JButton confirm = new JButton("Place Order") {
@Override // Make it square.
public Dimension getPreferredSize() {
int width = this.getParent().getWidth() / 2;
return new Dimension(width, width);
}
};
confirm.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
placeOrder();
}
});
orderButtons.add(confirm);
// Cancel button.
JButton cancel = new JButton("Cancel") {
@Override // Make it square.
public Dimension getPreferredSize() {
int width = this.getParent().getWidth() / 2;
return new Dimension(width, width);
}
};
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (presenter.getOrderItemCount() != 0)
if (0 == JOptionPane.showConfirmDialog((Component)e.getSource(), "Cancel order?", "Cancel order?", JOptionPane.YES_NO_OPTION)) {
presenter.cancelOrder();
currentOrder.setText("");
}
}
});
orderButtons.add(cancel);
// Order panel.
JPanel orderPane = new JPanel();
orderPane.setLayout(new BorderLayout());
orderPane.setBorder(BorderFactory.createRaisedBevelBorder());
// Label.
JLabel yourOrder = new JLabel("Your order");
yourOrder.setHorizontalAlignment(SwingConstants.CENTER);
orderPane.add(yourOrder, BorderLayout.NORTH);
// Receipt area.
currentOrder = new JTextArea();
currentOrder.setEditable(false);
// I was a little unsure about the MONOSPACED, but it turns out that Java,
// internally, sets the font to Courier New if on Windows, which is monospaced.
currentOrder.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
currentOrder.setText(" "); // Ensure width.
// Add to panel and window.
orderPane.add(currentOrder, BorderLayout.CENTER);
orderPane.add(orderButtons, BorderLayout.SOUTH);
this.add(orderPane, BorderLayout.EAST);
}
/**
* Displays the built window in full screen.
*/
private void showGUI() {
this.pack();
this.setVisible(true);
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
}
/**
* If the number of items is not zero, verify card and pass it to presenter.
*/
private void placeOrder() {
if (presenter.getOrderItemCount() != 0) {
CreditCard card = new InvalidCard();
String prompt = ""Swipe" the card.";
do {
// Prompt for card number.
String number = (String)JOptionPane.showInputDialog(this, prompt, "Complete the order.", JOptionPane.PLAIN_MESSAGE);
// Cancel payment.
if (number == null) {
JOptionPane.showMessageDialog(this, "Order completion canceled.", "Payment canceled.", JOptionPane.WARNING_MESSAGE);
return;
}
// Make card.
card = CreditCardFactory.build(number);
// Change prompt expecting a repetition.
prompt = "Invalid card. "Swipe" the card again.";
} while (card.getNumber() == null);
// Now that card is valid.
presenter.submitOrder(card);
JOptionPane.showMessageDialog(this, "Paid using " + card.getName(), "Order complete.", JOptionPane.PLAIN_MESSAGE);
}
}
/**
* Presenter will call this method to populte the TextArea in this case.
*/
void printOrder(String text) {
currentOrder.setText(text);
}
/**
* Presenter calls this if there an error. Menu file could not be read, for example.
*/
void error(String message) {
JOptionPane.showMessageDialog(this, message, "There's been a problem.", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
}
McPatternsPresenter.java
import java.util.*;
class McPatternsPresenter {
private static final int FIRST_ORDER_NUMBER = 101;
private static final double SALES_TAX = 7.5; // Sales tax as a percentage.
private MenuModel model;
private String[] menuFileNames;
private McPatternsGUI view;
private ArrayList<OrderItem> currentOrder = new ArrayList<OrderItem>();
private int orderNumber;
private float orderTotal = 0;
/**
* Inner class for name/price pair, for the lack of Pair class in Java.
*/
private class OrderItem {
String name;
Integer count;
private OrderItem(String name, Integer count) {
this.name = name;
this.count = count;
}
}
/**
* Disabled default constructor.
*/
private McPatternsPresenter() {}
/**
* Constructor, receiving a list of the menu files.
*/
McPatternsPresenter(String[] args) {
menuFileNames = args;
orderNumber = FIRST_ORDER_NUMBER;
}
/**
* Attaches a view to the presenter, so it can communicate back.
*/
void attachView(McPatternsGUI view) {
this.view = view;
}
/**
* Calls MenuModel and gives it the list of filenames to
* process as menu items.
* If an error is encountered, call error() in view.
*/
void loadMenuItems() {
try {
model = new MenuModel(menuFileNames);
menuFileNames = null;
}
catch (MenuModel.MenuModelException e) {
view.error(e.getMessage());
}
}
/**
* Getter
*/
Set<String> getItems() {
return model.getItemsList();
}
/**
* Adds an item by name to order. It maches the name with a price.
* If an item with that name is in the order already, just increase the count.
*/
void addToOrder(String itemName) {
for (OrderItem oi : currentOrder)
if (oi.name.equals(itemName)) {
oi.count++;
orderTotal += model.getPrice(oi.name);
printOrder();
return;
}
currentOrder.add(new OrderItem(itemName, 1));
orderTotal += model.getPrice(itemName);
// Print order to view.
printOrder();
}
/**
* Submits the order by printing out to the kitchen and server log.
*/
void submitOrder(CreditCard card) {
// This does nothing. Prices are stored as pennies.
card.charge(orderTotal*0.01);
// Make a string of the items in the order.
StringBuilder itemsList = new StringBuilder(currentOrder.size());
for (OrderItem oi : currentOrder)
itemsList.append(String.format("%4dx %-20s ", oi.count, oi.name));
String itemsString = itemsList.toString();
// Print to kitchen.
System.out.println(" HELLO, KITCHEN PEOPLE!");
System.out.println("----------------------");
System.out.println(" ORDER NUMBER " + orderNumber);
System.out.println("----------------------");
System.out.print(itemsString);
System.out.println("----------------------");
// Save in server log.
System.out.println(" ----------------------");
System.out.println(" WRITE IN PROGRAM LOG ");
System.out.println("----------------------");
System.out.println(" Order number: " + orderNumber);
System.out.println(" CC: " + card.getNumber());
System.out.println(" Date: " + (new Date()).toString());
System.out.print(itemsString);
System.out.println("----------------------");
// Next order, wipe this one.
orderNumber++;
cancelOrder();
}
/**
* Cancels order by clearing the currentOrder list.
*/
void cancelOrder() {
currentOrder.clear();
orderTotal = 0;
}
/**
* Returns the number of items to the view.
*/
int getOrderItemCount() {
return currentOrder.size();
}
/**
* Produces a string resembling a receipt and sends it to the view.
* Prices are stored as pennies, so they need to be multiplied by 0.01 before printing.
*/
void printOrder() {
StringBuilder output = new StringBuilder();
output.append(String.format(" ORDER NUMBER: %4d ", orderNumber));
for (OrderItem oi : currentOrder) {
float price = model.getPrice(oi.name) * oi.count;
output.append(String.format("%4dx %-20s%8.2f ", oi.count, oi.name, price));
}
output.append(" ----------------------------------- ");
output.append(String.format(" Subtotal: %8.2f ", orderTotal));
output.append(String.format(" Tax: %8.2f ", orderTotal*0.01*SALES_TAX));
output.append(String.format(" Total: %8.2f ", orderTotal*(1 + 0.01*SALES_TAX)));
view.printOrder(output.toString());
}
}
MenuModel.java
import java.util.*;
import java.io.*;
class MenuModel {
public static final String NO_OPEN_FILE = "Unable to open menu file.";
public static final String BAD_FORMAT = "Menu file format not recognised.";
// This is where we hold the menu.
private Map<String,Float> menu;
/**
* Inner class for exceptions.
*/
class MenuModelException extends Exception {
private String message;
MenuModelException(String msg) {
super(msg);
}
}
/**
* Disabling default constructor.
*/
private MenuModel() {}
/**
* Constructor expects a list of filenames which to load and parse.
*/
MenuModel(String[] filenames) throws MenuModelException {
menu = new HashMap<String, Float>();
try {
// Attempt to read menu files.
for (int i = 0; i < filenames.length; i++) {
Scanner scan = new Scanner(new File(filenames[i]));
while (scan.hasNext()) {
String line = scan.nextLine();
String[] words = line.split("\|");
menu.put(words[0], Float.parseFloat(words[1]));
}
scan.close();
}
}
// If file wasn't found or couldn't open.
catch (FileNotFoundException e) {
throw new MenuModelException(NO_OPEN_FILE + " " + e.getMessage());
}
// If read line did not split into two, because it didn't contain '|'
catch (ArrayIndexOutOfBoundsException e) {
throw new MenuModelException(BAD_FORMAT);
}
// If the string after the '|' doesn't parse as a double.
catch (NumberFormatException e) {
throw new MenuModelException(BAD_FORMAT);
}
}
/**
* Returns a Set of the names of the items in the menu or an empty set, just in case.
*/
Set<String> getItemsList() {
if (menu.size() == 0)
return new HashSet<String>();
return menu.keySet();
}
/**
* Given an item name, return its price, or 0, just in case.
*/
Float getPrice(String itemName) {
Float result = menu.get(itemName);
if (result == null)
return new Float(0f);
return result;
}
}
CreditCardFactory.java
class CreditCardFactory {
static CreditCard build(String number) {
if (number == null)
return new InvalidCard();
// Sanitize.
number = number.replaceAll("\s+","");
// Validate.
if (number.matches("\d+")) {
int len = number.length();
char fst = number.charAt(0);
char sec = number.charAt(1);
if (len == 13 && fst == '4')
return new VisaCard(number);
if (len == 15 && fst == '3')
if (sec == '4' || sec == '7')
return new AmexCard(number);
if (len == 16) {
if ("6011".equals(number.substring(0,4)))
return new DiscoverCard(number);
if (fst == '4')
return new VisaCard(number);
if (fst == '5')
if (sec == '1' || sec == '2' || sec == '3' || sec == '4' || sec == '5')
return new MasterCard(number);
}
}
return new InvalidCard();
}
}
CreditCard.java
abstract class CreditCard {
String number;
CreditCard(String number) {
this.number = number;
}
String getNumber() {
return number;
}
abstract String getName();
void charge(double amount) {}
}
class MasterCard extends CreditCard {
MasterCard(String number) {
super(number);
}
String getName() {
return "MasterCard";
}
}
class VisaCard extends CreditCard {
VisaCard(String number) {
super(number);
}
String getName() {
return "Visa";
}
}
class AmexCard extends CreditCard {
AmexCard(String number) {
super(number);
}
String getName() {
return "American Express";
}
}
class DiscoverCard extends CreditCard {
DiscoverCard(String number) {
super(number);
}
String getName() {
return "Discover";
}
}
class InvalidCard extends CreditCard {
InvalidCard() {
super(null);
}
String getName() {
return "Invalid card type.";
}
}
menu
Royale With Cheese|3.99
Le Big Mac|4.99
Milkshake|5.00
Pack of Red Apple |5.00
Big Kahuna Burger|5.00
Tasty Beverage|3.00
Fruit Bruite Cereal|4.00
Adrenaline shot|100.00
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.