Skip to content

Commit

Permalink
Merge pull request #290 from ShaniceTang/fix-bugs
Browse files Browse the repository at this point in the history
Fix bugs for buyIngredient and viewTotalStock commands
  • Loading branch information
DextheChik3n authored Nov 8, 2023
2 parents f07a4fd + 61f2601 commit 2eec5b4
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 50 deletions.
5 changes: 4 additions & 1 deletion docs/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ Format: `add name/DISH_NAME price/PRICE ingredient/INGREDIENT1_NAME qty/INGREDIE

* `DISH_NAME`
* `PRICE` must be a positive number and can be up to 2 decimal places.
* `IMGREDIENT_QTY` must contain the unit ml or g specifically.
* `INGREDIENT_QTY` must contain the unit ml or g specifically.
* e.g. `qty/50g` or `qty/1000ml`

Example:
Expand Down Expand Up @@ -205,6 +205,9 @@ Adds one or more ingredients to the pantry

Format: `buy_ingredient ingredient/INGREDIENT1_NAME qty/INGREDIENT1_QTY[, ingredient/INGREDIENT2_NAME qty/INGREDIENT2_QTY, ...]`

* `INGREDIENT_QTY` must contain the unit ml or g specifically
* e.g. `qty/50g` or `qty/1000ml`

Example: `buy_ingredient ingredient/chicken qty/500g, ingredient/milk qty/1000ml`

Output:
Expand Down
28 changes: 17 additions & 11 deletions src/main/java/seedu/cafectrl/command/BuyIngredientCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import seedu.cafectrl.data.Pantry;
import seedu.cafectrl.data.dish.Ingredient;
import seedu.cafectrl.ui.Ui;
import seedu.cafectrl.parser.Parser;

import java.util.ArrayList;

Expand All @@ -17,12 +18,14 @@ public class BuyIngredientCommand extends Command {
+ COMMAND_WORD + " ingredient/INGREDIENT1_NAME qty/INGREDIENT1_QTY"
+ "[, ingredient/INGREDIENT2_NAME, qty/INGREDIENT2_QTY...]\n"
+ "Example:"
+ COMMAND_WORD + " ingredient/rice qty/200g, ingredient/chicken qty/100g";
+ COMMAND_WORD + " ingredient/milk qty/200ml, ingredient/chicken qty/100g";

protected Ui ui;
protected Pantry pantry;
private ArrayList<Ingredient> ingredients;
private ArrayList<Ingredient> ingredientsToBePrinted = new ArrayList<>();
private String ingredientString = ""; // Used to store the message about the bought ingredients
private int FIRST_INDEX = 0;

/**
* Constructs a BuyIngredientCommand with the specified ingredients, user interface, and pantry.
Expand All @@ -45,7 +48,7 @@ public void execute() {
try {
addIngredient();
ui.printBuyIngredientHeader();
ui.showToUser(ingredientString);
ui.showToUser(ingredientString.strip());
} catch (RuntimeException e) {
ui.showToUser(e.getMessage());
}
Expand All @@ -61,25 +64,28 @@ private void addIngredient() {
ingredient = pantry.addIngredientToStock(ingredient.getName(),
ingredient.getQty(),
ingredient.getUnit());
buildBuyIngredientMessage(ingredient, i);
ingredients.set(i, ingredient);
}

for (int i = ingredients.size() - ui.OFFSET_LIST_INDEX; i >= FIRST_INDEX; i--) {
Ingredient ingredient = ingredients.get(i);
buildBuyIngredientMessage(ingredient);
}
}

/**
* Builds a message about the bought ingredient and appends it to the result message.
*
* @param ingredient The Ingredient object to build the message for.
* @param index The index of the ingredient in the list.
*/
private void buildBuyIngredientMessage(Ingredient ingredient, int index) {
private void buildBuyIngredientMessage(Ingredient ingredient) {
if (Parser.isRepeatedIngredientName(ingredient.getName(), ingredientsToBePrinted)) {
return;
}
ingredientsToBePrinted.add(ingredient);
ingredientString += "Ingredient: " + ingredient.getName()
+ "\t\tQty: " + ingredient.getQty()
+ ingredient.getUnit();

//append new line if current ingredient is not last
if(index < ingredients.size() - ui.OFFSET_LIST_INDEX) {
ingredientString += "\n";
}
+ ingredient.getUnit() + "\n";
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import seedu.cafectrl.ui.ErrorMessages;
import seedu.cafectrl.ui.Ui;

//@@author ShaniceTang
/**
* Deletes a menu item identified using it's last displayed index from the menu.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import seedu.cafectrl.data.Pantry;
import seedu.cafectrl.data.dish.Ingredient;
import seedu.cafectrl.ui.Ui;
import seedu.cafectrl.ui.Messages;

import java.util.ArrayList;

//@@author ShaniceTang
public class ViewTotalStockCommand extends Command {

public static final String COMMAND_WORD = "view_stock";
Expand All @@ -21,9 +23,14 @@ public ViewTotalStockCommand(Pantry pantry, Ui ui) {

@Override
public void execute() {
ui.showIngredientTop();
pantryStock = pantry.getPantryStock();

if (pantryStock.isEmpty()) {
ui.showToUser(Messages.EMPTY_STOCK);
return;
}

ui.showIngredientTop();
for (Ingredient ingredient : pantryStock) {
ui.showIngredientStock(ingredient.getName(), ingredient.getQty(), ingredient.getUnit());
}
Expand Down
75 changes: 44 additions & 31 deletions src/main/java/seedu/cafectrl/parser/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public class Parser implements ParserUtil {
private static final String PRICE_MATCHER_GROUP_LABEL = "dishPrice";
private static final String INGREDIENTS_MATCHER_GROUP_LABEL = "ingredients";
private static final String INGREDIENT_ARGUMENT_STRING = "\\s*ingredient/(?<ingredientName>[A-Za-z0-9\\s]+) "
+ "qty/\\s*(?<ingredientQty>[0-9]+)\\s*(?<ingredientUnit>g|ml)\\s*";
+ "qty/\\s*(?<ingredientQty>[0-9]+)\\s*(?<ingredientUnit>[A-Za-z]*)\\s*";
private static final String INGREDIENT_NAME_REGEX_GROUP_LABEL = "ingredientName";
private static final String INGREDIENT_QTY_REGEX_GROUP_LABEL = "ingredientQty";
private static final String INGREDIENT_UNIT_REGEX_GROUP_LABEL = "ingredientUnit";
Expand All @@ -70,6 +70,13 @@ public class Parser implements ParserUtil {
private static final String EDIT_PRICE_ARGUMENT_STRING = "dish/(.*)\\sprice/(.*)";
private static final String BUY_INGREDIENT_ARGUMENT_STRING = "(ingredient/[A-Za-z0-9\\s]+ qty/[A-Za-z0-9\\s]+"
+ "(?:, ingredient/[A-Za-z0-9\\s]+ qty/[A-Za-z0-9\\s]+)*)";

private static final int MIN_QTY = 1;
private static final int MAX_QTY = 1000000;
private static final String GRAMS_UNIT = "g";
private static final String ML_UNIT = "ml";


private static final String SHOW_SALE_BY_DAY_ARGUMENT_STRING = "day/(\\d+)";

//@@author ziyi105
Expand Down Expand Up @@ -236,7 +243,7 @@ private static Command prepareAdd(String arguments, Menu menu, Ui ui) {
throw new ParserException(Messages.REPEATED_DISH_MESSAGE);
}

ArrayList<Ingredient> ingredients = parseIngredients(ingredientsListString);
ArrayList<Ingredient> ingredients = parseIngredients(ingredientsListString, true);

Dish dish = new Dish(dishName, ingredients, price);

Expand All @@ -255,9 +262,11 @@ private static Command prepareAdd(String arguments, Menu menu, Ui ui) {
* @throws IllegalArgumentException if the input string of ingredients is in an incorrect format.
* @throws ParserException if the input string does not match the constraints
*/
private static ArrayList<Ingredient> parseIngredients(String ingredientsListString)
private static ArrayList<Ingredient> parseIngredients(String ingredientsListString,
boolean excludeRepeatedIngredients)
throws IllegalArgumentException, ParserException {
String[] inputIngredientList = {ingredientsListString};

ArrayList<Ingredient> ingredients = new ArrayList<>();

//check if there is more than 1 ingredient
Expand All @@ -272,8 +281,7 @@ private static ArrayList<Ingredient> parseIngredients(String ingredientsListStri
Matcher ingredientMatcher = ingredientPattern.matcher(inputIngredient);

if (!ingredientMatcher.matches()) {
throw new ParserException(ErrorMessages.INVALID_ADD_DISH_FORMAT_MESSAGE
+ AddDishCommand.MESSAGE_USAGE);
throw new ParserException(ErrorMessages.INVALID_INGREDIENT_ARGUMENTS);
}

String ingredientName = ingredientMatcher.group(INGREDIENT_NAME_REGEX_GROUP_LABEL).trim();
Expand All @@ -286,10 +294,22 @@ private static ArrayList<Ingredient> parseIngredients(String ingredientsListStri
throw new ParserException(ErrorMessages.INVALID_INGREDIENT_NAME_LENGTH_MESSAGE);
}

if (isRepeatedIngredientName(ingredientName, ingredients)) {
if (excludeRepeatedIngredients && isRepeatedIngredientName(ingredientName, ingredients)) {
continue;
}

if (isInvalidQty(ingredientQty)) {
throw new ParserException(ErrorMessages.INVALID_INGREDIENT_QTY);
}

if (isEmptyUnit(ingredientUnit)) {
throw new ParserException(ErrorMessages.EMPTY_UNIT_MESSAGE);
}

if (!isValidUnit(ingredientUnit)) {
throw new ParserException(ErrorMessages.INVALID_UNIT_MESSAGE);
}

Ingredient ingredient = new Ingredient(ingredientName, ingredientQty, ingredientUnit);

ingredients.add(ingredient);
Expand All @@ -298,6 +318,7 @@ private static ArrayList<Ingredient> parseIngredients(String ingredientsListStri
return ingredients;
}


/**
* Converts text of price to float while also checking if the price input is within reasonable range
* @param priceText text input for price argument
Expand Down Expand Up @@ -370,7 +391,7 @@ static boolean isRepeatedDishName(String inputDishName, Menu menu) throws NullPo
* @return true if ingredient name already exists in menu, false otherwise
* @throws NullPointerException if the input string is null
*/
static boolean isRepeatedIngredientName(String inputName, ArrayList<Ingredient> ingredients)
public static boolean isRepeatedIngredientName(String inputName, ArrayList<Ingredient> ingredients)
throws NullPointerException {
if (inputName == null) {
throw new NullPointerException();
Expand Down Expand Up @@ -467,22 +488,34 @@ private static Command prepareBuyIngredient(String arguments, Ui ui, Pantry pant
Matcher matcher = buyIngredientArgumentsPattern.matcher(arguments.trim());

if (!matcher.matches()) {

return new IncorrectCommand(ErrorMessages.MISSING_ARGUMENT_FOR_BUY_INGREDIENT
+ BuyIngredientCommand.MESSAGE_USAGE, ui);
}

String ingredientsListString = matcher.group(0);

try {
ArrayList<Ingredient> ingredients = parseIngredients(ingredientsListString);
ArrayList<Ingredient> ingredients = parseIngredients(ingredientsListString, false);
return new BuyIngredientCommand(ingredients, ui, pantry);
} catch (NumberFormatException e) {
return new IncorrectCommand(ErrorMessages.INVALID_INGREDIENT_QTY, ui);
} catch (Exception e) {
return new IncorrectCommand(ErrorMessages.INVALID_ARGUMENT_FOR_BUY_INGREDIENT
+ BuyIngredientCommand.MESSAGE_USAGE, ui);
return new IncorrectCommand(e.getMessage(), ui);
}
}

private static boolean isValidUnit(String ingredientUnit) {
return ingredientUnit.equals(GRAMS_UNIT) || ingredientUnit.equals(ML_UNIT);
}

private static boolean isEmptyUnit(String ingredientUnit) {
return ingredientUnit.equals("");
}

private static boolean isInvalidQty(int ingredientQty) {
return ingredientQty < MIN_QTY || ingredientQty > MAX_QTY;
}

//@@author ziyi105
private static Command prepareHelpCommand(Ui ui) {
return new HelpCommand(ui);
Expand Down Expand Up @@ -607,24 +640,4 @@ private static OrderList setOrderList(CurrentDate currentDate, Sales sales) {
int currentDay = currentDate.getCurrentDay();
return sales.getOrderList(currentDay);
}

//@@author ShaniceTang
/**
* Extracts the quantity (numeric part) from a given string containing both quantity and unit.
* @param qty A string containing both quantity and unit (e.g., "100g").
* @return An integer representing the extracted quantity.
*/
public static int extractQty(String qty) {
return Integer.parseInt(qty.replaceAll("[^0-9]", ""));
}

//@@author ShaniceTang
/**
* Extracts the unit (non-numeric part) from a given string containing both quantity and unit.
* @param qty A string containing both quantity and unit (e.g., "100g").
* @return A string representing the extracted unit.
*/
public static String extractUnit(String qty) {
return qty.replaceAll("[0-9]", "");
}
}
7 changes: 7 additions & 0 deletions src/main/java/seedu/cafectrl/ui/ErrorMessages.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ public class ErrorMessages {
+ "No worries, new pantry has been created";
public static final String ORDER_LIST_FILE_NOT_FOUND_MESSAGE = "Order list data was not found!\n"
+ "No worries, new order list has been created";
public static final String EMPTY_UNIT_MESSAGE = "Unit cannot be empty! Please use either g or ml :)";
public static final String INVALID_UNIT_MESSAGE = "Invalid unit! Please use either g or ml :)";
public static final String INVALID_INGREDIENT_ARGUMENTS = "Invalid arguments for ingredients!\n"
+ "Ingredient format: ingredient/INGREDIENT1_NAME qty/INGREDIENT1_QTY"
+ "[, ingredient/INGREDIENT2_NAME, qty/INGREDIENT2_QTY...]\n"
+ "Example: ingredient/milk qty/200ml, ingredient/chicken qty/100g";
public static final String INVALID_INGREDIENT_QTY = "Quantity out of range! Quantity range is 1 to 1000000 :)";
public static final String INVALID_SHOW_SALE_DAY_FORMAT_MESSAGE = "Error: "
+ "Incorrect format for the show_sale command.\n";
public static final String INVALID_DAY_FORMAT = "Sorry, please enter a valid integer "
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/seedu/cafectrl/ui/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ public class Messages {
public static final String REPEATED_DISH_MESSAGE = "Sorry, this dish name already exists.";

/** Messages for view stock command */
public static final String VIEW_STOCK = "You have the following ingredients in pantry:"
+ "\nIngredients\t\tQty";
public static final String EMPTY_STOCK = "Sorry! Pantry is currently empty!";

public static final String VIEW_STOCK_MESSAGE = "You have the following ingredients in pantry:";
public static final String VIEW_STOCK_MESSAGE2 = "| You have the following ingredients in pantry: |";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ void execute_validInput_returnCorrectOutput() {
System.setOut(originalOut);

String expectedOutput = "Added to stock: \n"
+ "Ingredient: chicken\t\tQty: 500g\n"
+ "Ingredient: milk\t\tQty: 100ml\n"
+ "Ingredient: rice\t\tQty: 1000g\n"
+ "Ingredient: milk\t\tQty: 100ml";
+ "Ingredient: chicken\t\tQty: 500g";

assertEquals(expectedOutput.trim().replaceAll("\\s+", " "),
actualOutput.trim().replaceAll("\\s+", " "));
Expand Down
3 changes: 1 addition & 2 deletions src/test/java/seedu/cafectrl/parser/ParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -677,8 +677,7 @@ void parseCommand_invalidArgsForBuyIngredient_returnErrorMessage() {

IncorrectCommand incorrectCommand = (IncorrectCommand) result;
String feedbackToUser = incorrectCommand.feedbackToUser;
assertEquals(ErrorMessages.INVALID_ARGUMENT_FOR_BUY_INGREDIENT
+ BuyIngredientCommand.MESSAGE_USAGE, feedbackToUser);
assertEquals(ErrorMessages.INVALID_UNIT_MESSAGE, feedbackToUser);
}
//@@author
}

0 comments on commit 2eec5b4

Please sign in to comment.