From ea325f28e62637f78d81be7c0fb2cf7e93e8e985 Mon Sep 17 00:00:00 2001 From: itsmejr257 Date: Wed, 10 Apr 2024 17:03:55 +0800 Subject: [PATCH 1/7] Add validity checks for inputs in RecurringExpensesFile.txt --- src/main/java/seedu/budgetbuddy/Storage.java | 55 +++++++++++++++++--- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/Storage.java b/src/main/java/seedu/budgetbuddy/Storage.java index 36b90fff73..664d53f172 100644 --- a/src/main/java/seedu/budgetbuddy/Storage.java +++ b/src/main/java/seedu/budgetbuddy/Storage.java @@ -15,10 +15,7 @@ import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; -import java.util.ArrayList; -import java.util.Currency; -import java.util.List; -import java.util.Scanner; +import java.util.*; import java.time.LocalDate; import java.util.logging.Level; import java.util.logging.Logger; @@ -29,6 +26,9 @@ public class Storage { private final String filePath; + private ArrayList expenseCategories = new ArrayList<>(Arrays.asList("Housing" + , "Groceries", "Utility", "Transport", "Entertainment", "Others")); + public Storage(String filePath) { this.filePath = filePath; ensureDirectoryExists(); @@ -46,6 +46,40 @@ private void ensureDirectoryExists() { } } + + private void checkValidAmount(Double amount) throws BudgetBuddyException{ + if (amount <= 0) { + throw new BudgetBuddyException("Invalid Amount detected. Possible Corrupted File"); + } + } + + private void checkValidCategory(String category) throws BudgetBuddyException { + if (!expenseCategories.contains(category)) { + throw new BudgetBuddyException("Invalid Category detected. Possible Corrupted File"); + } + } + + private void checkValidDescription(String description) throws BudgetBuddyException { + if (description.contains("|") || description.contains("!") || description.isEmpty()) { + throw new BudgetBuddyException("Invalid description detected. Possible Corrupted File"); + } + } + + private void checkValidTitle(String line) throws BudgetBuddyException { + int indexOfEndExclamation = line.indexOf("!!!", 4); + int endIndexOfEndExclamation = indexOfEndExclamation + "!!!".length(); + + if (endIndexOfEndExclamation != line.length() || line.contains("|")) { + throw new BudgetBuddyException("Invalid ListName title detected. Possible Corrupted File"); + } + } + + private void checkValidListName(String listName) throws BudgetBuddyException { + if (listName.contains("!") || listName.contains("|") || listName.isEmpty()) { + throw new BudgetBuddyException("Invalid listName detected. Possible Corrupted File"); + } + } + public List loadExpenses() throws FileNotFoundException { File file = new File(filePath); List expenses = new ArrayList<>(); @@ -78,6 +112,7 @@ public void parseRecurringExpensesFile(ArrayList recurringExpenses, throws BudgetBuddyException{ if (line.startsWith("!!!")) { + checkValidTitle(line); int indexOfStartExclamation = line.indexOf("!!!", 0); int indexOfStartOfListName = indexOfStartExclamation + 3; @@ -85,8 +120,9 @@ public void parseRecurringExpensesFile(ArrayList recurringExpenses, int indexOfEndOfListName = indexOfEndExclamation; String name = line.substring(indexOfStartOfListName, indexOfEndOfListName).trim(); - ExpenseList expenses = new RecurringExpenseList(name, new ArrayList<>()); + checkValidListName(name); + ExpenseList expenses = new RecurringExpenseList(name, new ArrayList<>()); recurringExpenses.add(expenses); } else { String[] parts = line.split("\\|"); @@ -98,9 +134,16 @@ public void parseRecurringExpensesFile(ArrayList recurringExpenses, int listNumber = Integer.parseInt(parts[0].trim()); LocalDate dateAdded = LocalDate.parse(parts[1].trim()); + String category = parts[2].trim(); + checkValidCategory(category); + double amount = Double.parseDouble(parts[3].trim()); + checkValidAmount(amount); + String description = parts[4].trim(); + checkValidDescription(description); + Expense expense = new Expense(dateAdded, category, amount, description); int listNumberAsArrayIndex = listNumber - 1; @@ -130,7 +173,7 @@ public RecurringExpenseLists loadRecurringExpensesList() throws IOException{ return recurringExpenseLists; } catch (Exception e) { LOGGER.log(Level.INFO, "Exception successfully caught. Error has been handled"); - System.out.println(e.getMessage()); + System.out.println("Error Detected : " + e.getMessage()); System.out.println("You Recurring Expenses File is corrupted, resetting the file...."); resetRecurringExpensesListFile(); return new RecurringExpenseLists(); From c20d27d189122b0a1bf8f5a194a184cf235555ab Mon Sep 17 00:00:00 2001 From: itsmejr257 Date: Wed, 10 Apr 2024 17:04:34 +0800 Subject: [PATCH 2/7] Add identifier for Recurring Expenses in print message --- .../seedu/budgetbuddy/commons/CurrencyConverter.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/seedu/budgetbuddy/commons/CurrencyConverter.java b/src/main/java/seedu/budgetbuddy/commons/CurrencyConverter.java index 11f2f7c24d..90cea58591 100644 --- a/src/main/java/seedu/budgetbuddy/commons/CurrencyConverter.java +++ b/src/main/java/seedu/budgetbuddy/commons/CurrencyConverter.java @@ -1,5 +1,7 @@ package seedu.budgetbuddy.commons; +import seedu.budgetbuddy.Ui; + import java.util.Currency; import java.util.HashMap; import java.util.Map; @@ -22,6 +24,8 @@ public CurrencyConverter() { exchangeRates.put(Currency.getInstance("HKD"), 5.80); } + private Ui ui = new Ui(); + /** * Converts an amount from one currency to another using exchange rates. * @@ -184,13 +188,18 @@ public void convertRecurringExpensesCurrency(Currency newCurrency, RecurringExpe int numberOfExpenseList = recurringExpenseLists.getSize(); + ui.printDivider(); + System.out.println("Conversion for expenses in Recurring Expenses : "); + for (int i = 0; i < numberOfExpenseList; i++) { int arrayIndexAsListNumber = i + 1; ExpenseList reccuringExpenseList = recurringExpenseLists.getExpenseListAtListNumber(arrayIndexAsListNumber); + System.out.print("Changing the default currency for " + reccuringExpenseList.getName() + ": "); convertExpenseCurrency(newCurrency, reccuringExpenseList); } System.out.println("Default currency for Recurring Expenses changed to " + newCurrency); + ui.printDivider(); } public void convertBudgetCurrency(Currency newCurrency, ExpenseList expenseList) { From 84d7e1f61957166e764ab9edc8a510366d1f7ad3 Mon Sep 17 00:00:00 2001 From: itsmejr257 Date: Wed, 10 Apr 2024 17:06:59 +0800 Subject: [PATCH 3/7] Refactor Storage and CurrencyConverter to adhere to check-style --- src/main/java/seedu/budgetbuddy/Storage.java | 6 +++++- .../java/seedu/budgetbuddy/commons/CurrencyConverter.java | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/Storage.java b/src/main/java/seedu/budgetbuddy/Storage.java index 664d53f172..ecd2a6ad79 100644 --- a/src/main/java/seedu/budgetbuddy/Storage.java +++ b/src/main/java/seedu/budgetbuddy/Storage.java @@ -15,7 +15,11 @@ import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; +import java.util.Currency; import java.time.LocalDate; import java.util.logging.Level; import java.util.logging.Logger; diff --git a/src/main/java/seedu/budgetbuddy/commons/CurrencyConverter.java b/src/main/java/seedu/budgetbuddy/commons/CurrencyConverter.java index 90cea58591..019ded6af9 100644 --- a/src/main/java/seedu/budgetbuddy/commons/CurrencyConverter.java +++ b/src/main/java/seedu/budgetbuddy/commons/CurrencyConverter.java @@ -11,6 +11,8 @@ public class CurrencyConverter { private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); private Map exchangeRates; + private Ui ui = new Ui(); + public CurrencyConverter() { this.exchangeRates = new HashMap<>(); // Initialize exchange rates with default values @@ -24,7 +26,6 @@ public CurrencyConverter() { exchangeRates.put(Currency.getInstance("HKD"), 5.80); } - private Ui ui = new Ui(); /** * Converts an amount from one currency to another using exchange rates. From 18ef598079f764e66b54dc8f788c2c2a28bae525 Mon Sep 17 00:00:00 2001 From: itsmejr257 Date: Sat, 13 Apr 2024 16:46:51 +0800 Subject: [PATCH 4/7] Add javadoc comments to FindExpensesCommand --- .../command/FindExpensesCommand.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/budgetbuddy/command/FindExpensesCommand.java b/src/main/java/seedu/budgetbuddy/command/FindExpensesCommand.java index 0832be5f6c..b8f922ce45 100644 --- a/src/main/java/seedu/budgetbuddy/command/FindExpensesCommand.java +++ b/src/main/java/seedu/budgetbuddy/command/FindExpensesCommand.java @@ -8,6 +8,10 @@ import java.util.logging.Level; import java.util.logging.Logger; +/** + * Represents a command that finds and lists expenses based on a provided criteria. + * Criteria can include description, minimum and maximum amounts + */ public class FindExpensesCommand extends Command { private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); private ExpenseList expenses; @@ -16,6 +20,15 @@ public class FindExpensesCommand extends Command { private Double maxAmount; private Ui ui; + /** + * Constructs a FindExpenseCommand with the specified expense list, description, minimum amount and maximum amount + * + * + * @param expenses The expenseList to filter the expenses + * @param description The description to be filtered, can be null or empty + * @param minAmount The minimum amount of expense to be filtered, can be null + * @param maxAmount The maximum amount of expense to be filtered, can be null + */ public FindExpensesCommand(ExpenseList expenses, String description, Double minAmount, Double maxAmount) { if (minAmount != null && maxAmount != null) { assert minAmount < maxAmount : "Minimum amount cannot be larger than Maximum Amount"; @@ -33,7 +46,10 @@ public FindExpensesCommand(ExpenseList expenses, String description, Double minA this.maxAmount = maxAmount; } - + /** + * Prints an initialization message that informs user of the parameters used when filtering. Diplays + * an N.A. for filters which would not be used + */ private void printInitializationMessage() { ui.printDivider(); System.out.println("Looking for Expenses with the following parameters : "); From a565011618cd11cbb46f4b66b40b0a70e26d996f Mon Sep 17 00:00:00 2001 From: itsmejr257 Date: Sat, 13 Apr 2024 16:47:02 +0800 Subject: [PATCH 5/7] Add javadoc comments to FindExpensesCommandCreator --- .../FindExpensesCommandCreator.java | 54 +++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/commandcreator/FindExpensesCommandCreator.java b/src/main/java/seedu/budgetbuddy/commandcreator/FindExpensesCommandCreator.java index 8b22cdc7b6..c428f9ae1a 100644 --- a/src/main/java/seedu/budgetbuddy/commandcreator/FindExpensesCommandCreator.java +++ b/src/main/java/seedu/budgetbuddy/commandcreator/FindExpensesCommandCreator.java @@ -25,6 +25,13 @@ public FindExpensesCommandCreator(String input, ExpenseList expenses) { this.expenses = expenses; } + + /** + * Checks the order of parameters in the provided input. + * + * @param input The user input + * @throws BudgetBuddyException If the parameters are not in the order of d/, morethan/ , lessthan/. + */ private void checkForOutOfOrderParameters(String input) throws BudgetBuddyException { int indexOfDescriptionPrefix = input.indexOf(DESCRIPTION_PREFIX); int indexOfMinAmountPrefix = input.indexOf(MINAMOUNT_PREFIX); @@ -40,12 +47,25 @@ private void checkForOutOfOrderParameters(String input) throws BudgetBuddyExcept } - private static void checkForInvalidParameters(String input) { + /** + * Checks for the absence of the required parameters `d/`, `morethan/` and `lessthan/` + * + * @param input The user input + * @throws IllegalArgumentException If any of the three required parameters are missing + */ + private static void checkForInvalidParameters(String input) throws IllegalArgumentException { if (!input.contains("d/") || !input.contains("morethan/") || !input.contains("lessthan/")) { throw new IllegalArgumentException("Please Ensure that you include d/, morethan/ and lessthan/"); } } + /** + * Parses and returns the maximum amount from the `lessthan/` prefix in the input string + * + * @param input The user input + * @return The extracted maximum amount, or null if amount is not specified + * @throws NumberFormatException If the maximum amount obtained is not a valid double + */ private Double parseMaxAmount(String input) throws NumberFormatException{ int indexOfMaxAmountPrefix = input.indexOf(MAXAMOUNT_PREFIX); int startIndexOfMaxAmount = indexOfMaxAmountPrefix + MAXAMOUNT_PREFIX.length(); @@ -63,7 +83,14 @@ private Double parseMaxAmount(String input) throws NumberFormatException{ return maxAmount; } - private Double parseMinAmount(String input) { + /** + * Parses and returns the minimum amount from the `morethan/` prefix in the input string + * + * @param input The user input + * @return The extracted minimum amount, or null if amount is not specified + * @throws NumberFormatException If the minimum amount obtained is not a valid double + */ + private Double parseMinAmount(String input) throws NumberFormatException { int indexOfMinAmountPrefix = input.indexOf(MINAMOUNT_PREFIX); int startIndexOfMinAmount = indexOfMinAmountPrefix + MINAMOUNT_PREFIX.length(); @@ -80,6 +107,13 @@ private Double parseMinAmount(String input) { return minAmount; } + + /** + * Parses and returns the description from the `d/` prefix in the input string + * + * @param input The user input + * @return The obtained description, or null if the description is empty + */ private String parseDescription(String input) { int indexOfDescriptionPrefix = input.indexOf(DESCRIPTION_PREFIX); @@ -97,7 +131,14 @@ private String parseDescription(String input) { return description; } - private static void checkForDuplicateParameters(String input, String parameter) { + /** + * Checks for duplicate occurrences of a prefix in the input string + * + * @param input The user input + * @param parameter The parameter to check for duplicates + * @throws IllegalArgumentException If the parameter appears more than once + */ + private static void checkForDuplicateParameters(String input, String parameter) throws IllegalArgumentException{ int count = 0; @@ -114,6 +155,13 @@ private static void checkForDuplicateParameters(String input, String parameter) } + /** + * Compares the minimum and maximum amounts and throws an exception if the minimum amount is larger than the maximum amount + * + * @param minAmount The minimum amount + * @param maxAmount The maximum amount + * @throws BudgetBuddyException If the minimum amount > maximum amount + */ private static void compareMinAndMaxAmount(Double minAmount, Double maxAmount) throws BudgetBuddyException{ if (minAmount != null && maxAmount != null) { From eebe8dc802ea1c21101417adb3309b9aac7516f4 Mon Sep 17 00:00:00 2001 From: itsmejr257 Date: Sat, 13 Apr 2024 16:47:37 +0800 Subject: [PATCH 6/7] Add JUnit tests for out of order parameters --- .../seedu/budgetbuddy/FindExpensesCommandCreatorTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/java/seedu/budgetbuddy/FindExpensesCommandCreatorTest.java b/src/test/java/seedu/budgetbuddy/FindExpensesCommandCreatorTest.java index 10e4b313c5..4fb77aafa6 100644 --- a/src/test/java/seedu/budgetbuddy/FindExpensesCommandCreatorTest.java +++ b/src/test/java/seedu/budgetbuddy/FindExpensesCommandCreatorTest.java @@ -46,6 +46,13 @@ public void createCommand_duplicateParameters_returnsNull() { assertNull(initializeFindExpensesCommandCreator(inputWithDuplicateMaxAmount).createCommand()); } + @Test + public void createCommand_outOfOrderParameters_returnsNull() { + String inputWithOutOfOrderAmountParameters = "find expenses d/23 lessthan/40 morethan/"; + String inputWithOutOfOrderDescriptionParameter = "find expenses morethan/ d/23 lessthan/40"; + assertNull(initializeFindExpensesCommandCreator(inputWithOutOfOrderAmountParameters).createCommand()); + assertNull(initializeFindExpensesCommandCreator(inputWithOutOfOrderDescriptionParameter).createCommand()); + } @Test public void createCommand_invalidMinAmount_returnsNull() { String validInputWithEmptyDescription = "find expenses d/hello morethan/dsfefew lessthan/20"; From f466cdca8fac5aa57ac1bb99ae70306be5306311 Mon Sep 17 00:00:00 2001 From: itsmejr257 Date: Sat, 13 Apr 2024 16:50:44 +0800 Subject: [PATCH 7/7] Refactor code comments to adhere to check-style --- .../budgetbuddy/commandcreator/FindExpensesCommandCreator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/budgetbuddy/commandcreator/FindExpensesCommandCreator.java b/src/main/java/seedu/budgetbuddy/commandcreator/FindExpensesCommandCreator.java index c428f9ae1a..d715b6cf36 100644 --- a/src/main/java/seedu/budgetbuddy/commandcreator/FindExpensesCommandCreator.java +++ b/src/main/java/seedu/budgetbuddy/commandcreator/FindExpensesCommandCreator.java @@ -156,7 +156,8 @@ private static void checkForDuplicateParameters(String input, String parameter) } /** - * Compares the minimum and maximum amounts and throws an exception if the minimum amount is larger than the maximum amount + * Compares the minimum and maximum amounts and throws an exception if the minimum amount + * is larger than the maximum amount * * @param minAmount The minimum amount * @param maxAmount The maximum amount