From 03248a0362f9d384f1ff7d7323a148bc870eb336 Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Tue, 9 Apr 2024 20:26:37 +0800 Subject: [PATCH 01/46] Fix inconsistent spacing in print output of expense and saving --- data/ExpenseFile.txt | 1 + src/main/java/seedu/budgetbuddy/command/AddExpenseCommand.java | 2 +- src/main/java/seedu/budgetbuddy/command/AddSavingCommand.java | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/data/ExpenseFile.txt b/data/ExpenseFile.txt index e69de29bb2..527ddb145d 100644 --- a/data/ExpenseFile.txt +++ b/data/ExpenseFile.txt @@ -0,0 +1 @@ +2024-04-09 | Entertainment | 2.24 | asd diff --git a/src/main/java/seedu/budgetbuddy/command/AddExpenseCommand.java b/src/main/java/seedu/budgetbuddy/command/AddExpenseCommand.java index b8a19a7954..3b2c0e1b3f 100644 --- a/src/main/java/seedu/budgetbuddy/command/AddExpenseCommand.java +++ b/src/main/java/seedu/budgetbuddy/command/AddExpenseCommand.java @@ -22,7 +22,7 @@ public AddExpenseCommand (ExpenseList expenses,String category, String amount, S public void execute() { try { expenses.addExpense(this.category,this.amount,this.description); - System.out.println("Expense Added :" + category + " of $" + amount + " description : " + description); + System.out.println("Expense Added: " + category + " of $" + amount + " description: " + description); } catch (BudgetBuddyException e) { System.out.println(e.getMessage()); } diff --git a/src/main/java/seedu/budgetbuddy/command/AddSavingCommand.java b/src/main/java/seedu/budgetbuddy/command/AddSavingCommand.java index 279a7ab000..c019ee32f5 100644 --- a/src/main/java/seedu/budgetbuddy/command/AddSavingCommand.java +++ b/src/main/java/seedu/budgetbuddy/command/AddSavingCommand.java @@ -27,7 +27,7 @@ public void execute(){ savings.addSaving(this.category, this.amount); LOGGER.log(Level.INFO, "Savings added to: {0} of ${1}", new Object[]{category, amount}); - System.out.println("Savings Added to:" + category + " of $" + amount); + System.out.println("Savings Added to: " + category + " of $" + amount); } catch (BudgetBuddyException e) { System.out.println(e.getMessage()); LOGGER.log(Level.SEVERE, "Exception while adding savings", e); From ea325f28e62637f78d81be7c0fb2cf7e93e8e985 Mon Sep 17 00:00:00 2001 From: itsmejr257 Date: Wed, 10 Apr 2024 17:03:55 +0800 Subject: [PATCH 02/46] 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 03/46] 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 04/46] 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 cccc5c8c84ef067af2b125aec6edf09dee4b0bfd Mon Sep 17 00:00:00 2001 From: Dheekshitha2 Date: Wed, 10 Apr 2024 18:06:55 +0800 Subject: [PATCH 05/46] Add PPP, first draft --- docs/team/dheekshitha2.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 docs/team/dheekshitha2.md diff --git a/docs/team/dheekshitha2.md b/docs/team/dheekshitha2.md new file mode 100644 index 0000000000..c560c65737 --- /dev/null +++ b/docs/team/dheekshitha2.md @@ -0,0 +1,37 @@ +# Murali Krishnan Dheekshitha's Project Portfolio Page + +## Project: BudgetBuddy +BudgetBuddy is a product for users who wish to handle and track any current/future expenses on a singular platform. +BudgetBuddy provides a faster and more efficient way to track and calculate expenses and provides the ability to deal +with finances on a singular platform with ease. It has multiple financial tracking options to suit your needs. + +## Summary of Contributions +My primary contributions include developing the budget setting functions, and enabling users to delete their expenses +or reduce their savings, thereby improving the app's usability and user experience. + +### New Feature: Added the ability to set and manage budget +- **What it does:** Allows users to set and adjust budgets for various categories such as groceries, transport, and + housing. Users can define a maximum spending limit for each category, which helps in monitoring and controlling + their expenditures. +- **Justification:** This feature is pivotal for users aiming to adhere to their financial goals, and ensure that they + do not overspend in any category +- **Highlights:** Implementing this feature requires a deep understanding of the app's different functions and how they + all work together. One challenge of implementing this feature was integrating existing functions like `Expenses` so that + I am able to retrieve the relevant expense information to check if the user is still within their budget. +- **Credits:** (to be updated) + +### New Feature: Added the ability to delete expenses +- **What it does:** Allows users to delete expenses that have been added wrongly or are outdated +- **Justification:** This feature improves the app's flexibility by allowing users to correct their mistakes, ensuring + that their financial records remain accurate + +### New Feature: Added the ability to reduce savings +- **What it does:** Enables users to record when they withdraw or spend from their savings, updating savings accordingly +- **Justification:** Essential for maintaining an accurate record of savings, especially when savings are used to cover +unexpected expenses or large purchases + +## Code contributed +(RepoSense link) + +## Enhancements to existing features +- (to be updated) \ No newline at end of file From ceedc5bffc5f22d6a417704f9f8963b4467935a6 Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Wed, 10 Apr 2024 21:21:50 +0800 Subject: [PATCH 06/46] Resolve conflicts --- .../budgetbuddy/commons/ExpenseList.java | 61 +++++-------------- 1 file changed, 16 insertions(+), 45 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java index dedca99ea6..e17fc121ef 100644 --- a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java +++ b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java @@ -29,7 +29,7 @@ public class ExpenseList { public ExpenseList(ArrayList expenses) { this.expenses = expenses; this.budgets = new ArrayList<>(); - + } public ExpenseList() { @@ -77,8 +77,8 @@ public ArrayList filterExpenses(String description, Double minAmount, D ArrayList filteredExpenses = new ArrayList<>(this.expenses.stream() .filter(expense -> (expense.getDescription() .toLowerCase().contains(descriptionInLowerCase))) - .filter(expense -> (minAmount == null || expense.getAmount() >= minAmount)) - .filter(expense -> (maxAmount == null || expense.getAmount() <= maxAmount)) + .filter(expense -> (minAmount == null || expense.getAmount() > minAmount)) + .filter(expense -> (maxAmount == null || expense.getAmount() < maxAmount)) .collect(Collectors.toList())); LOGGER.log(Level.INFO, "Ending filtering and returning filtered expenses"); @@ -102,6 +102,7 @@ public void listExpenses(String filterCategory) { for (int i = 0; i < expenses.size(); i++) { Expense expense = expenses.get(i); + // Checks for null expenses if (expense == null) { LOGGER.warning("Expense object at index " + i + " is null"); continue; @@ -118,6 +119,7 @@ public void listExpenses(String filterCategory) { ui.printDivider(); System.out.println("Overall Total Expenses: $" + String.format("%.2f", calculateTotalExpenses())); + // Assertion: Check if total expenses calculation is correct double totalExpenses = calculateTotalExpenses(); assert totalExpenses >= 0 : "Total expenses should be non-negative"; } catch (Exception e) { @@ -145,6 +147,7 @@ public double calculateTotalExpenses() { LOGGER.log(Level.WARNING, "Negative expense amount detected", e); } + // Assertion: Check if total expenses is non-negative assert totalExpenses >= 0 : "Total expenses should be non-negative"; return totalExpenses; @@ -170,32 +173,6 @@ public void addExpense(String category, String amount, String description) throw throw new BudgetBuddyException("Expenses should not be negative."); } - // Check against the budget before adding the expense - Budget budgetForCategory = budgets.stream() - .filter(budget -> budget.getCategory().equalsIgnoreCase(category)) - .findFirst() - .orElse(null); - - if (budgetForCategory != null) { - double totalSpent = expenses.stream() - .filter(expense -> expense.getCategory().equalsIgnoreCase(category)) - .mapToDouble(Expense::getAmount) - .sum(); - double projectedTotal = totalSpent + amountAsDouble; - - if (projectedTotal > budgetForCategory.getBudget()) { - ui.printDivider(); - System.out.println("Warning: Adding this expense will exceed your budget for " + category); - ui.printDivider(); - - // Replace with actual user confirmation in your application context - if (!ui.getUserConfirmation()) { - System.out.println("Expense not added due to budget constraints."); - return; // Exit without adding the expense - } - } - } - Expense expense = new Expense(category, amountAsDouble, description); expenses.add(expense); @@ -268,21 +245,18 @@ public String getName() { return "placeholder"; } - public void setBudget(String category, double budget) { + public void setBudget(String category, double budget){ LOGGER.info("Setting budget - Category: " + category + ", Budget: $" + budget); - - for (Budget b : budgets) { - if (b.getCategory().equalsIgnoreCase(category)) { + for (Budget b : budgets){ + if (b.getCategory().equalsIgnoreCase(category)){ LOGGER.info("Updating budget for category: " + category); b.setBudget(budget); System.out.println("Updated budget for " + category + " to $" + budget); return; } } - LOGGER.info("Creating new budget for category: " + category); budgets.add(new Budget(category, budget)); - System.out.println("Budget Added: " + category + " of $" + budget); } /** @@ -290,32 +264,29 @@ public void setBudget(String category, double budget) { * The expenses are sorted from the highest to the lowest amount, displaying the amount and what percentage * of the total budget each expense constitutes. * - * @param inputCategory The category for which to retrieve and print the budget and expenses. + * @param category The category for which to retrieve and print the budget and expenses. */ - public void getBudgetAndListExpensesForCategory(String inputCategory) { - // Trim the input and replace multiple internal spaces with a single space - String normalizedCategory = inputCategory.trim().replaceAll("\\s+", " "); - + public void getBudgetAndListExpensesForCategory(String category) { Budget budgetForCategory = budgets.stream() - .filter(budget -> budget.getCategory().equalsIgnoreCase(normalizedCategory)) + .filter(budget -> budget.getCategory().equalsIgnoreCase(category)) .findFirst() .orElse(null); if (budgetForCategory == null) { - System.out.println("No budget set for " + normalizedCategory); + System.out.println("No budget set for " + category); return; } double budgetAmount = budgetForCategory.getBudget(); - System.out.println("Budget for " + normalizedCategory + ": $" + budgetAmount); + System.out.println("Budget for " + category + ": $" + budgetAmount); List expensesForCategory = expenses.stream() - .filter(expense -> expense.getCategory().equalsIgnoreCase(normalizedCategory)) + .filter(expense -> expense.getCategory().equalsIgnoreCase(category)) .sorted(Comparator.comparingDouble(Expense::getAmount).reversed()) .collect(Collectors.toList()); if (expensesForCategory.isEmpty()) { - System.out.println("No expenses recorded for " + normalizedCategory); + System.out.println("No expenses recorded for " + category); return; } From e2b6ca24fc89a0ee26d62b87f23bbdaf6729da31 Mon Sep 17 00:00:00 2001 From: jasraa Date: Wed, 10 Apr 2024 23:43:36 +0800 Subject: [PATCH 07/46] Add jasra's PPP --- docs/team/jasraa.md | 58 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 docs/team/jasraa.md diff --git a/docs/team/jasraa.md b/docs/team/jasraa.md new file mode 100644 index 0000000000..7f57744700 --- /dev/null +++ b/docs/team/jasraa.md @@ -0,0 +1,58 @@ +# Jasra Zainab's Project Portfolio Page + +## Project: Budget Buddy +BudgetBuddy is a streamlined finance-tracking application designed for efficient management of current and future +expenses on a single platform. BudgetBuddy simplifies expense tracking and calculations, making financial management +both quick and intuitive. With budgeting features implemented, Budget Buddy is a well-rounded financial management +application that is user-friendly. + +### Summary of Contributions +Given below are my contributions to the project + +#### New Feature: Added the ability to edit expenses +- **What it does:** Allows users to edit expenses that have already been added. Users have to specify the index of the +expense they want to edit, and they can edit the Category, Amount and Description of the expense. +- **Justification:** This feature enables to users to correct any mistakes they may have made while adding an expense. +Thus, improving the apps accuracy in managing finances since users are able to update the most correct information. + +#### New Feature: Added the ability to edit savings +- **What it does:** Allows users to edit savings that have already been added. Users have to specify the index of the + saving they want to edit, and they can edit the Category, Amount and Description of the saving. +- **Justification:** This feature enables to users to correct any mistakes they may have made while adding a saving. + Thus, improving the apps accuracy in managing finances since users are able to update the most correct information. + +#### New Feature: Added the ability to save and load expenses and savings +- **What it does:** This feature allows users to save the state of their financial data such as their expenses and +savings added and load them back at their convenience. Information such as the Index, Category, Amount and Description +will be saved. This ensures continuity in financial tracking even after closing the application. +- **Justification:** This enhancement is critical for maintaining the integrity of financial records over multiple +sessions. Users can confidently close BudgetBuddy, knowing they can pick up exactly where they left off, making +financial management more seamless and user-friendly. + +#### New Feature: Added the ability to get graphical insights for Expenses and Savings +- **What it does:** This feature presents a visual representation of users' financial data, displaying expenses and +savings as horizontal bar graphs. It gives users a quick and clear picture of their spending and saving patterns, +enabling them to identify the largest and smallest categories at a glance. +- **Justification:** The visual summary of expenses and savings helps users better understand their financial habits +without delving into the details. The ability to see which categories take up most of their budget and where they are +saving effectively can be crucial for making informed decisions about financial planning. This addition enhances the +user experience by providing a more interactive and engaging way to engage with their financial data. +- **Highlights:** The feature includes a neat, aligned graphical output where each category is represented by a +proportional bar filled with hash symbols (#). It also includes key insights like the highest and lowest expense and +saving categories, as well as any categories that haven't been added to, ensuring users have a comprehensive view of +their financial status. +- **Usage:** Users can access this graphical summary by entering specific commands to retrieve insights on their +expenses or savings. The system will then calculate and display the information in an easy-to-read bar graph format +within the command line interface, eliminating the need for external tools or visualisation software. + +#### Code Contributed +[RepoSense Link](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=jasraa&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2024-02-23&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) + +#### Enhancements to existing features +(to be updated) + +#### Contributions to the UG +(to be updated) + +#### Contributions to the DG +(to be updated) \ No newline at end of file From 0ba62b0382ebc0eab020c46541909ca74dd9b8a0 Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Thu, 11 Apr 2024 04:11:28 +0800 Subject: [PATCH 08/46] Fix bugs in add expense and add savings --- .../budgetbuddy/command/AddSavingCommand.java | 4 -- .../budgetbuddy/commons/ExpenseList.java | 25 ++++++++--- .../seedu/budgetbuddy/commons/SavingList.java | 45 +++++++++++++------ 3 files changed, 49 insertions(+), 25 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/command/AddSavingCommand.java b/src/main/java/seedu/budgetbuddy/command/AddSavingCommand.java index c019ee32f5..721963d3b1 100644 --- a/src/main/java/seedu/budgetbuddy/command/AddSavingCommand.java +++ b/src/main/java/seedu/budgetbuddy/command/AddSavingCommand.java @@ -22,15 +22,11 @@ public AddSavingCommand(SavingList savings, String category, String amount) { @Override public void execute(){ try { - LOGGER.log(Level.INFO, "Adding savings to category: {0} with amount: ${1}", new Object[]{category, amount}); savings.addSaving(this.category, this.amount); - - LOGGER.log(Level.INFO, "Savings added to: {0} of ${1}", new Object[]{category, amount}); System.out.println("Savings Added to: " + category + " of $" + amount); } catch (BudgetBuddyException e) { System.out.println(e.getMessage()); - LOGGER.log(Level.SEVERE, "Exception while adding savings", e); } } } diff --git a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java index e17fc121ef..2473a1254f 100644 --- a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java +++ b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java @@ -158,25 +158,36 @@ public void addExpense(String category, String amount, String description) throw assert category != null : "Category should not be null"; assert amount != null : "Amount should not be null"; assert description != null : "Description should not be null"; - - if (!categories.contains(category)) { - throw new BudgetBuddyException("The category '" + category + "' is not listed."); + + String matchedCategory = categories.stream() + .filter(existingCategory -> existingCategory.equalsIgnoreCase(category)) + .findFirst() + .orElseThrow(() -> new BudgetBuddyException("The category '" + category + "' is not listed.")); + + if (!amount.matches("^\\d+(\\.\\d{1,2})?$")) { + throw new BudgetBuddyException("Invalid amount format. Amount should be a number with up to maximum two decimal places."); } + double amountAsDouble; try { amountAsDouble = Double.parseDouble(amount); } catch (NumberFormatException e) { throw new BudgetBuddyException("Invalid amount format. Amount should be a number."); } - + if (amountAsDouble < 0) { throw new BudgetBuddyException("Expenses should not be negative."); } - - Expense expense = new Expense(category, amountAsDouble, description); + + final double MAX_AMOUNT = 1_000_000_000_000.00; + if (amountAsDouble > MAX_AMOUNT) { + throw new BudgetBuddyException("Amount exceeds the maximum allowed limit of " + MAX_AMOUNT); + } + + Expense expense = new Expense(matchedCategory, amountAsDouble, description); expenses.add(expense); - } + /** * Edits an expense entry in the expenses list at the specified index. Updates the category, diff --git a/src/main/java/seedu/budgetbuddy/commons/SavingList.java b/src/main/java/seedu/budgetbuddy/commons/SavingList.java index 3a93f37184..a8b8c53d4e 100644 --- a/src/main/java/seedu/budgetbuddy/commons/SavingList.java +++ b/src/main/java/seedu/budgetbuddy/commons/SavingList.java @@ -132,24 +132,41 @@ public double calculateRemainingSavings(double initialAmount, double totalExpens } public void addSaving(String category, String amount) throws BudgetBuddyException{ - if (!categories.contains(category)) { - throw new BudgetBuddyException("The category '" + category + "' is not listed."); + assert category != null : "Category should not be null"; + assert amount != null : "Amount should not be null"; + LOGGER.info("Adding saving..."); + + String matchedCategory = categories.stream() + .filter(existingCategory -> existingCategory.equalsIgnoreCase(category)) + .findFirst() + .orElseThrow(() -> new BudgetBuddyException("The category '" + category + "' is not listed.")); + + if (!amount.matches("^\\d+(\\.\\d{1,2})?$")) { + throw new BudgetBuddyException("Invalid amount format. Amount should be a number with up to maximum two decimal places."); } - int amountInt = Integer.parseInt(amount); - if (amountInt < 0) { - try { - throw new Exception("Savings should not be negative"); - } catch (Exception e) { - throw new RuntimeException(e); - } + + double amountDouble; + try { + amountDouble = Double.parseDouble(amount); + } catch (NumberFormatException e) { + throw new BudgetBuddyException("Invalid amount format. Amount should be a number."); } - Saving saving = new Saving(category, amountInt); - savings.add(saving); - - if (!categories.contains(category)) { - categories.add(category); + + if (amountDouble < 0) { + throw new BudgetBuddyException("Savings should not be negative."); + } + + final double MAX_AMOUNT = 1_000_000_000_000.00; + if (amountDouble > MAX_AMOUNT) { + throw new BudgetBuddyException("Amount exceeds the maximum allowed limit of " + MAX_AMOUNT); } + + Saving saving = new Saving(matchedCategory, amountDouble); + savings.add(saving); } + + + /** * Edits the saving entry at the specified index. This method updates the category and amount From 76208778aa3f654cc36e448feff60792c4db2c08 Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Thu, 11 Apr 2024 04:23:58 +0800 Subject: [PATCH 09/46] Fix UG --- docs/UserGuide.md | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 477cfcae20..2e1bfbeabf 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -58,15 +58,22 @@ Example of usage: `menu 1` : Displays commands related to feature associated to menu list item 1 ### Add Expense -Adds new expense +Records a new expense under a specific category with a detailed description. Format: `add expense c/CATEGORY a/AMOUNT d/DESCRIPTION` * Increments expense of the specified CATEGORY by AMOUNT given. -* The `CATEGORY` must be one of the following pre-defined categories: "Housing", - "Groceries", "Utility", "Transport", "Entertainment" or "Others". -* The `AMOUNT` must be a positive integer. -* The `DESCRIPTION` can be any string. +* The category under which the expense is to be recorded. It must match one of the + pre-defined categories exactly (not case-insensitive): + Housing + Groceries + Utility + Transport + Entertainment + Others +* The `AMOUNT` is the amount to add to the expense. It must be a positive number and can include + up to two decimal places. +* The `DESCRIPTION` is a brief description of the expense. Accepts any text string. Example of Usage: @@ -74,15 +81,23 @@ Example of Usage: ### Add Savings -Increase savings by specified amount to the savings list +Adds a specified amount to the savings under a particular category. Format: `add savings c/CATEGORY a/AMOUNT` * Increments savings of the specified CATEGORY by AMOUNT given. -* The `CATEGORY` must be one of the following pre-defined categories: "Salary", - "Investments", "Gifts" or "Others". -* The `AMOUNT` must be a positive integer. -* The `DESCRIPTION` can be any string. +* The category for the savings increment. It must be one of the pre-defined + categories (not case-insensitive): + Salary + Investments + Gifts + Others +* The `AMOUNT` is the amount to add to the savings. It must be a positive number + and can include up to two decimal places. + +Example of Usage: + +`add savings c/Salary a/500.50` ### Add Split Expenses Add expenses that are meant for splitting among friends or colleague From 9b756a856da1e502c2026218389870136201b0e1 Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Thu, 11 Apr 2024 04:36:37 +0800 Subject: [PATCH 10/46] Fix bug in split expense --- .../SplitExpenseCommandCreator.java | 58 +++++++------------ 1 file changed, 21 insertions(+), 37 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/commandcreator/SplitExpenseCommandCreator.java b/src/main/java/seedu/budgetbuddy/commandcreator/SplitExpenseCommandCreator.java index 53c40e8ec3..354e147585 100644 --- a/src/main/java/seedu/budgetbuddy/commandcreator/SplitExpenseCommandCreator.java +++ b/src/main/java/seedu/budgetbuddy/commandcreator/SplitExpenseCommandCreator.java @@ -5,84 +5,68 @@ import seedu.budgetbuddy.command.SplitExpenseCommand; import seedu.budgetbuddy.exception.BudgetBuddyException; -public class SplitExpenseCommandCreator extends CommandCreator{ +public class SplitExpenseCommandCreator extends CommandCreator { private SplitExpenseList splitexpenses; private String input; - /** - * Creates a SplitExpenseCommandCreator object. - * - * @param splitexpenses The list of split expenses. - * @param input The input string. - */ public SplitExpenseCommandCreator(SplitExpenseList splitexpenses, String input) { this.splitexpenses = splitexpenses; this.input = input; } - /** - * Parses the input and creates a new SplitExpenseCommand object. - * - * @param splitexpenses The list of split expenses. - * @param input The input string. - * @return The SplitExpenseCommand object. - */ public Command handleSplitExpenseCommand(SplitExpenseList splitexpenses, String input) { if (input == null || !input.contains("a/") || !input.contains("n/") || !input.contains("d/")) { System.out.println("Invalid command format."); return null; } - // Extract details directly using the prefixes - String amount = extractDetail(input, "a/"); - String numberOfPeople = extractDetail(input, "n/"); - String description = extractDetail(input, "d/"); + String amount = extractDetail(input, "a/", "n/"); + String numberOfPeople = extractDetail(input, "n/", "d/"); + String description = extractDetail(input, "d/", null); // Description is last, so no nextPrefix - // Validation for each part if (amount.isEmpty() || numberOfPeople.isEmpty() || description.isEmpty()) { System.out.println("Missing details."); return null; } + double amountValue; try { - double amountValue = Double.parseDouble(amount); - if (amountValue <= 0) { - throw new BudgetBuddyException(amount + " is not a valid amount."); + amountValue = Double.parseDouble(amount); + if (amountValue <= 0 || amountValue > 1_000_000_000_000D) { + throw new BudgetBuddyException(amount + " is not a valid amount. Amount must be positive and less than or equal to 1,000,000,000,000."); + } + if (!amount.matches("^\\d+(\\.\\d{1,2})?$")) { + throw new BudgetBuddyException("Amount must be a number with up to 2 decimal places."); } } catch (NumberFormatException | BudgetBuddyException e) { - System.out.println("Invalid amount format."); + System.out.println(e.getMessage()); return null; } + int numberValue; try { - int numberValue = Integer.parseInt(numberOfPeople); + numberValue = Integer.parseInt(numberOfPeople); if (numberValue <= 0) { throw new BudgetBuddyException(numberOfPeople + " is not a valid number."); } } catch (NumberFormatException | BudgetBuddyException e) { - System.out.println("Invalid number format."); + System.out.println(e.getMessage()); return null; } return new SplitExpenseCommand(splitexpenses, amount, numberOfPeople, description); } - /** - * Extracts the detail from the input string using the prefix. - * - * @param input The input string. - * @param prefix The prefix to search for. - * @return The detail extracted from the input string. - */ - private String extractDetail(String input, String prefix) { + private String extractDetail(String input, String prefix, String nextPrefix) { try { int startIndex = input.indexOf(prefix) + prefix.length(); - int endIndex = input.indexOf(" ", startIndex); - endIndex = endIndex == -1 ? input.length() : endIndex; // Handle last detail case - return input.substring(startIndex, endIndex); + int endIndex = nextPrefix != null ? input.indexOf(nextPrefix, startIndex) : input.length(); + if (endIndex == -1) endIndex = input.length(); + String detail = input.substring(startIndex, endIndex).trim(); + return detail.isEmpty() ? "" : detail; } catch (Exception e) { - return ""; // Return empty string if any error occurs + return ""; } } From 432d2920b8da0a586c9aab3895112c9edfb4b9dd Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Thu, 11 Apr 2024 04:59:23 +0800 Subject: [PATCH 11/46] Fix dvided bill to 2 dp --- data/SplitExpenseFile.txt | 0 .../java/seedu/budgetbuddy/commons/SplitExpense.java | 9 +++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 data/SplitExpenseFile.txt diff --git a/data/SplitExpenseFile.txt b/data/SplitExpenseFile.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/main/java/seedu/budgetbuddy/commons/SplitExpense.java b/src/main/java/seedu/budgetbuddy/commons/SplitExpense.java index 78c25d9fdb..0e49812a2b 100644 --- a/src/main/java/seedu/budgetbuddy/commons/SplitExpense.java +++ b/src/main/java/seedu/budgetbuddy/commons/SplitExpense.java @@ -23,9 +23,14 @@ public String getDescription() { public double calculateAmountPerPerson() { double amountValue = Double.parseDouble(amount); double numberOfPeopleValue = Double.parseDouble(numberOfPeople); - return amountValue / numberOfPeopleValue; + + double rawAmountPerPerson = amountValue / numberOfPeopleValue; + + double roundedAmountPerPerson = Math.round(rawAmountPerPerson * 100) / 100.0; + + return roundedAmountPerPerson; } - + public Boolean isExpenseSettled() { return false; } From c93bb304d0fdbd95837a553d13464d7c5fdf0e9e Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Sat, 13 Apr 2024 12:08:52 +0800 Subject: [PATCH 12/46] Update DG --- docs/diagrams/SequenceDiagram_addSavings.png | Bin 48584 -> 0 bytes docs/diagrams/sequenceDiagram_AddExpense.jpg | Bin 0 -> 67984 bytes docs/diagrams/sequenceDiagram_AddExpense.png | Bin 56632 -> 0 bytes docs/diagrams/sequenceDiagram_AddSaving.jpg | Bin 0 -> 67649 bytes docs/diagrams/sequenceDiagram_SplitExpense.jpg | Bin 0 -> 47204 bytes 5 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/diagrams/SequenceDiagram_addSavings.png create mode 100644 docs/diagrams/sequenceDiagram_AddExpense.jpg delete mode 100644 docs/diagrams/sequenceDiagram_AddExpense.png create mode 100644 docs/diagrams/sequenceDiagram_AddSaving.jpg create mode 100644 docs/diagrams/sequenceDiagram_SplitExpense.jpg diff --git a/docs/diagrams/SequenceDiagram_addSavings.png b/docs/diagrams/SequenceDiagram_addSavings.png deleted file mode 100644 index 2e659fc41ebecb148d6e6a1d8ac5e07ad5faec1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48584 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

{t*kN3n5Uu;Zh6 zsRynEyrD7ypI~3^c;PcrzW8+i>n32Gnd$1IxE0{i>{&10Uru%iZ_649sN(thNl@XI zuiHQpNN|1Am0N|2A{kJOh|eyjO!HInsvkX~qq;5H?Z{=d;i2^vNOb|{J7bsM`se2_ zha5(uO@oVt-V^ezSA+t*sy>(~-|hRM>p~a<;8S(M{uhM%a`8J^^EUa95?m(iOd51j zMx0n!=Ev$yC^^6X%=*rvCdY=QkMI7%0-%P+qUxR3Y|{y6+`3|YBx|ZuuGhPlFL1*F z>CrboJ6Ye|zRhkv*J2;(?-GgKU?=@K;I*srm5PAUr`}gf9xNvfvUQbz&;c{;0NKh zI0tLGW+bN_Z)~{_d5FjIdQ|9vU-u5Zika5WDVthIT=jChRk&0+1{j|!skg|3>IDyg z^oOHwm}}*3kI(sFjj7sA%@7&l?{7XgXlK%n!14Yjv8TuOMp1pP*#<&9c}r?E{T(s}L|-IRlta`bPR`{m8=I6x9OPjNho; zoO{@K?2oCoE>l-(;uU2+O3K5YP_x|L?o2n<=&Rpo>l<+e^=RJ>Xw_&4VUB$L(IQq@Z z4ZJ&9Rh;(7vu;HsXt8)59kaP{{b8@y=lfEA06wL01ff&x=VPb-*io){`R&-A6k?;V z#yY6A#q(SjG)OiySbs*jA1n%#rzQlGuD{zx5I9b(*fWU8?sDmbOz=7AJbaNrFYJiB zSLkhE^Vyp7$nEl(j;nH8b;;3FWZhO^un51y={g>##&;@1b*RFkVYP%H2{fFIji+xn z0l_^6@JMhTuE-n$hA}rpW!7l^{rBc*HIqdrU@Ws3Q<}UX^L&(JK5dVDwnHGPrD3{n z^-tf6aT_R3&j4|oRaJv|h_k6qe?>Jkd2XKRcgKpH9TG~#};M*0Rs=b-1 z3O6&av`apzRo@9D=iJdhv=XE`jHZW7PP;Ba{jRkz-XlPyn7+=zpE6=Xu`tx;Bm7x1 zS#>S-FZlL)uTd#rN9)fw%OcJHMa?{VKWbsa6K@I6p_$AeR=$A?Mc;4n8&#h7Uec}N zQ5Uwt$^0y`6^Y68csAuDrb(V(AIH~4{;~g6?G3TwryB2ht`5bmMsHELk{vDcZlKN*ZKUiV&>%IWVK&)Bkzdk^^ZI?>Y zxY)U?e-=5*=YqZ!&g5*YM914vJ(zgh_*-6gUIl-@kMg7N>*ON@ z-V5B$YU2Vo0^mJoUXOLBo_KIDT1D^YGS8OKUtx0AB30p1!26Z+SEkS74%)b~sMjbmK*P=<}~L(o(hfY!4+MD;XXdpA7~ zmE-$TqbCb20o6Ai0$*KM>(daisf`K1gE5{l{1b=*%)9g}V&o8t7ZD%1acF~IRMPz3 zM1QeMKeHpUZyjV=?DeD_|2+xZ$(s~1KXC3Q)bZnKqohXn~CV z{_<&;(Wr;B{0_sOKfYR~Weu{&&;Ta5^*Ce5_CUf=^q|1#OKjSl zZh0N00rIXsi9i<+|NIl9z9PhvpZx9eGd@cjQu8m`)C_I9(;z3l7%~{3!^Q*0AI?Lg z73j~Sn)+)S1HOMGi+uT^8_Ak1wcWnB@5f;0vxcgWT{)6gIB zz?_AF###{i`NTeNFbdd@5LyH%17&E26)p8Vw=ddI+gXAfhDX3F{(iGQ47llBz za9bnc1_vbB?e$7H6p}Qst>H4Hub~Q*&w?`s?*`c;P&isnfCykFr|HGxy%>#p(nRz! z9pR|<&De0!`D(`sq-DF|KveJ25*^s=6PHQH@3IhLu|;_sxw)xWy%KFU2X|x*HX&B(zma>MPQCHT)@<>$)mcbP0vCET zb>LV>9XiT~!qURPmFZ|gcv0s)j2pG;vq5u@aYh24&V{i`|8-xZP*T?XP(-NY8X5ML z`g{B8DRywW1gy4?oE#(_9>`vEb8x*yUInJpSYyBi>lHc;efVa$QqyM<(>&Rc(ZjI6 zwEvMW<*KAFg{&zf<^3z~8f?Y6Zb}cMb(K&ix3JeU1H%TWt8^Z7ojg-er%E}|CFeXE zVN~p5^(h#5p2^uIGj-YMR+v$Z-dTLz(^G^{xtKX8Cx8n|O2VbZq+Cqy0 zWjW4)OOSI${A@K<+gRP0d5%4#SA&Zi%&gsk+_ad}#OpwA#YF0Z9N*ZeFBO1xH{c0j z=B}f(PhawRu)l(Q&96t3yPzK51BA})H#CCyS6&mezel@iJ(7u| zH};~C{PfFC)4zeb7(^eav_iFIYAL~{N{tKZ9UrOn4r=`nn^Jif1!$G`@$-dyDG}!j zy~9*bEiM2S{HyF5)%e$NF5ix*A5Sx!*BG0J3uB%UmJng{_1l@>TB3gaM5LTRFtxYX zYvsE{i#6PI;|(clX?U^076FAe$oX0KWnXFt>9E%v30@W#ZC*4JHsu!3lfKr3QjOr8 zU|dk761~K+%k{*3c+`~4kd55-Q((a)B?iqTpwmp#EKopB(!ti=rrm%mq>_O7y@mI1jfr4a)-dDF zqxxw#?MyoF*-sTiE~e+UpoVAHJ0;U%z7|+J9o6=yCrPUL3B!+q~;6;H?!9HMtU2M zn88|Qi&g~Z17IbBW%ZaF?vwn*{O#9hTnLy$$)c8M^{ywK#*Uh3IM6?N8OiBi8XRqy zoZCOAPQ}UX+1N4Je(S^WrLU98f;_GFIvP72bfv2jpW|PbQ{SG^BhM9x9Sew5FMdmY za5G*Cd^EhATR|l~8oc<--!UKGrj4PZpDF8UFwM_n{Ksq}>BM|mt*)Gf61R=dKAEYP z^5ka$e0J^Xl~SsiZuy9A2`gXirMmgU+B*VBDpWVm|Ain9<=W1DISa~(7WMZmj9%Ek z9=R9#BVmzC)(V3{m;^|Pf$ncMla@@SD)C+t1U_U!38e=+Ao1iZZG;r zwmm{FBYD`4eE$4bs1*zEqQf5HdL#oY`;P1n0hkX9M&+*z|m~c)-eWFo;?XyMa3Z@Eg9|~RLRpw8I3glO}-)7&z*LC9+ zxik|rIponsObDe}P$AV;ZXvXj{0*Fow``cqiZ%RJl1p9- zf0v*aOKtloqT{Webd&3+$%?4Ms+7kZF_c#uuHOoI3#l7!$v6Gi-||xT*oQEiq0kA) zw+mL@-zj1*W#dmuI3&u~yw-$k6dEXsQt|AH_oPP65+vW;d<+fxFsB3|Sfq(XcCYI& zK6;^;TdAx`A9ja2!G&>D1VX>i<+p*XSPU?X=Ff)B-;=yjin^>2%c$WLDxvoI-&|6S zbl*F$FXYB@8!#$U)N$STXHX#rX>SdpS*YICUbF!>z-Fo$B`1mc)NDRyyI%Y8O`g1M zosYE_;e#qW3$ifv$q8-~>6&mnG^q&~-j-qe41j16Pu${P{z*~7gdw<6s zO6Zqd=)}`(Z_$3!>JRi82iW?BjvW7j(k>(-FYY4`z2F^f(8<#_ zOaS@&U(k39DhQ2t+Qj;P;iQ?G#yhCzF@>jjGVa%wncV9yWnG#(M<_)X(*Ti6k`?Io10l`dNH(nkAe&3) z!=9JmpGR1kEJp9sxO3;u%snIf2~kbHO;FC{+H{ckaAQ1tyLn-fK75}HnF%#HqdQa1PpL5> zd-SWkj9+Gx<&w<4PD)3$&i_=xe0dm3n2$UL!@kXa7nX~PdWYcMpUZ#b3oM+y^or5>822*!gFBMwdyp5?C(*QMv&1_zOQaPi0e& z3)?v_9FxgThw=oI;Nzc*r>rLgDw*CrFrB#a?#GK;Ibr+ta5)Mm^fL@zykW+1fJVc; z7ZEX)yV(Dn_XoW zDkDMBI~SN6NKc*`7!a?&r6;)DM<tVgNv;5!i}YZ z)A<%SPMZH4F9RWB378(*?tmZ?P$vir1xoT?PO6M3rd)sr;w?2d2?7MrF~hia<^Z)- zU6mSMq-=HEj;jTj8l<`oni2%8a6sE2RhG2@XdCwUNbTptAWGUu6>0qKsq?be=2s^K zYG5JB!0~WP#LBj$c}N1`i+AVbNgt$En-ReaCJr6yX*m6QHNdt3pNyh5KE4z@Ag}0! z4&8#BG)@g~e^dxeI(9F`5h*N z>JPyYTEOCI>xOMRzC#E8o zsfW0=^EU?;@a8Tepec?28E_;i@n1uSa?m58I{nah3`=~MdXf|@{;(P7n1S#B&i7o7 z(L%i1(!e9rar5qmRkR16LI6aBuK)ldl{$zY3-Gg9g{|O0F$|xV@Y;-#x0w$p*OZsT z+#{Focw9GQY(k**_cb($$dXA(GFYf4GE1uu%H>KGNJ2S4A>!d0C`llnVFjAC|D`1S z>G(g;Oa-bR6Qm0Z+^lx(z-G!Id{D+8IDTw@Kaq-uhWs|brf~yv2@E^(8-bG=W1XR% zOP=>jkAH(oMmOA`*#nnPviPz!RG_)Dy;nMmkCOBh4oZT|}dBf>40U3!<#1UHY*(vb|?neNk@;6llOzH8u+hVYYpX1`~q@joMw_|9w}# zVTAF^SkNy%EI|ILTVf8a9FQnbYklje=1 zCjY_GKt#n=9KwsQgKcZK2IKD!RGi!g?o>Fc!{dbOaCB!W(TEkb=qeem00~GSQ z@b4>FPCRK@4mhqeq|m%8zKBEr$!#D}Vm(LLQ@jyx9C|C}VALLN?&IRl#l;!FdyV=k z`J+lt>yCM)dD@rVd2Wr$?2_4pw66?hl((-OH5&LSCufAi6+)fk6Mh`PI4Rn3;YrusUMgejN7BXEH&%4Q~?XdVnhD)DR zdrANekDj3PIp}gX{!|VFCM%L3i37xHkSEWkvHl6?NXwC8OoWX7{+kFq9j;L(w&VbTISN4KXg2F zTjV@1k$p)dpB1U99InNcm#g|7jXxRh<+Csq79k|kzaud-t!&@xlZK(C+oHGn@7}27 zJD@z2dcRl^dxmlSlPLuW`{1WXBxrG#EOV+6r<2`i$2_LF9~pbkkmC}{_!H%co;o`t z*PTGKd&d%*&CpVGA^q8HBrTZPb-#fomf~|~BU^5KzkKe(h(;{>A5t5U#+<8`usyye zz?zelbHXL}RCl45@vHxjmqCQQGi-N;Ne(P64;Z4?@YDG)8k#M3YD)5FJbCX_;4w9O zi9{pzuWGhnq*r0C;YT_K8o9ElAQUXuNFA9X@t5z$WGAzfi>GmTPqw+0Y5Gt0^epM; zVI_ZY#Oj;6=tO;p5hj{pR>a3*%=yI0_{vKrTHK$F;Ezm9t_cGK2L|JL&B)dQo8BuH zHq2h5@tD|B0vLp-hC?vlYr1^L$vHUQ5b1~H85LJ{(AUe@l1NI(EwNFxV`<}7N_$t= zMUfk5vBQII9YJG_5Wqgp&wWme7I&I;?#t&h_qhXU{5P&=^xb1?Jt3%!RP^b!nnWbq zi`Yv!rJwJ@;Zt|_FG!!TtL7sm3BgF?iw)HFwJ6JS>C@jhh$-k6OhMP3^dtG;j#aEI zDILe7TITZUX3J{f?LGc^v#q5vZs@snB1f z8Qjj_b!Cd*`AI~5`0Y7q@%~cmx3s7CB*1S2*s$Nq5A422;)NLnNvOx;3Fg8eePa!Q z&BpD?PD+?x+e#HZ;~`zPT^f~Rg_%CJU>RO`M&IufL7Eh{P|?YjBmYUCUcCUfWrV|j zXB8vYrg0uTKz3qAwp|Hte0);EKH`imroAAC8ggGq zVdB9=aH@f#oO))M>o~j8Du|rwO>BUl4=_DoB{nDfRhN5K<=f!!&pE`%&x*?|I52_7 zJR`!tfy8w&KY3iX+yjUI#RLmfc;Ptg5^W6)da@gpkjBfVT7O2LxfPA+o5h*3X_tJCaFg_DlDl8)L6NPJOkG)hS+5;>#y!WW@h6vP+_K(}jJh0P_`*T_rCB z%Zbkh<1g*QY&kc(dLHQ^lEWP~F>>79ls}r9m?wR3_M)4TX*lkN`{G0A#-kGeyFCea zwyMF^L#I54qg6Wh!W~BqE^skk8c_Z`g*z(+0kO~D(A1O$rJ0;a<3fAm-xWQM@0je! zz~<8_x4(RO&;@RCO#=o2fjn?QDV~>$nOwt6#OP=l>d28z+pa z{55|z9}6;VT4C)cBysZBVpkjKQY(t>1}Qo6oT7A!!LM}v(_MoJa&oI=XU}i1swvLP z&H!;uaqqpFRwkYP_49Uz(iX~B+o8tCY)vdjS7WiY(h)*?bd>kVXZCHNO~If|+q}8X z+(Y8;PMX_n6j?bqm$vPPZD-yy?#aEqOSxywoqsl2#2RyOQT8$iHA+oox{bGWuORGb zDiCyCv(!Fh8L5E$?#*4axE1gU+9DTsX7;d6srI>8}wGpMQqIjUD?p%^PZh32GecY>T!5lg{t&-o|dtV z>zl63SvvXUE(SF<&|E$+Q@YTo0k|qHxRQ?a8#g|cU6Os`7fRPk@(s@F2@` zGxmae%--=T7od|kMznbR$xe}%n1{L_gspqSlMU4ZBvT8BIuf2`$PsO6j%^;j$FL@s*JocOY{_~reJ5~2aOQ^0*5L@^-#e?0j|(@7)b*uuiX z#G`97PH9?Ee{#^X!+c^hzoIp`zY|IQAHj89af2BrJpf&klr&n}B{uW^H&DU0rX~7x zmUoT8-Ao!#B(TcuDZA!wExI*6aa7B<>CH;N^MU%lbp~)8lZFSrCU z_b4y@4=Yh@GYsdkOL3A^@(oW3`>PWTL#8TGJ5K;wcE76fbEFx~%9Z?l#_hI>L=*U$ z*EN1|*z#cSsV$KU_$Z2eH4~do%bE^Ry*;UaKkYl7GzB+oBNQ#c2`c?l0%$O)yI`kN zwhalVR|=78Df*(LjD$pr#O-8#_A0}gE2ol7_VWDM;~t`!QeHt^-mNN zE}u($-6@H_G`!C=tENOQhhOZuU(;gx#X*qcTpH{u;=I!SpmCA)*(7=_d~L^PZh?T6 z2tkwMSku1+O(3+tf~H~y2rA8|igzL9s#Rc9 z&F-_EM#0D5qyb}GzT@t@A_EF%}HD4zQnToul=+?sHxE(B5X9bU_tdT zOhiC{dY>)t-P+b*z)-XxJoST7{PlPcEY$t*=P01`2MX2!nZNX_XrcP(t;eKA1zE1x z3t@1RHvC{Wy~j5j^=4*8>aflC^*1JFc8Px+Mjz`I+oFp_>;D`tWwRLBNeC2)ds68i zXN-U9FYHFaa;K}@((jYdbZ&6#VyCnAUHz|KaFsk4qR!m(3}}_k`>LO!*lRqszR)5U zLo}kbQKm+V=!0U)@T=VyrO&`__ju>u-esDV4oZNA50X5-MU1>nSJP`2*TMkN$Sl1y zCNy&q_@b>5|ADnH{^xP62@k&Zw*UynEyAVv{hxD2V>8u+!5pBqJ9gE7Tw9n+a)og^ z8huC|f^7ZW3Acr*i`op@rIlFxqel&M*skhtAxsA24f4x>5`K8kb!==bTOr!A)FeI7 zI*-llfmiSkRWupk_z_W`xGS@!TgM=3|J9y9dy+b}Gyz-8OxBVd|NgS1ZIepAaNvCM zcn}TwpNd#Xgg0&Y`r~`JTddYq**gdRRRbZ4zoWuq{wf?S<21HQ6r()Kjd(liYy3Mw z$*rd@KV2&Fc#-$24!M&i9A!Sq(zFDfV&HAzEMnx{Pfpxki&Tq|*6ZZL2?(1#a-??L zx|^tf&K3Get0XY4$=ClbqwmA@%7h}1{r`M^?YoRH?1Q%9cPab&3%o7Y|I4WV5#pT& zUlVt*=pEQ`5*w}iO}$oCi?!LC!JdH*>Q?kc9*OtzhTxx*L}^z&wDsk5*A(7`9X!YA zB@wEcB+eKYPQt*CcsA1_o{^IJ>qXl1_rIA9Ym}wcPADKQsJyfrChT zKxW0SzgpMf?7I@F!~5rgKtd5V{JfkQ1@Im-FD7BW&9U(E-?#Hk);=u&pT1pusQ;XC z>87F;b&xZh8z}Rpj4}__j({B?HO9Z;&y_Yc_C`~+ZB4jIw(#AY-;(#g^%Th6*Auymp7@703Blo1{DOAL@6)ER z#Z3U0+(u_xXaFsnd&>aKuP0VtH>kf$ga*1aboVGUZ1H)O3ROU7r`V4DkcGwJ>oz-% zU5@jh26M$NRod zoEZEA@HQ)G@tN))2U<|W`6JL-Y#rqUceA-bqg9^IpI^EQY}hm{7>bxCWZ^ZTLg$k}k32wKgGc9%jo=*~VSWmW_aG5)WR5zB?;uR-X9T=j%Wx z$9c~2P5AF)K!H;-3-GMh+#D+?$K`(kq|cb#^w-%;546xJcu{n2GUG*oJ1x8(xTWkm zh5)L&pIgS`B{vN;y)D6Az&CeT(aAx-n1d%=(5~Op2N=SHUfuj$5*cweD zw<241hMp>?W@8APVAD}y*}8P#<*2uOgJ0TJI&E>h^~@)$o%A-8?5ovU3+@nlh+KNP zESmKGCp`dJ>;of$)^z1BwU9#F)wtOK-H7j7zrcOJEytcOK^IJ#L-~r3@s(P^iExqZ z%d`E^Hrxxi>ZRkHH1ACWm-v(F?R+K!7_romIDH=0)Hhy48pA>yN?V z$L05QVMqnj-Yetp9T;tT*SWx3R1ULZ<{HD`G2lGHq_>kg5Ej_==?~CPDw=!krFePvhgC28a0sRb5@2?X>(*vLQingT$1zCs;XX0? zKk3_0ATa<7^P;SN3_2dvp_i%qqYdWd3B!W0o0R_I-A;Yf^f0_9*U7!z0_RXVfBg4} z^A(g|Q>up>q`gtg;UZk>8kv`1`Y+P@E0mHNlImH31W(Fe`7Em6c#q=3zPDExF88jq zc`f}0*4m@d?i4RLyiKf(CH`zoyrM-Phf+a<=xBZ98TZ=Cu7^a><}Z0%r|iq8Gq#b> z!BKPqfd7wF)yk)B_#)gO9`S#UFP(e++-*-V)fUDfx@u!>ywtOvgJ;3Id|(QiR*YR$ z5Oa+uNWX3Avq>Uwp5|O6g9-HcEa*GG>hoIAUpPsWL(3<24vco-$N3SeGC;ZzPI_$&ace#;7rb*^!k?s@s*_bT>iQwxTdy@ zdlFpCdJ#R}Z(m-y^}(I>&eu4jd64pK4gN=*tCP9sFF$Pw{@clVk*}H2EB=kv!uiBY zbGe;OgOaX?qTIlnc&~1hYm?p%+zidk&hfO(CnS6F1}{L}vV+<0jk-;HpaV_Qu1GlCb*mCk7gKcl=(L=M-VU)e)v1wPUo6_ZO%>Fp)G^pg! j_HQm->+deze|25uj37-~dE6)s{HLaTQYl-(^!on;0CZQ^ literal 0 HcmV?d00001 diff --git a/docs/diagrams/sequenceDiagram_AddExpense.png b/docs/diagrams/sequenceDiagram_AddExpense.png deleted file mode 100644 index 0b345200a0318f72eb674cb08293426d2073b2d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56632 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

=Xv_@ZnW6c-Tv?ZCam0 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 diff --git a/docs/diagrams/sequenceDiagram_AddSaving.jpg b/docs/diagrams/sequenceDiagram_AddSaving.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7e92ca27d0ab8052090c840bd8ed95d1cd8ed02a GIT binary patch literal 67649 zcmeEv1z40>`#z-(sH9jZDWNExqC*NO5*Cesw8W4@GayQ+h)6doDoRN=7)Xaf4@iU3 zAu%w(|IEN3#`mqe`|Y~>`@7d(2xrcF-V@JrKlc;wJHAQ^GTTY^lHlRtZ9ge1bruhg z2!V%(-wfFdT9`FwAA*1IZO+O_;HA{<`-q2UbI10Cs;#+$p^2FR9y71x>Tk?ET*fdP zTV`G6;ju80fF|;o;)pJHo|xgq!y~7cVof zIG-T+!OzdZ&Bv?0+F#emz+!Dcd6<)lnVBv#k2F6A7Z{37#l%7%W^V(2RX7iRaC3oX zUJ39U_&|Vf^;ZW0zJs7e+|ts_K*ivaoC%nRG(WE(2d@BVW|NaWFMpbuM-u#QW@2gp z{*f`zGlgL;ku_~9_Av*(q# z6yWA3tc)cjR9DvlH?X!bfmy6An~#HsgLm}-*L4?kQX~69xfwm z+QzJ~7wDbzW<* zG1dhlxOzRdY2&G^?jvqDtzj@Q-iAZl_%W`Nxr3yE8D_I_`?z)=AaTF{+V$PAUe}>N zGn}rxu(czc*8wibV`&9*I3smd_5@D6;JRjZYg;a1r*C9n3w{FWSe0d4N1QB!?ZQgC zow?a*6GH%&rdwt_6p` zVQg!dorV54Jp`q|+*i-dQunjmtceolo(5|$fNlEk^88tTP0jxM>@imDD{cI)3V{1!ZoNST zzLEP4(rO6E3w>P6B{P_wDX!ZZvk<~`S%+JI&|g9;_z(-Dyi&NEg8pmpxN0$QP`LWn z>a;ha-+z;%RW$^21($ud-x@q%Cb-(`j{>K)ftju?uvr^M0sH?Q82s6S5WV>d(KiS-?qt6q9^WAuKSU~wVb&&27#9@7RDKt& zSYx8A2KBcY#BVZw12B&^Kh*x zI!;tq7yJiY2%O6NrHZ}I-PRO){qG;us^0<*;V(HQ4-QCv-}qSF{c+&<8&zFUUhjl~ zJnW2fdE-dHMeXSNKbH1_w9a*nU2od-tDq^G_q(=Ud`H^B->CzpM0XhHC>; z7sn|*2o{=Q@+3Bvy1?9T2*2Q5uuHmnrbgJv+!2t#0l0t(D{z@unAnLRRmw+UXm3`4#P156%3OqdjYRIsjw1z%s^@`yv_jzrkZ%e(Ea~#~JO7 z?lR7BZw%|>a2BVwe{109yGriqNZ%HNRM@17tQ zMt{UR#Q25l&fI!PpYKcCiIdQclDx)9HwyCC1mWik^4c;sSd)LPxA@ykl85Uz-9oJU z_y@$|?@1)ByEQnD^mV@TPjjTd)C=Up)%@V5k23(jk8%D-3dt+@rB-s|w&(Ya|2w_F z|2Q2!-15F&F3yhq;b7d)c07L|@9~QQ{+lS^&tibwI2HNAaDLBnVzdksu*2!j&o`al zrc8cuz@JxH_eVJ3A2s$kcjilLgOkuNM0r&tHgZ6oe;x_^Hf4Z~8-l9Me}3}sM_Au) zW&^*IH2AL5fK~Z_4Le*fw7_BJALbi4iu0GU!>{9!>(l>9>C zH{y}Ps}Q%rgIteCuHnajGmAgDbl~@*$G;F2_`hqSBvi8hW@Z)Dmy1CBG;Ki_5K{x*5{ ze>&W{k$8U}Cf3S&HpXSY+wq^xyuY!rUyI(K=8AtQ^A`9jo3S2d{y8>Q5NG0XHume? z{KJgpXU9#s*Tj8;Rs3({_*dTWuYDTxH)2MAwEAc*Jhc7>)Ur+5Eex8d7* zi}gbPfAo`iza3ux1G>3}#o*;pT)2l|{vLG|{HlDF7Z+Lo(*pLl*Yg*CO?&iOOG^+!4YR!QcVn-#7mMs;FNWSK09ObZ`Lkuk|u< zMt?(cYV}$2(;)UoZ4pdlTswZw>wRh$pDa$DzSjoD-+Kzezc99dT;(^C>4r z;xSJge4`J)bOH17;dPJemo8vm*8Z*kC5)5lHB-TZ`+I{j;Ed_&9{t>Y#9v@`pJyW^7Q)Ao-ViP{KHn{>}=1k`scnB;T14ZcqQTSNhr0!wvbb zd|l3Wb7yR;@7(^=Z?*ghFU9-qoZ6SKIrwflE%zS{xvVGO__=x4!1Zr}5gaSRi9GIa zoN)eWdH+i>gqsUD->>KY`w#>Nc%PMX?L@f2clE3~Cb%2?tOVT8R4|}PXqb?5n%ZLDoyl{1%dT%Oj@&J>#wQ&pNZ>V3ISiga%p|~KS%%h zzN!abpAK#}|1hBb>_>ZW^kze}_?tK}?qT=Sx|a;hlwdaCwVT+lFI@kk9$W|9i}Y<_ zmf+Ql8{Q;{EA%mUFv5I|Ajc(L8xuVahqXZUU;6UKuLAq)FSptd6v8pijX@!t_m4Z^ zzap-WJ^TOgU4S^b`24Ml8=(gKDeik7S3g+00P`)JtFN?opY$EZ!=uMLDJ6d1;o?XU zEI~yDzEZ+VByl?Mps|Tu4}JDIzx@zuN$<;CdX;o<-?~rtAG$yAyq1t#y*fC|aNFhc zLE-2(w=QgS}HE}ZJnY>^}keON9=Ca%DvBE=n z#|rXO;$wyxp^1s-A*MzoCqT{vqvS8i`-grHV$2C1og1s|z&ISle{BU27`CbOR(N@>O(?`kjNhev`#m{8NxJn=B@pp;e zJSubfXncr40LzXpL1fBXH9^wN`c|x%^JGoTD>#e2z=OIXy#cz$k{8S zEK)dGMl;ZordQN>d}>85j1mBeyq zRwYSQw=Px`HgbwY{F2H-Mg8(5-O3yEXy>x|>}_+E{`m>Hh48R2E^jhAfu836>d*{m zU6ioiKwWesik{A~A_p3LQl-@;=p*|pQ;Du-u&UwCWUI>ObUWNI%%ar%6KzmF(q;e^Djz2oi>@6N$k1QdBn zz_cmpv`*T+TgP+|^WEO9{BJM1AywS^{mDwq5aY#*7A%@Y%L~Kdsmcv^N?@JE9mkgE zd#~jbxAOGr=C!$R_0SfbEMFd}WR0yES}I-~s~&14fiBLC*AwLQN?esw;j%V0ZBf15 zrdi_V`gk<7v0|>|=v9{nie2Us8*ql6A1KXZ1HN5~m~%2(&K-={Muq6Z=Px0VUDhU| zaTLmCca8VoP9vbd!pZL2hu;GHe`q2|@=h+c%jchY+u$D??D%XXNk6H-} z(JN@wbS-cFF+KSB`)HKIrw?Z`^vZ9YHQMDnZZI9-5dP#Pn0*N^LO)Bjgg3c;Zz#P% zzduAg{q2zw^*V{$v1EIbQGR_;x4V}2Cd3mNJMM;!ASq~r3Y{=2zntIZ6%C6;y-J&G}J=7?Z~CUp~ghs zcfIBQMlTGPolt^EFUakbr)_XI$qE_dwhwflu^W$on_LX-%OFSXa(L0Q35eSXiq?pp z>!M@bl?E!y+nf^i+jZGoDDeUkgS1)h*Is6>mIywgZSC6Xa-Pj2o@2X5C)XsasKpdJ zqMf^!r7T$&g^Ek#GR{)cI7!MtXZ}i|WFtcP_yUAF-Fm3owAGupwklS9aG`||X22}p z%8QUXeP@df>fLcob@E&z!par0qbkgub6h3uji<)KMH!b>ciIfpJa&0z0n|g*^-k#3 zXQ@8(y)mZD#Fbkg&L$nAK#Vw^Me!oq)98`Ks;EGH6RIx(ni&8z`}(T|JSoCUQf z>ZH?(Wmjg+wF3hK-*qX^$nCZ1oV6?8ZyzQ@=bE`I@z_KGZ0S&BYdVSzseQTm+A~-~ zHm5y%XhZSMt-_**fY7AOQqZ7U%(azYXTpkY$_dyJXA_NkzR*-&ps5kv?dqHi#}1Q` zKoL*PO>axvj#zY1a6hSH?Q=QroA}tYyLpF+mS~@3IWhZ2G|QC7n|w67t)U$uOJ;-$ zCLO!(6~P^3aWOlnlH_J>q@WS9_KBNBl}w{*TQ04exe{GFD+xWI#zsQVX`Ohy-gW*3vnbSB5^-}Hhc>MVB(|y+~XoiFf_0QCI_Y?W!2rkA( z-)426mz0+hcc?A|le{wj&erWwLj z_p(X|gDgIx-Tj3Ao5{Nd#7)*#^RY}K`e7uJLt6T{J@;^FJ3qnA>8Csj&=*x(dK4W{ z&zMT-F2@lPg>4hL-A5!5uRtZs$nXi=Xa^zDTh?bnWbEaAOi3PE2{ote&a|J!Im+5g)#; ztE>bK8LYSY2tC}1!HiFlVrHD>BO2?r@OX`;#q1ny%QCGkc3rGV&UxP!`r_4%U4Cc* z^fM1a!-1OcYqG7-@q%$^#^uICGg+|0NiSjeNXvG&?F)JN-3(r=3Q=6499ldYITkZ- zG?~mb0ee0+UBhcQH`c*q!!&}Sy$9;U1i`W}7dP2mT2IePw zTT5<07}!1gGIX9_xqInq3x`^IytniM1-FFq?qt=p7g3@J=rJ?qnt~ohc9~xD(N6r22 zP#3FJ3KfB@L?C8K`Ii28m;k1GxIso33q!yTE^ok)*VOe|rux9Sl za`w&`%OKN^M*gu7cHIm5G#y*$TyA$44yP2{tZtvtx|)&=Z9mq=s90i09v3qlcPg@& zSm_b)t}jLc$rt$ePLL>q;h7N3D%u3#NtqF;XK9!2v=ngXGX`ok@)|cPHcnq{Zxj`f z_N`xlekgp%QWb2@Bd_$({~^#``GAM9hlu9iDqo{*_L2soc!X)55Pt<|=yJHSNr21w zyDIfr&##NZuldnr&vNOqU#iGr>{5OH;K{t6YZ@|D>S|h|*OaSof?j=9fNEcF%5H0w zdE-}fCNHUtN8m!usp;M)H72VpUS=dF>p!?NQxroPe*sI4AOS$&C2B~Z!OUXELz&C% z$bG!=dXFV(2KYanVt7wR2r`Y29g!r)h`iUHd=8rJT3NM^!gS;b zGy8JiA|+yU7TBuCW{v)4k?Dyxn|(!JX1nIW+O2cqTGOjwi`FW_eus+ChYlAMjrE6W z3kVFHF`pR6g3fJHpx6%rV4%&R>Xk68Pmce!~*N|(m0~T zKKmBCPzzyb391%GdVE5SX<1eWZg=Yw`<3fv>@@JF83WIZC~QWaH;gr^-!US_+sO5Po|mIva+*S*x5wX1WTAcqtvFq>vRHDw z9#$|aFfD`lBr^a!z3vm9GS8{zUvawW7B4iWMsT`*lp8>HE@!u9ngpIAx)gaD)zFqx zdU7k-@lQ(G)K&oB`)SNRoN_h{>AP50eJ9uw;~QuDO>YsM_i*eBkV%g%pT8TUSED}X zG9afhXB}f*+F(=F$}9judtoH(6g@a!CK{%5)_bjD{gdW}9VWW?y2~Sc@eXVu$RJ=V zyy`U;;3KNN*w$PFfc#SYE$9l`X8O}R#l#bFuY0#viWZnp)QODO)V;amKkMhnP#Ulc zA(a`yYoq}0%10ybN_yYi*TZ3CG6{?anyO1K67evzg%*D(@A&MeZ5|JS8IEL39`<(m zAjEINuY^VwbuJc}B{s+To8d2xuPl$VxIRcFg5>u2v$H%rM9?Z(JD%H1I*p#LS45UI z!%oyWj~5w{?i0FwSM8~ec=mCNSJ$aqPl?Rkwi0$hF1M!)gmde8VGJeXEPBFQl&=$2 zXP++F^x(Mt1Ak5SUKO_iTE=1k>ZcD34QA{sUGDNEn{~N8ENIrEQ#|Ph)93buG47N* z4Vuahs-|H4%qs77M2 z|9GdqonN83f=i4j!mTL>!kg_nT(Xq+iP`N`(%Zqr)Z#Yhm(iaXtSW}~u^$>;wIs|` zkEh&XpsxA$$%S|8)5#eYYQlMos83Vg$P8Uk>p*>Kgd&Sw0^*~O5>GrxR>;rn-~$_A z((`GH#{e*Kkw(xY8H|zhx-Oao*qYiwhj=v<*gU>_3flyCuse((b2zEQl9cpvbn_As zQf2}E=$e>ny;t|e6Wz?@D~9NVWi?W$t)#DpyL6%!_Vgjs4XT}>Esau)r+xACU$If7 z#*_I2)LZ?i9}uUCJ#Vy8k?V7}(7e6}(A%4~(K74#b** ziR{z~>pPh;5jn0VupR0J0v^{VbaOcJG!l0nQE#9!)Rzm4>SQt+s3@mK^o=u?RSfNA zKTvr&vYZal?xU)o;|a*o*yb|^4IcGx$K%Yko4lW}Bcwp=q$$1@BUC^l8FwIy+me(Q zyq?(-aJTDK?jgzq4$YB+BlP5)7?Y641Rz5%ex7ObR8uMj9YxS;q+0vw=mw8yclUE2 z^4CwimE@AQG>cqZNG>{KJlb|u?^P@YO9g>Gue=wTP;uaYK7L|ok4!33)Wi)4zwZ()C_R!9w zYk2F!ItuLPNK@h0(gbWycaqBni*1{0Ip0bZiU7PBKn=v>HJ0f^FueKDBeA9? zizM}0$A$>-u_w>M3$hxY45)*EbfvoHAiL2sN+}P{u(vK`RUwP3(gvOw5|>)~n}6uV!S^ZpN-%G(aL!%7K=Z$2y#t<6=nH8xY zd$W(oiAWQKTqm-T7QC^Du39$sB++eIv)D!WM(u(wGO%S@ z)Mk;K;z^CSv)P`@npB5?OVv=*wTlQ%p%b;J_whdSRJZ57P62WRdMciuj3`r(B(1kM z^chGO)S9Li4dlEj)hOr>(Wo(sb%jd?33j?<TBTdmA!Ds-Q!qxfPqGgKV^uC= z6^6V4f2uu$!r8Gm3Zld~P?1GB7pMpomY=@^?Hin;h~?DE*N<`N@vV8EBAcEVKh@mU zc(&(VufJ#v$`EO-m(~+%&^w?Ygmmj)a9jQ~+-#k3vv1p>$@1B|hZ69m+ngukpd(09 zW>HTfwt}HVx(sx#Dp+Jv&$&0nuE;r&`*qY>4@BAf7KSve56z_z zZXx~jzVAcgsEf#j;XIBK<6W2(W!#vR1tP%kc#5@RlG6$eKVks!IOI`#slZhJba$$C z{yWMZMSJW0^6?nl;D~r;#dnk-B3LxNM~Z1^N3xMUwV&2Z_jR_hm!rU=<;k9MKR$A| z+3j&a@L^@2kF2D=K1_5JY9kEoz;U2Pj9k7~XsnMIBca3iS}fVyC=r@xq!zNYRr|)_ zrWk_j%owIc!F10rD^$R+CM%z7%X_=u*=XSkrIOwv?i(tAc0J6D#UHEN#NtoA0t78#7i~htHd`;;RL`NHI)fM?ASM`Zjx!iv@Neu(+?g{<=td*2!$WN|L}Wv<}Y- zXPPv^jd^AJ-uQ@mX1l80l~$h5?YRw`EGIcgSyIZ{6H+iG!@j%?(vf<|jV=Q1lQ>!z0YX(G;?%j~^dT1l$riJj%Fq&Yzu97(OMB-)8~lNMD~H44Xin$TC$-lV9jzMuSUE@XkQDu$ zS3RP3F>CA@W$1>ZTg-2Gj+73%O%`Zu9~Gz(?@6iFXv<(9Y4?smJ1obppkmGXqbJgl zvWwjNGLz3PghfS-_{P9r-Q%j5rd;`)467qxxAsrA>xr|1h{XvI*!fM18;#`+vJ9wP zX>&HesBeV`&{u(0*&kNJKN#yIIN^z_1wbqhB4V;@+s&IhcsOlTN)|JhVvJRmD^8iJ z;UA%M)^?p~RDrde(v~?pR3)>&7%ZzaHbwvFJ)tZ?l4LEZySLY*Yk35(ankTcqKf6j!#ZAdEPsRQ0l(4a6W0!5`cz7_D~m*kjw3 z(bBdBF?aX86d@hRu3X@o#aGUj->#10HAaS(3XME7Li!ghRCXvE=2YZq3~M5;n=MXR zJ+lpns3FtxeKk;Ju|1RViiX^*+~a~H^&N&rz@=|Wb(={%ZB_wes!ml;)2?9lR^Dfq z)1(%nj1D+*C*444s(XP|;t_S2S@bMYpk=%%SbGm2n?BTx%9{vvsXVJ!n?VVy77RtBI%c^b=ool}g_`*U72L(wh!3Q#%h1yj9GYR;c| z5L5lBoS)oXY?^3j-=MON{U%!)-ICy<+2X-vN{NwC&g>CRTB%PT?Nf7*IUUZ4^Ex>N zrloYK2UlwBtz)xn;zR@s5@Uxel%r7zFFQFhedpg@J1n#F{;c%ftQ&`2+Wl_2Ct2J! z7fat8*D0g%NL}RP%cUc?k3FsOC?8X18TF_KxuN(`apbMO9F$Rg%xH2~g{T?0!Qum% zHfw}4v$m{sbTrS0XGU~A{>P8C(LOwU#p9USK>dVOPHewQLN3yODskV)p<8Yx!uv9L zO0~={Ev2#F7}0(6lGMfG96C*-xDU-#a6}=Sb`}Z$kP>870;wK~abv%~kZkeMKIV39 zV_f4|W!W?kmoax4JH%DM%-xx?-+rmg?L7j8nA4@_Y--``9(>BVhoZr8yDytX?fqLQh}aqc6zjW`8Zvr^u7k zr~ZaHYD<6%fB&m!G+{ti&I_aE+vlCRvN7S6ePxNK?Lw0Wd0efw6VbmW^nia6ya}!r}~JR8@VsT=&`F2+xB@i z7Zy_%YsD`t4Y$n{D<}8o<;gXSmb7w)qdcEvu_O9i2-x?v3QT)@Aus4yFDtkOha|D7 zf&70SNQZA{zwPBKI*Wc(I3I`zjCStI>={Tfo@w8fWOU^X z+mO7DorkvE0QtY_lDxWPU-3kuQAyt!-G-{zGq99B{B8x7{`+6KBfQ0ih=%qKTKi{k z=31(#4|I}Vu1}@;B%s(`0)mKU1%=Y+N|+W0({k=~pok#jay)eJLb><+yV}An`?F@t zlC!oRRgIF1anDxBf>#nUJ(GsaA4{#Wb9jxE8F7?es&lJ~HPKUfmuvLehpWq?_71co z=S*IYcOgn%c~@nqseNL25=r_NVKS=dDde4nXcW^ZsS`5PRWgKHX>+u0uT6h_+`PB1 zC>*IH`hLoi_k+1MrQ*fXKvk_b^{!iQEeX!~IZtI2&Y!!g5-$GYc=k5_6b~^?j7p=l z&2nwr3zr(S8i!(PnKS}Nk57^UHPIvf(`YY+!q|Hv%{*_v?CUodn5`9vQ0tPw48qal>75KH^~v&Rqdw?TU@ZE8MwUrEI$*JQF+kh8qWnFt!KTC_{{m$3 z$YnD@uQM(;mYq9LY(r$TW%SERo1Rm=e$SQ(f4<2_GMX_i`5dtNT@+^K7;X=@Mw;h@ z*Nd*SSA@jKM+z9+t7&LBZw@VOnut?bD%&ZeveZwDY^-0o8xo2ETg|f*J zmul2|pr#n_w$zH^Vi(au<70H0wA*5BIi1G?xzLE_i_W#$p8JhIhGet+vd}9XPAnpP|+tJ3h zti9W!?XTnUw?4LIr8_(m<#L^voWKi&RVgrGRSytVg-*!ssEo8YTcj&(y5&41^CVU$ z1oZBXTTsNY6aruAXaBTx?|fF_x*?#0$+3^#SXC>b) zhPhNkOfv2uL4*Fe_>Yf>fhS27^pTKYlu{=ur&_dA1mnT?YzO%_;g5wfSPy<$4FB~Z z?0%_l_o@>);T|z^K0lBw#7P1AiU@)~Gls9kFX_H$!5eks(-nXRf5SbMmx+`K+wBSE zAYh`z&zY8V&D)g{LUv>Ch=WD+7tU57j|p-wSIVfOKq{4!&f$Dlj!nA~Tj&qn zZ8bZ2XkwEe4M{&GA$A)t`Rt*4M=vJ-FhJ&>82avJdT`4c4PAqX&-qCo(FU2I3gk0<7?f z?t#z(8N0#f466i~DJ4@}^n51Vx0@l#omeRlpLI(!2~}LoR;FG8h?ERwpQ_vz}q za{_={N|{An(QF5!*TQGR(f&}*>O}ohzX1lPO=udbW!w>@!#H!KU(@IOKuxk zH_>VLh;2f`xyoU9Gn%{i>=L6tipeOSmHr~5OwUcw=BsELx|{X|aTp%|9!qP>WRRZ7 z0G{i=z*mVC}F6e(0NaidH`f|f&(KTR>-RE zc}{cR71Gq^v4g;z@-@bvs#X0!LvWYs^)04ktq+qublBq1co}!$Lq$M0Z%@_RFXj^m$Ow5lYA$z#^6DPPZ)jI4R`oH zlTjDc2@&k%Fg4zB=AeFXjoB`pP01qUCTcr?Wdf0DuLX%DR`2n;_mwC%(<$qZhb(?u zZNf&uuzVFH?mkewc01VI=CSklY#kXWzo0)!&_=9j8hYTsl`HP71Z`IFS<`(xYcVzF zpctlsDC~Yi0@q<#P-{ldRWr;QSJZ7XIy4tXOV1UCHIYxf@Q8N98dj@s;^o}UwLcDI zk5-T)+UoF@I>p2m$&-F-EtsO4I8d{9pZS`W9#N)tRTkV&SV4yTgCy3N(M#eHcoJid zhqP&ZyXdJgHKO`FcZIP1iSIH5L9hV7i-ADXOAHLtD{I;u)@w_&S{5^Z1V7vL42d0u z82a&z!=oWAahOeJABF6ac(#h!$8x2p$Yn#YCv#`h2_5XM$PWXt(K$y|q~|00<`GvB zUZ&u&WG$zwK5Q)5<9xM4q*x-(1iNjfZHNUx4ly-GTry_}H{1%dXILgOv1*>lINlHu z-C@Q`jlMX=ZtOKgn7w=ckj1H-9C1%k*9jjhY;T#Qq_`f@2=J1;~>CbK<-B+=!`BcXvT*N*_*nTW3&jpnp9u>t0ax#3N0Oy)>E%y9XG79*} zR?k1z1J7p1i8H%ESyz6=TMKYvG%-ynnM|4xd=L({dxB++=n!`w(M09ss!|%%IihH} zP!0n|zk)`&n$fCQc9oPctpfNAH3C$Jz%XIxWYRm?xAu#KEFElqYMl_C{tkmuycgeX zCHh1Z4@ZfKVJfij8P5>ZobhE5aDPgUAdn^CIK8SuU0Xjpu8(KTLD8@CPR@%_zDMDW z{(cvfR}QOZ$}%sjo-qcQ>F^Is?1q*01?NnN=3c4~hNdhE51w4je;5gUDShS^+p z|AFZDBR9oS{$xZhpdf5gK4|t3)oTS~^@1wWH+Z152#cpz*fk@VUW2-nQT23^iltnm zM56|ZNi;_zw{M(XIf-iv8Es9J1bQ+wGW`g4_#`^b zEgtz0r2@MEzeKGe`V^P$BSaDaDXC7eOx%|d6S-?LD)z;`MDIc*x%bk}A11h+6$y%* zKz_g<6h_Oz@jg`rv-2L9+Uo!!rB5U=P_HX>Z5R3c6}&7tehB^${pe93i)|=#-lL_l zplZfm8@qrlhO1U$Z-Kw)a!b@vyQ-W1{yBRnT_x#N2_mdYJy}QzPTTJ#ES!$ z2pYsoE6?RBxKZEcI(PzL;0^(fCxPy>UXQX8->I~DJ!1nXu-}mNUOn(lYj1EChk^T9 z_f;fVpzI;GcijCan@(C1?cWZ@lc6HN6~ZXCKj_8I+7o?(5$8_~vh^t19+d0U#h9;9 zC^zG_aG-08t$FwS&A1~#svXoP*;jP;&=9FJD;X4K4GBd{iUHT4w`zdvMi8DIxk*ou zMaHNcF-gV?P;E%U)O#f#STw$5t&ZilP$Dl3YM2_Gpi>)VVs|BXP2h%nfCTM<<%gtQ z5!+3a$xrK*;{X(5C=TRew|Zm(<&Tfnm=D1*Pe5ebS0eQE^bFrU zlu!C}@*yQ8o|xc784_@8Dvmc>hzfzR&TUpOIV=SB%ktoJ28fh6sF1wQXIFi4^youPhT;%d*zkl93)6#( zM~wz)(KjJGl+Ic)A0jv$>wic~NaTt;TmfIdjVQr0bGo`P819C=NjmvRe&JI`s5@NZ zU7N=qtcm`}B{CO0J~f-lBy%ehBY+r#D<(&jX>&?$?2Wl3xZX?b-F6~MCinS3Rf%&D z8H{?I)sfgXiQz_N3Q}?B9w~%RPEI;_bO~cENDxb0IQuEVx@&KM_TD>5eM^F#4OmI> z2ZTmfv9}hd{(>EFQ|h2xZmPW;6ekK}Pw->x48BXvia(GnG`-Wa85Hp7Kh}d@E@?3y zJ?iCeNyvmHBRbvPq(oO(pS6%cPY9{H0~(H}{NiDQ_>0OT6E`L@50Y!`2eLQ>%GQE` zuL5L|*(i560X5b%tGwCI;Vm`@;mST5Iu%d&FeXqT^{CL0nBSpOl2bGWZTBqq;-m&> zMDr0RDVn`lcS_<08G@etD1J!2cMJoXUBW%@9wgb;{IRF44SN7L>_K#=zj)N1_P-ijSx<@!ff1R)U0MQk26jY!HMHX`s^dz4F{L^-i-Na8_ zpk+zj)AZn?1}|^`Z&L^dk~61~hPHs$y?r!Z44l1)Cej*m<3OxQH7}FsB=-rx(_;sh z@d7`G>n7e@R_3rL`r+sGFaaN~65x2(8ofM5rDNu}`IJpEWn7HLE4tHz4dPsn6JAkF zX>3*A8+^g@9Qg0HyO=DVx1G=vFUg!8YjZ4ThAw32zVu2e9;}UQUNov)DJ{LKmSO0Jse}z!P)*lAIo@eM z)^3t*(V^aQ*Cm?T{Mmxt{6zQ2TTl{5dNbJ=X@{&{`T%mk4{{s(HB<(#=R1_OaoCZY z4ouL1a0v*Thl&=>F<>Q1Y=cC_x+1r{0Oc9?O+1CVB2ob42HhnX%_m)TvNYFy%+tVCDuoP6=3St;XSxAGY zCesS%i`(edhDX{ZXCHwY)f*Cc5@?erXFoh*^GIFNO^yx2W0IB0v(#;Mf(1 zEFe=HS8iKz>jFG#Y_k6w zoOr&)x%lL^^rO8ro%7PO<2}>QJ-6^$$)VGseJVzU;HfY}P*f0Z%=98mi<((9=U&}) zYW5n`^k7EI2uZ+jb86&T4Kt6%rUP_p6rU=X{6A5XpMA_EzmMDR$YXC_qq;DI>JS4& zTkuhfXu0FApWet61&d~9tE6a#ci+wrTtMbp-ES>HAUe@jt-gYv%9+Y`yWUv$U(=xDkdihD_$$X;GW4uND2vd%r*HZLI)fp9j^CO7#$;3K#fQRKfcT5`-iS-S*E z<=Dr-T@wAu!v0S1rl~wo@SEPa9WGK6%&y{;=yMU|8Q(W;Zyt!Yf4?W6K%DmWC}HMI zH|8Na<>m_bUJCsYlC2bmQVtZNuLiok>FS7BPKdOg7UoAoRqn& zel9e9`x&Tbc4Qv=C$r@1qu>!o-ZRo=B`yb2z|%)_Wx?jK2BDy~Q0SCi&Gkw+b5Q9a zxmt~nJ$#)oDF zSIEaw-lzB6pk_$=Fh~-X&L{)D(<@H)ZtP{6mN-juF4@$qM{83+Ln?Lb2uWn&yzwyX zycVelFKbD1)h)WodXo5bkSEViAwMi|zwGXQG8Ff~^<&Cx)&Az}`LCP?{2N{Z7a(Kd z_F@k`g(^s*y*g2iXhEH~^N(%Gp`MMj$<&CIEc9-S9_Pra&ranqC}>rsKt%M*!$`2q z_t6JRDoBGgHnQBd&pfwVTq9-VWh{huR_B zXPi5OFX+CFNh-b*Y%%q8v7Zwmj2vL4Q%T4i9mwgK(GZW=CEnrC9!k=eGhS6fOsIB& zRfDu6Id5$Cg*d#&rer=@=c7fhqGgsXt`@+KOq;IMx#0$xM4>lz$*>i88u>LJ@PHor zzU!35ZlhqjV(Da|*GXuroYvf8P_5E3%bzcm1;P}9`7)wAmy}1hwcSf-on^k* znyd>i@Yh&T)~|%o1r6(G`5Z%6T^3$!;<87oTtx3t4o$zzig<17wl$J{sx9r{rK|qI zqRMCrkLUaKJWFGPvR(V9kKD`ZSPtpriRgq5T6kyl_!rqP52=(4MduADBiyR*6a?2% zk53~tlIQhuX8TRg5}kCW+Zj+{@u;?wb1W>PqosHl3BJu-AuQ6#Z6N( za}G^~|8{?gK#W@<1p?i!VFChqVG4MY-q#_w+_AB)Ts*6Ub6EV7Bfhx&bN~%A=-_-i z)CQ(~rBJ1c}d_R}o+(G8_QW0+~#9F+LD`1PP;}X0C z8l&^H71(Ar#Y^*=T{Z4E<~g0=qRP+im|HCMq_N-B@AsE(u*%t4eJWd=F<^10Od3t5 zgm18Du(vGhUY%P*QV|-&l#`FBM{JMY#QNo)0$;>U+YU_J&_=&-nMu^<*IsxVT9Z?< zWS(L2?jem7J!Y@7_Heq|`@8$^rTa9?p~6NX{>maTF!>>h*L);TVeEO=*dF6C;j^>H z_*KwPjgI@~_7(doC~s=@jPf=Yv;ogeADxzI+y5y$6}<;G7JhVgR3G)SA~6NMXUED@ zu+dx}+zLUlvvY5!UzoXeM;#*i4by)KvF!mV7BSkJC9_$n;fhdHX*(QgJ}_M`DyS&B z^ofr`78B-pBmSa0fp|V)60OX-wbWvh2q-@spD=ayYS?ezu1gD8(}uv1y~@e#N=_w>>L?ampcaz{v}G>DAw zf3iL1v+8B;{ld#Mr?jNInM~(MAxnGd(Zh$*`IQbdz7Wrykoly^o$aYba_qZXgL$&- zcUx|0e@Ot+N8YQL${HomjgL6WnW_~~f1 z;F-1z%=4nxx>g-lOZ*M7geS?&gDg?S;e2Xm3BAiJAPKGk=$R!r=~ zGb6vmqor)>1TIEC0(OVWD^p3Rq?s}9lzSQT4CU+h6PfTCC%Iwr-3r(MxPxR|B9TiW zG4bT1#6~Kab})@wK9lK(@r!wbn0J-inJr#tQsj2>ou|@kqMXCJZ8yCN+Iw>*B%<0f^O>Z6DRhUX(XH6n{1ME0>Rep#3GIEG35oy%=WeSsn~? zV7LAYF6-ni)`AVI?t*7JG@l@7u-KL1rdQK|ZwDgYL73OQccJKXu@Avoo@w~!0pU>WFuf6sf-s`4@;4j5cuP*mmVl-US|p81RB)0s|==muD{J z00?>#*9r}g!Z~rGSCkg*5k`thYG|_AcxUz=BknS7gpjB>uFPE%huF-S7^`+F)}%%v zbJcdbPlJ^LdBUz|`>4_mNTsPAhe?;-ke z`kNk&mu|X2c;K@!o#OOBt1xQuOf;XAygP#qU-`YP#s(}%PjovL z>Cf;t%|l7KG**ct6v@IVQom3jA*Qcu1OLbLwVU#~V5rXzlSBlO|gmrIm z6nfMwh~?(3xcxxHvd}2NJO2}<_fRp&)t+A;sj@IXzMX}s`@CXTq!gT(GbO)zHe&Kn>DK5=d&rZ*>$#LRXNk19dFn{=w2&rq6T;s_BNTyeXXD0S$ zPo)WnPUe9P&wcUM8qfu&=!$`>=UP|sV0l)SC>-|ux~mdT1*MvB0_W=?K^D!Q1x<9j zaAqZ1EU&>x-X7my#LnRq;=D8D$DawiV<)rjOlEzqK|=qysd+uG-+D?<<{(*pb;|BX znarBk3S_Mp()MI( zUWH|fhpzB~lp-bF{qSobpw4(8k=fA(I;e1o&Ue`{$K@{1;Q_ku5i*_c$oN)eTo zTGnp=Bo!(D@9Dv4l^DK+D8?#q?{j*aS+PoB@RY^J@9u=9dHTiv&teWl{E$mUO2-X* zF`cgR)@^&O6qxDYba`ddIwItx$>+OMNHNY%dF(c# zMnWP9g$c^-pwFNm4wPS31+cx{m9E0t!AHrS3& zzh_vl2OM(;#$_Qo;fp|3t%q6g5T(IQ&ic(%|_scmh;34yPM)Ui!HU zntlE#EWW{MNMw=v_%74oX>VMDQxU4aZ0^Vz%m2GU?5^Bv96HVmg*Y8?4pb1U0 z`1v)g*Lki4HbaBrf0@}aWMMf#TLEggHxu&hh2QJa93^%^i8sZV8fS^Yc%UmlRSl&U z$kD;n+Uz72kcKkdfQjRmbYj7jIhY%1iIYxYGxE|pjHCVWmoVz%C|(NWG=KN|xmH0X z__i(jZM~Qzi9Mvj(AF0$Vrj)fTE(%O`#35XVF-iC(X6=@B#>c#dB;_gV2eb1JHN4- zYGJ!VPGA5a*5OKx66>n?D!TnwZlg&orCrN=(2Dg(R6UIys0%UBTBC}}Mb;zfFnNoj zH+{cT=u2Y+ya6u*fifC-A8&DmamF1XC23K>OCPbAvby=$94rbS>D0y6PQl`jdyw){ z7|13}-MU-e5&^z+OU%e3Zrpu+zE?O@Fv32OGo%<}epFQeH0O+9O%SBo4OE!Oq*CTV zFY6*mNUXTgB|v>BJk%wTh5KqJdJmt5y~x#jaPx(<^17;2sl%@1xQaYyhw~K^PbfrQ zC&wCJwtnpGY|?}Ez?O&joJy2J|HG$k7Fq`*VI8PuRsFw6H$tn@3Wb5g>a)nM4>xiqb=aHvQWL$2Cy_x z66+cVsk`1`Bzb9AUuNuXT6D9%pBA-`tY}TstM%K<`jC8lez?}U(51*4YJ)I>=$R;4 zWUKj{fhuWB&8_w$$b%+C&YYrtLXyX7aruT2>_IT457<@uNsUTwH`;U;HctL1=a@av zXk?9SE-iJRa3)aN15X>gD}kp)fVpsv71aeYJ#rrR*7tZ>4=|4j* zD2IUB!+d3K$Q(}W{j%=uZ;Xq-BT(1>U$2#gHL-3v4Y4qF-aHK{pxRo=M=VBYfCNY5 zSX?vW4fVWGX+d^%5$tAA&?04#hXIP~`gvA5{Jquj+@nTCw*=`dyVFhj(~VaghrZJ1 zz$sqVUk_emEz*(QD&O=y>&oYBxgi!^D&Np~c@xymOj^uRVakEOK%3$}L2i%}0!L3e zRg#eR;NY@PY+iqGfDCj!)+w+RkALcD%{S2(fNWe2Q1IXcL^T)b9862lQG#f?kVB z^&&c{q7VK@Cl$xFS!F2LnU$LNAOiagsUxRALM|D|8D_wo!jn%HD?8#+)V({?ABF%F z6}FF!Z~|xXhD$G{ z`zq_8Qa5HZ{$Z~X5`p`&3O++EhPMWsW6$H`gjTEbpCcjJQjg2pt>AocXzpTDACBEM zzC=YZgGD_Vd4YEXV8%BEgXB2*SC<`CupcOpJrH5)$*c}G`#R>@Ff}~JibH?w-sr#y zK?yR#ZtT~GW4n7C1d-bE3$O@)zd3&IN@B3M{q1z9n>u(rxCr!sr(hkcrlHW(u_(Nv zf$aeNepZve*j>CC_Wr{$AQ-7A`OJnG*-H>qQ2;xe_RKeFIvGAX9#Y*+#BX~dM zI0+#Pn=%{LS7?KTV4(pb7SU*C?QeV=!I>Ofr?xtodH*TXslgx!buD-8+_Cl*^5i~ z#OmGMD2(%xie3)+kTEwTGgvsY7d=78`TDMG-Y{Jew%-CZP$@mvEQNY-Faex}HyqhJ zLdFuANI6VxUoo=I#oh2)JGo|g`Sxy$08;c(uvm`(9yNBG)Q738{>U$` zPyQOH2ct<%Ivng)*mMwkiks8E?{UH0ECHX2ZC?zxGVcneoK4=?-zWcw#I#qC0>xhn zoc3Nx+U|(S9XOehvhKDvmK+}qik4$u%aU_@w%=r6CEoNO9IEC=fomk>ghRhi)Cos( zF8>#CKw!y4a~Rru^+pXu8Olv=|J*rWMW+$TvED~E9IDJN*m~~gqaCFnPzh0rLf_@b zcv@{rc|@QuKl$HA1)3m-TDE)QVC2|IKm8hwwfGnhFtuwzwmn6XYucMz&_OJL7_Bq8kH&kgASR$Vvx(luJKP{*3QsVrH zuVFxaLcIr%C3cgNU*K-|eOOet{e=7SjZY5H=`E9`R22g$kSHi+ns4!^IVfn3EzSE< zGMcB|n=bxUX7gKP({Z+6k;lI`9%!Q0lD9J@8ircDM_G^Ap}4)R8R{*wXP&E;2rtf$ z?myekKaM~fkbt3}1f)<{tJwASq+U1_YSR6iC0N2%t1xJpPBFS@=mk=L$S_<804Kp4 z??QB-TvTZR9fLbapq5?cbezg4p8l%)rF}{lEZi3bcA9fQ?$Eve0oSMRXNqyhZuE)*MUaWx z*h?GVi;W+ujJ=|YA6)&VWLOn%wO&{R$Xh~sUfP$l(Y{FZ$75D6(+;SB0egWj9PK9r z4jUiW)J7Z(0q6wgJc%*pD4*Wp>bZ6y6gt56e>rksFvx5%V&C+AR{d5;!F5mmm?M+_ z=02CXwVFAsv9+L)qjSocFSuthoY8C2Srl?1pR~hS3hZw@E@|J9JMa44RjcRgMlV+$ zitdmWPn}HO9g*$v>K0qS#+eRv0fwoH@11-;ewtuw@DvDf?SrC?Q^M25rj?Uiv2%_t z;UQ~|D^pO^Ikz_CWn)vb4rHs>ls;}Uw3p?#+3gGwXI(9o;rmFGv~a`C4~NNbMdRB( zXRf&|LS;P$yrSPGVoRo|d^9fi-0-_s@{)=jc#xXPdDALi3gw9(I#sIY`Ng(atl2R&1Dfq8L)>a~q{w=-4)UXH zy`wZtzhjPy)*Oj((OYWw8&r#SpS!-?{y`f0AhRQSGgh;vI$Gt7Py9oJ;Eb6$T|v+L zLUHXI%}Vh)rYd7IG{^6}!EYWiy>GjtAvM%PU5!aEOsg{LogU}7!yZC!&hEMV(?obu zU&A%@^X5%Uq!;pa@-s2#Z+AA+Z}g`MEnM(;!0PBi7+exnTz?HzIo1$NwQpw>;8?SQ z2JvISk5s3-UTrU>xSlm4SSYZ@*7pWVH9}t3()7w|*CXEU`|&Cf2`!%-Cmx3hhX|(Y z{fxtDrW>g%O%Y{R%QmL$W5DIeEvuYd+|R%Ejejk!k3hyQVqf}O*ZFC4LO~wa z=9BaQ=S)D*0p5w46Gg`Fkbq|riYOi$tX%O*;{Vn;C1$Y_btu_6LcXhQqR8LbuDeil zEj@aTpV5V03pyz$zZ95u+DOlJN#}cbXzi@wa0({x^v8Q(i-5*(wYn+W9>cxqK4onx z9`8OE_--n{s|Gly?FKa`wYW9IVQbdBF)iRZ$RbDGDjIHJQp)sg4y^<5D1lWlQ#3tul z{&-(q;w#7Ur01`<{Y`-Psw33XPoz!`1;}0d;$WOk#OI~gH6cq!P$8d5T{=Shah*oB zvEO`zqWa>b%oLPDcR9!~bYSM^2Yo6Ix6$Xl@BHSr z7Vr26$Row!nzuS~vcJd_DZlQP0}S|NDaGNfut$lueip&YbeDB!zF64X8Aykq7w@H; z0j@<6X_L{#0(Yw7wS1PBbfM|g&Y)QLZh|)I+5v+qlAe%cCt*94a2h+8#_c)c z;(1^#y;uli3Bh;9>Dv^NB$#MmjC-E#Q!M zIIVv3OzHmfpOW{Jx~|m&ncX+z8Xd$*#qgq;BvQWsHJplHh1W)#SJc+h)@FQYI?uGS zLPGiSgL09Z7vIE+(oH;#yh^Lc8U9!6>R$Jc()BW*s>K7}Je+ls6Nq{1nRe%@)8);_ zjIM)x>>Ir=%z+POM#XRuXRCjh_sC@7t+A$D@v!c#BdnhjCN8cFz{LixTn)eY1

zHU@i2qzKX^_Dj%bJg>XWMNqq`)}NsifC^4hxYxj7%d zB(q1a_av`jMcp$Q;1X2GzmX`6Il08dQ_q|2`?YPOLOG+mRaV@*rn%a zE;%hhF-4ITcPJJkr4bK%dThL_I9neXdYR_C*;TH zLT&XHc?{oAKFx6Hb^RO*Jti*s!SwD5xmhFYz@yXzeJfmaH@gcwI>fzJ1A%x=Fj{c( zF>gZYJIkps9|cWx5I4ZbgPa4jadB#LkS<+1a%8pLBo8u5A|Ul6}nVUE!eOz{5ULtbU8<7qOpBaruKt{Zmvaoe2w=J)$@u`AjV+U*Ba@pl}d z&P)-QfO_VTqGs{NS79eF6?(0I_UbkqdrYmoW~^b&C@O5E0r(AM$6TI+sePy@o8ACz z>KK}~o|qyu02N)Z%=qisY-<&9Czx^E9u=np&)8kSi(3k&qGqj&5 zn`Xb?d2 zZnPg2F490<1fFtvACIyBdliM#d%^vk9T$FU3PFfi_P6(Xs!1+MuHN}{t}24hKkA$Y~;6~0)gZ$$wIvEL1w`?-FSvn z?*?uceP7mGGRw(~3`mWdSx=46KY5Cjkno(m#036%n`I0^7!r~?>BfxAw2n}`2bH6g zHYl-v4DI+xFT@V$g#cTu`F{|6M%wZhfDjf@>PJj>wfka@rWN4m}r>r8#GwyqCmlQw@*3kdK$ z%{#Ii0xb?#KLyBz^1Tt7wnFT4#toixi1ry1>jlOms_Qt57*sT!kNh{eLWr`_sWg~X zu8RH^aU@13O;=|sd+xVhrir9K6`L49YOY@TnR0W4MiLTlTG>T|smL@YXr(Wsk;FAr zZf)0|R#6dyXd+p~%KS(klJcx{&ab%{z&E1ny77zmU{nkF*K?Vxk&+COeiLBR4rq!|UJ z%lWx)M`F?q3(UFefO)tUkU(?s40BJWK zM;?eO6Q$r$ca#^Kuu4=Wk7rF{&=(4Yo-_mLv+?ct1n5-lZ0!u1>oMNAqBmB3pLHc* zrr&OjR`lhM`l0J{_Lq-v6jy#W{(WWRhTc}S727){AI_DN&@V6?b^V!WvCFTc$PFGS zo$>MP#Lzc;I=2Dk_Bx?=ltSL@zPa|!aSt-P(`DSKLSJ_;Duya?0anJ=9EsOc*d1+myU9$ZeKpdeA zAOw|M=kZ6P#4S!Nmm0T-++fF0pgY_cqe9LF!hto}`+;XllWFXQ^Hh zBk&nlv7U%grgC=faw_ob2*=NfpV)7JJ+OArg(h&)_0-Lo9QvSLfpT;6m&jzha_)7v zHMi*>>~y!78eeF&Wt~kHY+6WyY80=5w9{uMqQ?kRh75$T71MEQ0+zT-NqK#MBmiv9 zA6aMVm-(i@?WpfEXr%<{m0HhnsWx=BK70Ga8H$SgELXMY8mMTA^*0=9yDXaA1C(HxgwCiDFdfGu$xNkUFN88owS`K{5zHf*ZB1x+s3{N=x; zK7XaRv5&?ncO^Y0-j?J4cle7rj*9U}3T=utb=xQy_{Z|KL78QRJ1$sUJ zna8FDL~Exjj*))Kh3mf?3Xhhv z|A7(yPw(fJ+-$!R9F=puKH7A1E<&H_=5QTQ@y2WzZ+2&0QGOX;Y+E=rKmX%Konymy z+WuhRc#h-M9OP$eG8?~|P0oTO?eN%0In0?|8F*;Q{*+4=AVDKR;FhfW8lRxe?CS_X zH}11NH?ynH;%1W#^W<}pquP(gY%@WYGlYTk(=CG)-e^{eC$AlrYB=(}v~(1qs=n{J zuPqPuYd4nF;o&*dXX3N~0mvtljc{s4l3XbQT8My$_;40w?EOO>q=n#`qSbW5!DI4B z3Li}+ig?{RwxsZkAKnq|%9nbCd^yG8@Af@!CX5GE05qB2)66)~?GYB(k6r~q=%f(w zYIzh%#n~VL-%BbSd$SWDghqci?lEvb|HcF(tO|MgXk~Pszg_f}4|4n`G=mhR;ymwa zgpgd3djEp9NdnVyd}kw)j_0>*j<`>9OrD;9yIQa8y>c(i8*hMRYOWob-){8ouueys zqDpqKO@y-ix>#vQ#W#S!RIs)2*0_MPKM4S?us2M1qtymL(M0PhaPe9*T=j9DrjI|R(uW4kdJK|_cxlq&R34CA=`@x7kM+c+r2k$|9Gh1Pn$W+b z9|sv)C%@djD3EbI-jWJger0$CVC;N4m@yA6y14U4yVv*+LXvIhG)aHGh0;X{b?+Fn4;5pm(6~W| zX;pbI;rj}(?vKX)sonYmBj!DBMt|Tv)|cl!)b1#bO7=KCj4^X@)EGoGGZn;=aw^!G z3o05MR}2*5OYba2Gn%@KcIDq1tPY*Qd`zmNozWVI^HuKig?+aVsAin#`uH!xZ7={e z74)f)%|1t55lat5b0KI2k+@u8w{8JEF%JYZ4q zr(kc>o-sf8d|%Wkjo0}vQVz&iQqDnT3yQ}`7wOlBmZ&B5eR9^lkv4?h$~iB3k!2FR zGEm6pKF|pFRed2yO659gQE6X$WY)wWmEV*2rP06e4q5 zj8P!%>v?Wj)J0w1ORQiCK`LJu;v_cnk+M1C-c2W1YUg{2E@)5b9sH>T0oXx_Rc|xn zi0$`1m!v>fV97X%o)J#|Cl)J(;D;ogxiN9X&VH9jf#;v$-WXHStAgh^XuSGs44X`> z`EQUW{8wZNENZSAl+leh7kd4@oiS~lq|6{pfG+@E7<}p?`5*x<95Uk8ziZAZ@vyEN z567N!qRV>QA+Cu=Pu{BjqE@7XJVkvlxCJ=#}i(=%;ujdJ>^uVC321PV5u!CyKq0%!rhfd>Qq$rQ^#Q8L;EP zX5R*h1{z=vf>r?pOW230;zE@;#TU&uwf6G{x$$f_Chy`gvROC}06~VcWq%G8l&D~9pZg8Q;nSvs!U5UHP?$w$6iTqjr3;Bawh>8a`3T0o4 zBz_`?(c`jaM)do+L~u>#gBM*gUGy^Gj2&eZHWEQ@CqhDC$e(|!*e~bVeaN(|TU}i} z@`FEh48*h1NVM7QSbr@a$-iyd)<#Q4Z4h>lWy>)hx@ZQMR$4=m^SZEUnGOGe1GVt) z+VAOx#d}ZojUp*6#v3VxNa7tj<^$yNcwXHDj4ojBGAy>*iE9{3^x4ntp1pIpzdltb zO>9;OF>lDNL` z{=lHkzhiw$K0ZgVP`6e4Tq6K&Y5dhWCkxP)-(q_A5z&^3YU)H^l&IbjBw+%ls~^Zs z>mH_1QQ*|4M+)7&UpZFZ^;GhCnIicE=<{Ka>(_X4E#yS{Kc4+|Dow4!?x=26yt!+0 z4B*SaPze@QVNp{>%ZZACf-_Le=YPlgd_0U`eFC$wZs$-fvtzl95a%QSq!F#T?n1F; zdiNek5aSP0T0lDeL83y&Bq%JOz>1Z)qNB2H9l?YyAUC>Q!xHhEf5Hha{ed`l8U@68 z-trkZmntkUvY!@4P2PIrF9HCAURU<~+^*RJFKzf~Dd{}819|r#du}gXikMd+9PX@t z9qu1!8rUHFM4KY^ii?795hy2Qzc0@e%YaT!WhIZ0qJn2j_$TZ7PwXf~T0#oUWCXD* zQje-( z0)qnvK(7K~ub|ZlPe$M+e>)`3^Zi<5y>oKf2#di6i36aiiR@IKt*KGm#J6 zU9TrnpNuL*E`d&v$0!a{>uyR!G8Lh52=Y585JGw~3E3R>zPqdP`g2co8Wpqx;$A=k z^mgNc!Cm|^ww;#F^U=&(XwfNQk;`CLhvf1&`6GPPkzen35>BH>S;KL{!Fe)n&4IDi ztCXii<=jLf5LiF@F@Q}>L30n38&zV|9Z2lEc)h&-raAn3oy zd#aoGll$w#1jU5VG)^lT`Lw~}nif5dr$1clV#P;Feo2>81IJW-&B^*-QS+sa9M^}B za}snhjrFc+aa{p;45n@t8?9-v+fUB-=+Tkv#PXR$hZBa?aU`S|Y(J*a=~7wYJJS^t zueCO4J|3V5;Ke665=KW#<`wpX8xP-pWHyyAw(da7djPlL%NV4Vfv2G1#Czipz?Zpb z^{5Fz?4)noU6}RQXzB@&hG5tOEl14L+_A9(D+>n;)c1PboVZ9m7i9FLZBJt%dx&5t z@@l_}jBhy3F=DXfI8JsF za$YX8<;M!FyrO!XZd&X?NovTiH*f(Nl#PX+DX+uuCh+<%X{On1CKV@SOQH^6h9`?2 z(4yNHVDdzHfIqV6G&1;#eLE8;PD$9^e|cPj6w`*AS#h#@BHXwCNa=^>wECIrZi|mj z_9sp=CTRyCuN~g4(B^Bg-xw$}>1I~WW*!h@$@F$~FL}1O80`HsIEU*5Vf09eh0)EO zXVA|}(Vzo57nZAy!79d~vco$O37FND zTL6ZqwWg*9Pdo7$&rOO7#v7p2uyB&OJ~tB?hZ+lM)muaAl8~KhPD$wqI zY7Q0{Yz9|fC{wc180cD)^vTlI?iF#FJIZB#ctk*C(Z~Xb1YSOSxGu9|G?6{%n+E<9I(8+_ zB4LGr&OtL)47P}Vrd_X~Z1J2o{v8ZpXz^&*S9GauxOmSYD|?y((YGDdac7Qm@o zte83Qb9g~AZ&cA$A|vzBI6rL1ALue<*n5ui5jEl~y~w&?K|zNu1G2!^D7hTaJ#_|s zxt~;_83xPG-ItXaC?ZWxirKlFX>(tDOSjs6WS`tz3XwzPS%p4S*!hAMmR$XO#fVE- z=OaaLyef>8&nYLwAn}2lLmU?ECY`3%9r(1@(7 zCNqkOt~*enVkO5kK0ha6=X1g4%wGy{1{C16v&t(5)TpJs~=rKSF<{2~iBfQ=&$T?Tw+~Y3O!c7n4A*PRHNkzNOng?de{G| zN?{8iAymR<*==n>F{Hrw+ro%~-wLr7*YY4s)KZ^A-q74 zaD3&qG87Th4(QaQTV404W!tMbWZer_=HUjVG`q5u;c>`WrvZM;f4o^kF8vu?S2Pag z%V%azREi0#L@no6yR&VV$kk0?Tyw*Zj^oie?KsD&OmJJyvFj-^zpcHcPkjryAjw=s zd`T;_D8ED6%X4#OWE{w?mg|4kCk4wIAS_3UiDb2M<|3? zHfyMSGs-tt%}2F=tju>>XX=!1Z5F%iqIdi*z>C=I09wwFXWsSpZZe@Xq!?Fnrp>{| zWRq*mh$56$YTJlnwj|eIbF`)Y!bGo$FU85t_pDr5)~c?ugyjB;#`s+H!&(y6osB!3(t_;Tn1^(0!P4+v5 zoQ%dLZtDUeM78gC{6O4zt=(?dYj*v097`NpE5 z6Es6xL3=pcRr?5ZlO9G_I!2f65$ct}@0bd_f7TZ&PT5~2YT(i5ZljJfeecKN{#aXf zf4DJqwEA5qDe{^ZJm_8EJ^Z z5~yhHSR{}0lVav6m)E6E!>}99fsu-fNtfCOHuqk?xxei19@*b39hApl{3XB;gI+XBpbGu*Yywi`^A^~YMaRp17D1x3JOX%DH%2;`-( zi?!NS$MUl zOzbg-)AB%FyjVS@4&uY2b`JT-KZIn~^0VH?$`8+W^b0z{KyPIQG0P_s6xf~aukLA9 zf>dsVgTt!LeS+Yy*J}?U%sSl%ektNW7>yR2t=b<#0-=L!b9%dt0@&!UGoMvMV)2NL zH+x=Pgo?djR>la|DgGmTwuq_r|HZ!-P+d?nGM2^aN zTUVH0L&^#Jzo3)Q<|cLQOyG^jMAwBi1rF-Rq$~0IqRJDV7QoL ze%7hKDo~a#1v%2wVX+LdI#Sfo&$nI6SUih7&64t>P}6kqB>5f~n#`L>IQYod1>x1| z@am!z<$*9EP2%iDNv%I3M_h#h7F<>ub22V`0v>h>CMNohY9l2acGK*0h%qKCf_GtM ze_ah35F8-;;X^mw^ws&0gFS>7o?#C7{;jw7c$I=2Y3!1JivO+j%{h#xy8f)2wQ z--MZ7S1pp+P#1Q44lzS=Vk+vwFuc`0PW_kMr{N^y6~L8hLX2=R@d@&4vr{mgXk6}x z?a`=G7S10STU-!-hX}q+Ls19Wm4B-z2|*54CYIt0g#xm$gS(&Lw(ZLHXCf28N?^0t z4)WuW>0DN(S4958xBK>FT2)4BAn{2|x^QY-6rGKuL?2T}=S+f3T1B_QAk@a1SBdyA zbxrux-F7N^x&RYctA9M}qR^Si)M(Pvs@m*y* zcK9F0MHC(~sIU9LXUfUc*P}K#SV!^su*ZwqVKkahatHBnI8zmZcKBjG3lkcz_X|*{AsDGN|7t zjQM`wNQzHmTes9ew}hRhio=OhJ4nHb2J1AiWC#D#!%|>P;-jLXEK-gWpRm0soDIm6 zO!8&Q6MKdpo7P|bEBYV~#}fAVi$*g2J&3DwA5jE6D;&CcS~+`(GJxAaeri~<9nNKE z{N;O8S0AJ{da*)|{nj3vrET>?)LcJTHEjDwR(Ri0t9)>J5ZRug1KFl0jc@d%>d0Z-RB)9HYGF6d$J7#-;H#Gn^qsjN=2_BnLL_c58^^7}Y z2>0IUc7F-m&r)}k!>~Q1kGl&UbKAck z+};aJr$Cj-4?SKae3 z@uLw5OsNE~p zaxfe7A2CO5t^5={k;g+a!B1{uH0R*)jJNI zK(!OPEE64rfZRM|iVZ`1bNm z!LvKNI&P8^E^+Kg`@wjD`u4aBN$cr^RlB&=(6_6<#$DE1yb8eaa21dAU~HIN^I;G+ zICcU?0)aq=nYHIXdDaaC${jopPjT1H*-nx~i0|ap;wN!+yJufUe*t zQ=l4K8O~h2T)qkakHZu7z8ul}snW08dhZ3x5WAO-zP-fNaXwN{h6J{6N6F_h=tmH* zJ^?gQ2m!JVgt&Hj&=X>wf+|<>6i~%qY~6Z&1^jBcMiw^IFg4MDW=NHWY)2|0GGHRd zI+n((p`|Z#{JqA4XePitC4Ow?L2t}BG+!WwAQgJ)j(I^F+q>akx*0|%GB2^|Q3pR2 zHtyU*fKAXY~amrWsZ!2`)E^u$CzuLD-Dk@QXYx7}hXkn#-+ zbITzL+CWW!iykgO)pArh>#rOTxzTAD`s>C(yv)pNGP&P(JjUPGC&YKykEe1>bpmdv zyfX85o!`dV(y%jiX_J~mh*@LdT!Bwm; i`?BrYGi6q6k(w{wY0i3DFG2$UsVbgR$T($o_x}MEw4A>H literal 0 HcmV?d00001 diff --git a/docs/diagrams/sequenceDiagram_SplitExpense.jpg b/docs/diagrams/sequenceDiagram_SplitExpense.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b371a2647b1dfc8084f94f97caca77c87316b5b1 GIT binary patch literal 47204 zcmeFZ2UL?yw=fz6QBY7oPh>m)Y2P zKluIo2OzY2fdAb(05Agn!#)2jo6H{WZAZA_8{y04MIcV->lFZSEd&6l`|wxZ zUp#qW<7M-2&5;nU7aSY_fZYNBfWj02p!o;@kemNo8R7DWzOfOCm{sFgtK=5s>?*< zB$dQO9DoZ{M8s4?XB_|*!dxQ)5ECxHC*!}tB~p@$mx(Ws5s?$hb*}>eq(m2pNXai> zBqq54xNrqPbb*-UBIzY6>dQ1YXzAE*-r^9st9Q>YWlU1aA-T40WRw$PVw)E5oj7ct0loXJ2HTLu%=EA0Ob z0Z(C#JdcgVJZ68%A9@2=_-0b%(|k%kPkkM_c4J$EWkAO0o15R4D0pnLuY6Fti~r8& z_hG}?N!%JmhF+<_V9$F0-A+SX3Y(R-Zp@!@gOVk6)K8>fKNx)I zKL~gJJZCrkxPIatT+X0TAW&@0&=) zMNV9s!Fq)e^)uo27mUs|LWL?Eek?Hj%ka?Tg}hj&h+y@|X?^~8S}`YP{`AW3#uh)c z;-f?V&Tl&&^$c};FZTh-_D{?n%l&wQ4(5yl6#q40E*qDwZ4(z+U}`=^>s16j0hQTZ z>Ic?RZdaoFC5{~zdo+sNmWsHlV0fe+-3eG_O~jYFG=4*;AnWU%P>1Kc^HU={$`2Ut zkO?}JXx>*b1i;?>fv2>3!|>!~p3cO#e|tOg;F=SN1tT z^7%<|z6sE)zcKW0qf-2o%;emoD0RvryQ{U6gBUH3If?;5i=>tk2FdL+0L!WLGb8G9 z=$uh3mg^78}xaB3yYFcMA13l!#sCR}+CH7OuiN)^2Gk{A5bnl1X(;cIgJZJRS z{FT(~u5vF`8Z}YIOy3MMLuj_^!ps^-`Bude?P5VSNyFea0!W9`k?xWW`qh?BGPt!h zG1@DqKbdI}3b8+}>Q!E!8kLQI{cPM$9vp|LEz-^*O{M3A!2BSt30Bj^C1rV~ks4YT zBXrrSB8KvWpDVf6gdp`pFwGIa!Rx92P3kdFF&S;++myUvTo?B`|4(o9C{*g@a#d!5 zKDE;?&RDTtdtknV!B?u5x#O_vc^z|jdfVI1%1DOHBJ@Q{Q4bnEnbqTM<%<&*w9lu* zDV(9mIa4)*kWuk8R4(1ptxX~ zz0+9O0^RYbO5Ol>zVbOd;8BWZj#{&onXVf#u@PUzG_#M-nNl&J7K`=kxUhUMzj;M{ z6b6apVB01s;XEE$TWvn=+hKZOqMv^B`$1E9`-tui(F)iuG7$SRWV2qc zdV+duk3Vf{5`P_>{hp6g4PLK>!DS@(CsSNnrfQlFt7kF*C)S11Upc;sIHI7{T?Khnp}G7Hp#>qs&VpwEZSE!iH?DMP z#(B8Z*uH_%MA{h_sk&-+WzrHRUy-=wuH07X8XUAFgY!XiW3^es4V8^=M8Bw9%>%-Z zf3xfV&5OetxrhTKx2no5O`-peZXpTStCw#X4f~ z+4+t4Ra=dc%07Ndy`8(4A-5|2f!%`1VoIvv;oLLXqX^Pc zl9F><5c|3AT&LBgetqt6c76xGV|3?lJ1`_IwMP`GUx|a;<(av}h)hXdMry0|9#&5d899KeJ$>aJ!$Q3rMz#XMxCEu{JfZ!mewA& zKJ{g*Bb<_x4<6Akfz)u5m{LcE0J)%CiBtrjy!RIu|4(37@%b9b#M+R?kM_+Bn$FO{ zsyz)ca4j}8%`o|R-ZND#Tjs$DVlS`_)Kjn3J*wUu0a6rcym> zKO~1A$gS7}F}BB~J3)vx?la3ZnXG_v+a7o1uNd-vdN427Foflu(x*!`6&FBFrZq%@ z#2F~~AjV4$!LB9Cz|x{viB|UTh_<&$2=!SP2tQDS>N?LL?=m~}R5FM7iy(4Xx@SR} z8OlOXxNGUYyfJal!SUPd#za(LA1{)7ct6Vjt>GrlXe8TxyB3KI(_@=)Q=VRjzWQX< zrJ;zbNkax?uo_ec@h4?@7x`PP?3Tc;l*Zz|z>MfYZt0iO5qXkXdO))I?O6m&SJ|>7 zi;X3mXk}e101u0yo8uU@P^e9p^BQ}(>ylSVFAC;Vw~NG7($QvytNHWm8&$`>&Om_l z^KDnrWY_hpu>_#9XgQ~haRaBuDxv_i>+R{nuPOSHpJ>VYbIjAOY`Q9XLeDN zW+jY_>%|UZwtaCG!|*=0P$?%jC;eEi`NHUkddRfb-qSfiqz!r-o^fyCaPY1KzaQ<7 zROiNEG-Z1hM^?pRmz zP3v9aFT_3HYNHJVmpgjOAPil7pf>ydoZ=#-p+S;J@7%74NUp^};OeyJK;y0k{L=!o z<{P?X^n1l|Qxo`!`r}_wZSf&_ke{5iPDA^s zxmMq1DMrK&jF>3HFspct@F`Sj@Y^cbTwQ3^4ccSm)A@Z(E;;@BERD+(z!Lurg=k=+82-fxQL# zFROYh14J)pzplsEx1bcqT0WD>Izc5-MA zMuN=|Mc&Zs`y=)JuuzH2It#>u`(4(%Itef!12PbEzzOaw{a?%4tIshF;rGHXBHkMoJZPesJw4z`)Bi36gy?220- zF0^t}>d&bev3wKO88EUX9J)Sx=shm=HQAmqS$cmCZzIUDR;1r=PIVgvZ*>N1vYf+z zi^k_}{ePeu!%dsi?{x(WrtW?&DF+(D4&_Z#=;zH1!eV&UuB7WGU}KFkHZezCeQ7k0opw!cG0dweHE|b8CjR)N+k)A@$fL3}f}w}8_p%_*SV*W+>-6h0BGaR%^8ZY&vTr~zE&7B6DT zcz_dj5&p^0&zpmn+l&y|@KNK48a1)hxl)1v{`0;?*{fT?eC<3o}u# z(%&L8ui>E6hN&lTp%TfU<`0byIVU}}tVv;r3r5CvdD4&f`99Qx3|-`}I})6RU~nBQ|Uwjdy6#FI-}P=+ec9|BFC0aDN0rS(A8(nNFW`Jut)NBvLAUBaT9 zO(~OSd@!e|=uE#i`|h)0=T(+~R`St?a_HyPl);4M z%aT&p)zzqy{hpBPL&2vV$|^I8EdVz0rqG`9v_Y*gg{b8USBF07U3k~W)6jw}q_g6{ za+!DtR?69}))W1;i8^pwnftUr`r%qVPlm#4sqTF>AdVaQcIBufLx1|Fl3-JN{t^n7 zX`yc3h5E)o9pnr{1%AUSO|(5OO{2gzodNW8;@7(*$CFVhWi#CoMS?X`OF8w7I#OCi z+%>N2F&`Z((R54j##@U1x6c5h*=pj=w;b@noEdg?eQ8ncuVZ5;tk{pD;x=D6i&k(p zxT7KMgYm0Y9G%Tgv-M4|rIQ8JD;V$SR3!FbnoFMC-THR@zA^*P0;B z?UOEl(vQJKYD+n8FynLWUj726cs=PBF_SqCD3o5R%YFZho@%k;d8fx4l*Dr`OzY=} zhjOLCB@8_Tg(3T?^tXRszKHm{{1x@!5^v3~koGOsbCyn(rh>S9L=oJ?ea^}cFK0`V z*}J773v{Plpxen=y;Fs3_g({2W?$75jm``&EEjbLcbIiq-~WuSgaen$x~?u_mt|ZV zP-wY&-J}IBu80p0R%|WGDl&#d^7L$_ucn*Q(=@b|aB392Tog5r@=DPN7F*>&LNSH? zk&F6qPCM3wDdsfW0oQ-Ua^F?ZWF%Pt@`*67-gqvtk^#qp zfQ88C`bo13rgq|0fHm?M{Tz$upYUxDf5+z3M>2Cp4GQt zQoF*sy=YV}bW^U9@eok~YWTQRZKFf)##mP7HM%?fvaA6L)qHf~iAE;BuR3wIWG*kS z#oz?1nX-X(Sk3+YK7WBS{U$SWjf_P%v1u&~a+r)4PQljPKkSevx>4vu9+zg%o$r9w z!pm!71(O&n13)E&$(KJez*k2F99Cp9)758rl%T4Lr6rLPyZzN36YE zAE_b}%^XMAZ;JB;>99q_pv)_B<&o<#D3#u_rOrqtWrs~srmC3|E)!5*fqL{?dnx@S zV1&S)=TO%NhU+l%H;d~q_1KY#n1?1oSr3|zdy)+Vwm*(;x2)b6*`kgvt6!6KpG-|^ z{dN-X@xv3a;nJuvqV*I{H) zE1&O3?`^+a+~XAkTcpF;nl22eCG7j)N|F0v*2rm!GJ)=wi>2-b>3ZC-Tc%i51QbnA z*PG{Ci{mPZB{%v@!Gl)W22V!NOUvH?P2X=-)F|yo8s>ZDr?XGJrwx*(ZWN}866MIHuJ>puz#mdiiD}-gNPTOuK%*kp4Z!DXgbc#WTbuJFP|*DtGn6A zCuzW3CB7qJF|9E()@AQr7syJ6Yz};T=~Yd2@NqpK?n^mKL%`=!myFmCk{{HZWp|J| z!VA)=jBv(83|`d&YNi>{7jBe?Z=ldD4b*l`|Ds>{vIZJ33{BsZzZIL0IRev5mBYu< z>gQ)QYpmdWP;w*Mex^8ND_f~)IWWUGUpNmOGwn%&*|vHyf%6V0jY^}GhFZtt*@mdA z_;n|sSu0v~&tZPIp_|Im?+9lgk>eurv|tgk=*^s|%RN0Jt3zO{tGl}UCyvF=Gr+o1 zkGpg#CJRE9aphMIQ-&zB7H&UygWHM~WjF54N0$EU^3G~m_~nhg+bDrO28%;88Qg&ACkyBQ7pnFQsz^ocB(TrI!L{>mg`y(Aq5++Q1 zawEF0$@2Uf*4XlfE^4nY?)nLGXfL;N)8((##_qeCwd#5nnHZQE43(JH#Wm{Gp@7b2 z48WZtuH+n5dvhv2o)riYmIxJFB4Z+4PJ7KjM6HiGA;OPzwjb{6y>4>BEV1eg@Vwdt z3AO5SoUL1o+OGT3ej}Nl|F}6+QZE4~l}tz88lhKe%{eg@x7OIU`(u0lE_$2TnON?v z(mSe@#-~D3-F>_c>>s?6O3@o6svL7!Ql}R4lAo+hDCc%XU#3*6^n-1xZ|dwG8XBKu zNvhvX6mO_Cr~X9J%*2~ z_N8}vA>=J+^PTztF^lVaX3p=mcP-hfYVG1=8p79{G7Ems&s^ng)Yo59D1>w{?86}m zrm%5tX_njk2Vml9_xJ{P!t{hnanYECg6rhSr;=y}`6UzPU>9KXP(n!QfcC5A(MhTz z;3@~}@$tLt;3RBpF?m=gIvXxap7!*-LpR!6tHT zBRH-)qH}P1OaP{GF(y>$b*1e#Xi*!biukfAJNQ6mtq25V2Z?)9rL^Ys%1d z4`z0$5z}w&k-O1$B6%LV6*n^rZAuqe&Cyp70XbyV_G7kF(LUwUo=@nxl^s-LaqpZ+ zN|1hIcB((;7U#l+2~tmw?0RKh@YkKM?JtRp{z2IJD|y}?``+k$>fN7ZrN62Z+)6;p z;C)}cuf!y$W5xusz2;xm^FEQ19Tk`Uw#J+TSdGWpP0P2Rl}<|(|5d5%T=l=B)MfU^ zDj%~S(cA{jUE*gg?y3rG#XX@65>HyYsrdM_=4nX~)A^IrdF}mqMfX27HR}?A&Kum% zn}dz+{86t?Wd!)6UY$Tr;|j6>xKxvWCFx;Gl8e4EhK|{?&6xwj30VnRf*H^K%q|TM zI%oX;zhP`XZ~ZvWfT-Vkmp_=tL9dA0Uf%r4wa-y+;3cm%T7RO!(6tQ@)fOkeZDM57 z>G>U;awBZ4c}LeK=&lY2m>GDBsCtU7o_!-EgvbQs#8n{5sVnk&igH2A%hzB zBjBB~JcS!#Q`eDm_E<8gtFp4Z9H$wLsl=+f7pQ47tSw42V^3D;q4<}$MymK)<1BMT z!blnY8Q|2du=(_z%unu-nM+#!P-hjojL(O^_|1M@3-5c#473xz=lNX+r(a+=%?HzR zK(TY@fe#clJ}L&5G*J|R+s3Xm6{j_dr5O4FsnfU`>5A);1%_X96Yrpkztbls6-M%D zsY4bG`1FqC-;yS+MlS<1O$tz-u#)UCtTg`KNyLn+bBe2TNK;d0XpOq-v>6hiXzZ|; z;cQA{A7y<`kp<|)ecXcfI<%s!M56TXX;mw&m%Yy9P=1&vt_Pxltr{_7`Nlws6wno1 zLI^cfLo6}NeHwWX@Jo2>YQKw)_vNA;Rbkym~^Em0<0gB%32TlD7q-kqeXvKo8@6FdeO-qt#kN7xNCd>j_ zK>F<~E_{q^qxmCk<~!)TqHeJf1IT0L-XzCJU0uC{qnJ3A*4u0aJ-)>aWk@@AJ!JTl zxToYW#V8s`t|sBwGJ0M`bnTqFh=`@Dk;B2)5QIS$2M50?zTcV6DfG5>ZHHr04Yd#_ zPz#dxe@LrpVu7%-r;v`S{#kJ=4Q%iGp`&}3HAn}EvMbt$8(u{ zg`A`IZ`(S6Kuk`5-(9esra&zaN^lwisW|w4@JKf$rZ{KgDXVwuYZ$fq*({e2E3O`ZH zyR4AhttPyK&HZd6x2})nKkRNOqBaml{iUH&Nu8OA<#8XR^BN?-M{{zFSS%; zJuN!F%ng25(^S_~BFf;3Gk-S_1gl#~Nzpk(C_ok%lrx*toLjTb4=Lpqw|huD6B-Fg5*+wI3}bPACiWcqd(ZIvS?eG@=#+52D>Zm|&-b z66fhrR|k*b+_=I9cROMHe7;!G0bE?G%0=-J`YwH5%prv;(&U2QM6<`a>BdUdBveG% zmM{`jBCgj7#$tJ8Ht$8M+CT1ktZjV;s9@}8)fIlM**)32{{vivTU(;XHr7@Rv6pk~ zVFpNpKteDbJI-wgd*o7XpqKGbyZlMb3CkYc>KWk6iahbr3C{ahMo{55&2qtl<)$J> z%usAc!_25lOHQ24EfejIt! zwW@a$z)f3fuTTxr;9d-Hj2l>Ll2@c}CP>RZcajH@FgFz*m#mWMi@iI_|CmX-Q3Cs# z*F*Nb&~k72`eBUdy(I`te-UJZX`JgGXwoi2NJ@y&z?WEy*$}F!M({mx@&c_LCuyT7 z<4C{CqQzP}w$yqmX&^7p%~o>1S+$nVb!Mw;Ic5e=^?UL$ZG6ThyjpkaGJe|IrMmYa z#BxNLG!ScyT>TL#s>*7W*DoVPJbcR&fd#-+ONQcU&ikL=zqnYJ&sNMocIwOI?dv=n z=$RB!hD6TUaBeh}F|Img^`M03W)TA#3&?q@ zZM8wV#o^s=OmsoG1JR0Ndg=vDqZq&0GPt`aSj!vsm|Sc-RqOS9T3@f&k?hutD6K{M zk(}N=!B0tdeb!sNW1EJTRXShQtS2mJ33B06BKlFuyeRV@iD;ISr%C1;lzCe3GFnsv zt>Y$M^LFpxXTDrEzeKKypW3*Qa}a6XuT(727wMK~Pw=Zrm0a_(G{i^Xp~D%$KSWys zn8!M3?ML-ISIU7LTu!gqL0X9-7D42w1!jq9AX;Q8hs7-EOX-}3aM|664!Ni_(Mb4V z93M1psAwhcjdreRhLZ^mY3^?N9zFe5W!C&{b)U2m%IJcJ0oIY4ooq#*Xyu<=j{Fm1 z=rk=V)C)ImRR?&LhFkxojAiGrMtiBz(;FRY>g$a8XBs)H9Q=sN*OiCC%7bJ8aRt>?xrO3W|%!nZuJePA1PC4TQ(bP zudoP+(%M)Bjji`~ag+ykIXEn?yK%Xf4!{(E?tz6r9TcR(QW06%-0!96GVN{+nG0l8 zfTAM4^_n%G7WiX$GH&x(uFnkyS6tVS+c2&?^4|YdVq$^g@(ttK@Mmhm@o>l*dkr*- z#8OQvdkZ33JoCgDhP5%H?o?FS!>K}J>x>QjwPPjxUm|;ic8pZfMixT~{r9}MM8RXi zZM4IYu2^m-F^JRl%A+^cZ$2VY(if6}O3{b|ajkm>FkFtwXeIOW6d3SEoZDrtJq!lZ z6X@x#9QcFs{k?nvEYP{DI2MZ997VT#cqOdg2)7dax@u;ODYEjVj*01ydFKx`&1z9< z8$)W2GhX5rFA(;wH*=4x6v$YZNu_1%Uf^|ib*MoX{p@dGag7eyHK80DOP`E zK5>G!kh4|dd!1+d?23h#c`3SSZCajB&cc3CIYojil?Z8^w=eUpUmjQde1%WDu=lBv zYR`M8j}M{;ZjH3pL(H=V&HzHEl+^p}T9!Sm{TU%JT z&IwxJy{p9quj?Ql_%2gW_NaybicIzBrQK97rVFba?!}gd+>3WpDfEt#A)Zr+5ope$ zr2a9T1sxrEHa0WraWwSua}d!BPZfRWm7#VNyYQ0 z{KD=e8ijwBTE4;OWZ=bVJSIY0kl<_<%ddps&|}DW&>!<=L+@CV#9X$!<_w_B@8+_9 z@p$GMdp1L@wxRC0symU`_h_o#z{JQrgb;&qT~9lQK_n+9a1Scx==D}>{HmV;*GI#9 z%M#*`+_1Dtd%(sR)v{W5GtR2FR+M7o0Bz`QkCbN!eWh_Xhg_3+xEY>fzYGjy_lAyo2`N zW#+%7$V~V=@`~dh-Qrm(u54dsjug)rUpO4n?6&WHIH}LM=r2mysD(`ToE5)|aspBZ zB}wXH*@t11KyU2_n-+uT48_lq79Q1kKsg!ucZy4nBZK5QT80_D^5iQMQyI0Xu;%ns zDa)&DESBBdf;&ew3|gVqwb)g=%z>QR@`7MsDfuGEw~u$UFOll9n=H0oiYdN|&Vwgi zY*Xe?dhl+7rD|(UDqWj@0aLNXkCI7!hdR6-NCc*#aknnCA%rFbLq%;^&c*Oh`%_rs zM=ju+!tNb^DKO(byu`+KXE(YeCar)BpW&wN#aHK+b~^&=s%&N4J+~r%+qPo%rH*}3 zUDT+W%hvH>c!dZAWhn2=ctBwePDa&|TcZuCJ5E zwn>8X%7mxH*~=loq%!tAgR-yfRk1#DFBHXY3%F@6%ZR_QsB4VBS44MfQ<}spb0RaS z$1Qv3W?L5U3;=1+@RkpEiCN1^pZD!8XsU;S)H-zg!^%An;Vsywl08lug(O(S;(kWxJxd!DlY~6d!q~$6;p7SfNX-VQ}QfA$-&3_5%245~c zG=oxIQ?r`_=HL5dE+icqG1eS#`XWGJ^|PA6_d=-wH3<$WE###A$2Q5k{BHd}8L1vR z4R47$A1{JDv@1g_mqZ4Eok(X+R0$mgSCX^R8zv9VP(DFgbV`TH7oyAFK>U>UN81)! z9_xDp1>IZoG7UA~HaVL`jxHxr*32RbqfN2#pSewidT)a}Z~FVvtCqWvzp{Ol!Y_L} zReWlrC*>hkjvduDL(&B$tsDN4X}kO>(?RQz%k8&?o`GDaq3C!`%lr2v)X3f3mBRGQ zl&d0U$P!n^AtzpT5_tx$4at}uH!MsKd#RBMjlTKlv*{WOYSxZ+LS^vfg7?mpFT2qg zHNsAooc>izf@=ka(Jf8AKRSeP=)X_HO!v07S3F>v^NjN!jFtY z^f>HZ?q5MqGBGfG!Q&$kjU$s$A?m0UTu)8Y{7vc}E(a)(eyeelCqQyPy8P2O_FqOh z|3n}8w>9cqf(V4y!B~?0cqY1A_RXvExYUKG`8537YP+dIq7Tm}k`KN0?|Zw~D@(J! z?y|OL{}T$-g!eMYRc2-VH2I&HSl?g8(1I;u{E52Fd|L-Vw6C)=I4*9||Tp^O28IP`d9Vqzk2mkR$J==9(3`5(2<|LE0yK5Fj2O->Jl z`&D!7Pw-HHoT@RMS2M?w(&jP<<=2&eS{qE5zgL#DGe$LuLQ%1`ERyRR=A#zDSk)K$ z*YluR(>Xj}*ckuln{{re|H0mnSJdk%XCj@O9PQ9BV0>3Y@&#txOwrxK1lG_Bu`@nY2!Dps+Ga!WF)pPs5X;DXV1tNXaB z$8)=A16619&g!r{`F^~^eR;s29o+wED8t{p*v=azrsmB8pRSb|)R=j{SUfCq*`)RbZ^l*Iyfbax|B z)m?!(PT$mY7H;ArE}&ZCw%qMdIUeca3)!-fIG$0Ys?yzah`U7FHt)~7QR4f-C@C|= zL_$T$sBZsILnCih#_l>(MWuhFU_G}Swql`fVY0(rtyZtIhseP20 zV(0V=QUxRN)r_!{b>F5UT->y}SPK%CqOpq)Ok@a5nyWcKDXLks#iQVm1c%iWSi_nK}}xu<56DGi@E`9|&mHvmc$K@QpjzsD;w_wo$D8 zk0%Mgm=0Zdh6O`T-l30-52f$@G!{>q{iSs1{TcM?eC5C4#I&W--^-=OKe!XiMk9$!QRCET&3o!bnQF(Oz_dInvGB^XM?w6dV z+U>G!v4Wm_`IP(wxf!hdJ62~(!SD<)^cHjm08X4n$g1^bA4_7bmzr4<39`xm5u&{a z1>bok4dGeM^_J2t_uH0%9~*xK=I$2`ydCh);9Hzum3q`*&@#PgzA1kHZ)_z5!?Wgj zBT8$+FI9Gn_<0ti@6FnMqCfpd8(bl#99j?Ie zU(X+cXZ4>T*$Z(jQ~%>x<}c?OTD|l8@CBW+pgd1OEwi;u_>m>uU03v>G3^CTTBB_R z)#J@7u7XTYE(C(xSx8~SlE|o%vsH?-A!ET_FrB7RSNtcMGahH)2pJz3P ztgK3>=qgQzgYta)U6$#(Jm{^>b@q*&a8ig>R^O04jEaP-b(Lg{w#>d^R@}{L-cgyrXW%Tgj?bfu<``glc{{l6J z`$Xu_LPODQ_b>OJA@j9}9X4xQV@ySv+k})6SMH~!Jeg{n5#7K3`F~4J;uW!|q;BDT zi(%bXVxVFALC-|A-L0wsS^MBf$o2QN*Utd8-|OIOZ2tOQkAe*ePg~zpVqKJja}76ALYR)OOGyzZuOj48uD=-9Ij^U*?+f{*;~R` z?)vH7@<7xBGUXbTlp_@bk#wMIxwB$A2V^cJM*k_v2CF<*q>D$KE~0O2aPh$s-1HhN*PTts_AI6z#o+q9ZxHyJUT7#Rh~Tw;hAh@PvENjwj4_pGuDY#^zI=Zw z;>pzUG-N+PaTG-VL()g!PLBciv+9Rtb6o=HxcQs8VxbjU8n?G>-06=mBc77-w;k|J ze472P?K1Y3GtZkjqG^Lg{$TEvk5%gXpQq!O3OqmjE7V2+SNp+=IoaNRiXB&zAx?~v z@Um0eo|oHH0i5dQB%{^8@O1OpufmD{x8!O8^ysEgr3)*_&_j9jD>#}MgD9OJ-E$k)0_KlEjX6)9S;mTX{VHru0iRkjm#W}a*ODbzYtaAeo z0{obc{sn4;*JAHijk5~O_nKCw9o;Bd+5MyT;q6b)o_^9mvYX@yn63rKNXf@ZM>oeB_I7QsK7;K( zGBIV=GnZH>jPG~D48IUEyYuJA_y@}WOOmAIzm}jW{%il5^MTm^&=#yw>?gDN$-BWb zfVdfX;rV?A(5+B&98M4sC{EQl37gK}lK=DAPt;Kx&uwXeOTaMsUsLm}vjo?>IV5ov z)_-T|A}%Nz&6I8Jb$#G0aKcpC!-pHQ)1e*it6sXFT4joc0Jw2Xw{wPm|Os zNon)sKiGf4scjT-*Fcm@GcTDOtg#lg;h_;N@482gUmvwc#w?7s1P!PnfoRxv<<{e9 zlLB=Q!BOXN)-L{4&t#RYnF23bdZzrPJvtF|?CgMRG_@gQ_awo-h3#MpAC^!+aMTT< zDuU^4DyyuDitN0uc;-ebk2UoOlQvz2uINjKK%1O;0DjK7}I`y4xk777k@KZfa zmIjm?x4S=&=`Hpfjc18G78m3rfmS)&y|rPXVWby`FGWA-X`zX6R=Dx>Kq)P$z;(rK zt$p%9Dy9}6pyUIpydxAs$90t~t!aHiS1n2oR5|^1vRRI6wn49w5doAfEennn3_?7EZ5i`xre4feH z+%>7f_*6Q~n{o9$#tf*9O53=YDnibc>88oaMe6yJSqs_m3RU+dNJ)vdV5_Z?{YcO_ zYeKoxXmS^nni)L0;m+SjwE2!jrq=?`7f_vIv6v`M-iR#2@v}UCj$@6hPa<=EAt+le zXVkNLBZS5&oH6zaIOV9U{q6ys4?}2-=eQ2Kc(|e{UUzaSI?~2hVvKv=R0S-Y0f)Vu z3V^Yv$0$QqhMngXsj*byg|sQQxYt@$yJnd8=J8@^9+4`9hEs|=Cbgx@iC{bc|Im?m zdoVBGtW0n-$AK7WP(@+qpGPCf~ zz*)#ls~wCptT8n(!A>0K@1-;OGFd&SvsPNA9jfQtV-*f(K=c+=H+Q8Bka(WXe2~=qabo7E+JuatmtXKLNrM+2%VW|?iYKx`TDlKcD44Sh-3G(sZZoe{ z@{@t76UTt>Ci6M@^clpcHnDzSXT9+JrvN}Ovu{3w`PYV&X*cfLG6!W8CfZw6bnp7l z7(CYaPSeN?G8Z2=ymDizQDn(vtcVQFS1VzkKPg^Dwt6)NSFcC+`IbWdT3voe(rvBU zOALLSiVx7p@60v+TNU#uOUXsag-8d>6V~AN>iQnf{vh1zD)Olj13{c%D!9%M(Zb^S zfw!+mhv89tzlBO`MtI`Zu3T|7MRW5DfAnBsRB1qCM%oBzVl3PZXk1GDnITThe!wN& zGl;3*9w=J`k~FLqIY~Dyx;EZh+wSt6xfhqyEXz^?T&5WG;+dKY(;- zo&mtgf>Ys)nS=vzBbaT%z^#?sODkL**YI&D&kM2ui|B;>8W(u;B37fltk!I$sNs}8 zWCP~Ep90~hVLLE%DvG?->)DXmx;5$M$e4M1)zD6OKjIqG$JuqGt+B;pxLaXT6%LQ~ zk-k!G_1ioiXWDW5Np`p*Gu*UPVGR_ao}ToVs_#6)`+#kW>qa^`jPoaO<;Z1k z@p9>h!(76%d4+t`JQeO;`n@1i@%+h9;6ZBQ3lw`ke z*3USZYvav&@mTIgSDn=R%U*BdC~02Dgt}tAmqO`2%R{5r-P2bN>T2#;y;?LmFx2*z zs94{6i8{R`h03}#?dFi5+!0y;r(#*t3%H649Bvxmh_6mIN0-!2zrjM zO=F(qQ8Pr-_h@3#86FZ-594YppiU{+tpVh>F|i}OlAD@JY#;veguuy{tERFZkaZx^ z*mv)^{cu-Hlp)652Li-G5rQn6d_0v20iQ3$&34t6XEVlZS#}k++Bs_VYnqP~;5<_~ zKXto>vR@I^(9Qr#IqU1g{7GE=GQR5KKiV`si*&wf>YEafXk$$bu6b<}&Dczqn5x^9 ztPm%fP>b!@Z=YLTig^QAZcc#es+J@`*W9pQQDv;IxoU7RgZ*TY`pvh|2w8 zCj++vchQqolo{#~yqpKAHWmn4arSbaF>P8l>kHOg>Q9JRzF&8k%wDU!5{VrU7i;D1 zAFaOo^dOBcTsM``%s7Pu~_Y z9DKVB5wv#J&a5P6H2N9G+u38WS7mhnz3f1Pp7e7a;TET1m(@qZE!%GDzu2zaza}v5 z5?21fLnlu!LxVo$ZIb15ooHG_Uzv6+pGUg7Gffl>m9PH6H_?wPaUhlM3{b{1DiAF) zz?FXnFclBU7f&|3uez4CrnFRam&D4~VmN`I*cj z`*MaQvnNrMs61F@>BfMV2bc?HE9Pi8#J=nMdVwZOhunCQkMOrQykDw584ioBw*+aa zckaA#WOsMH{LQ?gk1WksROA{s9DA=E5+K+~zu%ArA4oxAN!J8oF1-Ty_ZB1v-%Zyw z7#QA?>E1P`|2{4Xr}ievuf*aNriFl!{hfi?N?|Ko(gS%B4UdLDt+v0iL%m2bt>cUy zvm3oyjT(Pfi71K5X*w|l_qfjJjVl^}G%eh_deTw-*bNB-Z3u!Bx|uU=UlU`xt{rbK9A2n{Sa?`xHWn9lqM*UFy!_cC&J}B z9wnL~Yn$)>b5WqzjD}EDDBI|Jorhk#hItOQo4_&OJ!BHM`OKE{$&&FNwrVKL4k9hCIQzI4_i`OUoJx>? z^jYQ}NPX8cjG<-g0L*yM?pU)VYs{?Q%85GaR+^VSO##_LEoZ48g}m2yyw9)IrrGlgPstbz;ATJy?%zb`o-ifPM#1yUEsh*aM1p+MmD)2^s zm-eq8{txU`HxQ;v) zye)v?wG$c6_jTs6Wi0JvC}Mw;m(<@^&vU1?6TndG49sJfWUTU7&vHhzQE11@eApW6 z88MW4wWw!7!6X}yJ?@lEH48_4)1BZo2xZ~ybMqj-_Jv?7by3aj4!JGhrM8)lCB2OB z0}i!uNHe^t(|RF!A#T;u8gHXpI4rif*x(WFw&~>JBgQ%r9&+I3d)8q4)2AHA(a)yaA5IQGnSRe2jBn$-BhFfWY0l&yh;wrwqMw)UVeFDGFURt;AQ6K}v?MAm zB{92qyil9=V6urjUK^8#XA}70=~xF;7V>h z`Cl@#2MxjTl>0o4UnwY1{xZQGUrI7L;~C|xhuU0H%oQK8Oqk&3gfjV=O>2ZZ@33@X zE;NdqOWA7gS>@x=WlNDL%7O|v2kPhxf5)@55ww2k|jq zTL0@EhqJBv^ESW_uE*KF^wTx~t}P|4d66)z@k_VYl#&vHA`{r|BH7es;nrbAs1Ms~ z+2cfrpE~dF3ru(9K|e1AqPLVUuK-R1Q3V=y8b07V#CBTpSovz= zBSo{(x)#m<*Z}#LcS%c!W4qk&?ew6T%ZWGaZsFz-uj(7-D0WJbdK+U#;VT|_!TO3e zmG4laoX?g!1Me1kTG%*X*`KR>8)y}dl)xwdx<2taKQPAdjxJWLcyQQ}SRUlRe$)Iz zS-3PfCh@RMwc{>kjMz-c4i!(6GXZ$rC>;X0L!t!&p(TMVA?>G^WlT-Z_;Ovr%syhb z=a>T+yo_&YS?m?17)5$KiN%o?T~hS(TI7U7K$BxO&}tUDKIiFajSeFT=8nUT z$_MBq8ZW}ERZ1pW$ckPJpbfv;clB1JFGrOXA651TmL8dxCUKni&a1UCb7&BFqnAtV zBCqc(Wy7TZ##hs(hWHY+BtL>Xwkp`>Jsr(soi?=`;6D}z5Wt9J1`?IL&6xvipFkr z9vid*CGUphRAA81t_jupdQPORT&I$z9w8ht!5%9$-KAxxeW-L>Mi$5`c%U)C>N}S^ zSjMQ}HF$5>2Vbs(anq^jQbAjxZ9Kbp*9OZM&zf-BvY6XyZ2M5?vsNDlSCwHmF|LL$ zNiH;I-5HtNPdyx6>YhTsj9z~Bk3|3W=il9^cjhtjYJF|g(e!|=fZ&)TtieWB`y5^C z=liuab`^C= ztr>VVk{pi%8Au!1n8&0CPx=(ODPeM2=29s0OWD~#X>0XY(b!#{i7sm(y*fZ9B@|4l z(Ec9!-fY@xDtdUpXf}3SH@GFQ!%(pJ6}S9t;?-f_g*;BUkTLIWVML=nY>6_m}-Yte=~>e|0jr?O4D6h}p!=Ox&y+ zTFH;`^qL~9t@1?E_;6BTD93H5>1nhEL`7%>1ZrW8BOHn3&oyoYIn0!@?_A^cCSJs{T5PO)mnE;a^hmBJS9x4Vr^h@OeR>o9MB^5e>I)BNs1eODusH_M zXy6kwA=O_`SCn1b#$Nu0C|na>pWh)11PdJNQ{|e7BHK1?NTZ$e-wxLCKXe{4k;i%u*XtK}+O#W6V=-RYG#SH>zLcxPW4X)(l!* zjA-ip3Y~0fdAsr}?f%|9!H*6csMA@H@26O#Sej&27M+4Y7Uh5M;WuXU!Oj6?`jl$ zviWV;)h~2pQm;>Mn+n?Fno8^O(te$m6DO+qKeS82Qlppnhm6E&TH|LlS4tLZWMzc; zVp2@2C--L~1MguvD>o)D$_Y>XRm~IPo!!i#)H4vwKJb4F{G)Yz@Z2v(fpIJDZGRMbBHSRREG+=Eedd+nH^%QwtyD&|m zhIHe+1 zGbj_1!W(np@gEfE*G~Q0#7GzJ=11q{%-&3B=%jfSk&K}AB^lRgoeNr<;Sw|XmMIoD zi}D7}(&2VDwUU%CkO!RZajl)0LlU;HhG0Ad=7b%HiRb-yY32p*^?g)AJ^M>5#Q(t9 z@VlDnv~f>u8X|bq4TA0#F@KXnW5i)5+?e#vm;9k6*hdQ1!%>zQg4LWAj04rsDgMX* zY1kdN-etN1eI4CAEgkB7H`b~HceNJA+q}BraO@M;3It3AHAq2uIM$m9V}ySOU5B<0 zzLCY(ft}K?RMuVfkF|PeT2w-4@Vtn;IJpc*b&N!B-+5OXy_~=4=X?J{yhayLswN{K z+WM{Mpd5miud*b^3;^{x<7v)w7PWn`;QdtkvEK5V$*MOUFVB4c@y=Fv=2vI^(|_0y z&RqJtpWzln*YXDpFHjC7vXXo%YO$Wykajn~D_fIx?aX5%NX ze%D%fcoe7NYw?e{)2>dER-~w2e^bMRZPVLkSrVI?#8Pk2PIwDYo{Q?Q(i*CfemP=> zlCI`dGPExVxueP+>h3gfyVPDI;$&e4$j-Z)d-?r;OZ`_*{N0t;pGzcvh2qI~fvSMm zn#uI5!Ml!6ufme!Y22#qHk#*IIX$tuF=zq*CkKUNw}|MAp` zo9AAVu=ge&u4A@*ZK3Eni(oR9#HSy}Pnw{i?_xXJ zUbpwG*s`xr0=RI5McY`4m;7nhZf;FLRqP^3_$f(iDn~=m=O&(=DJfA?F(58(Iix!p zp}w{_8l1{wY2nlYHw96R? z_etkv)?-S2lxKK@*^!z+5NY7Re`AH9x|InhDd1L{-9|ByVY55)czYHJ(lkO~Vm{38 z5o6Gp96#Rsm};#jmSB+u2|%2}bKOUz^eJ>zo1SK^@Enp(0@#)YRs*H)_zEdoVh@q8 zTIH%1F&p-PZ-G`P*t1Gw+*^({=){R_!T~pHNCU>&BiFyUMFD&kDK_Tsee|83H|aoJ zC~8?N5wPdE-CXs$xXr|AOqp{AhOd&Bl_fWF6y(4j3SwXwMbmF!1t_29mbjfOaCNs? zx%)Q#t;o{ua7R>Mc?0yuYnj~j8cZ~LQYr*f#=|fs6H6RpD=!`OWGG<>{mA9gp^7A2 z*~YcJE;CVWhN1ieDFn#C_>~7C-reUSaf(a)Z2REh{W;5p;Ggk5e&)%1_;Uyi-v6C1 zP=7v*uQb|S72wDg4`2fD1snLXc$FFehvVX@^ojSK09GK3pRc*35&9wuho()^9WL!<1W7(%nRJLh0*BI)m ztt?o%e$~-DtL6@5q6w}s3@vrcOcxQcwMZ8qo-l6&vqAz;S7Ms zUx%G6@nj8kM-hHmy?eb^7CsBKFa@i_b)1G5uSJCH@zP6Xix-PnBX(qTCRJ=?8WXHS zB@*o@pgUT04v3ODo?v|*>7v5W=FH*PEZ__S!@0V1Gc2o644Ip=MXkG=1ByapfqWyGNf<_?~GuHVoPZ!m_ zj=`cbr;6iLTjpoYA?lODusm`D%($-^M%9{^|zXD8Fx9G;I?02}>2RJxuau zIaPxNcGjg9aZh)-N9ao~Eht$MQY*!HM?<8Q@OU4Tw<#Cc+i!`iiMOUtK#GzCHAnLz zL&>ZpMIcoQGoDd{WjxeG=PB=xe!3!Y)v>r^Co+Ce{1ItE_38eix1eB;)5fQkrmFF0 z1l^O|1GemmN|9}( zGJNkZ@LtE23cawwP>d@TCmJ+X<|ZDN@Fm9L<#x7WKqPa>sUk1k`>%BAr?9UspM$Th zrYS7>N)Hl?)TVv%^T=@V8KFHrF%*U6;`M?Cd__|n)T5Q(mvoRN9J5BL3y-7k(ATH) z@Yst6r82?gkSG#@@Tz+0&0onh8;|_WU-p~Do&g$xQe5b(Ro8vWSSUQP7 z9#m>Lt?n;$94TC>imGedSIYM(!=Z4r-K45%wg{vCtCJ=8G(+f&q(*o953TNB_8Z}C z*EZ$CVrw2z8u8XFu$eM~uk2G^WcBTk`#fesRx^lm2!Pohfcai%sBZbGv=K$GFsz7^ILj_>og`$R;SmMVLju22%VdX* z>8!g$UzWL;Vp(KDF;$F)?4lqE=+T{`hZ1@^Ayy5Ei43et#6N$vGo6gtOLP%TDumInB8}njybD4M27?UWQiNQ~YJBPugw)~T?1X42|Dga3kRVNg8?q+z2T zLrk_{xj;|LZxc5{-srd^2+nmy+11^sNmmjU@mr98F(Gk2$(6CstMx zo)Lq~YU!$`Nj^2WKn&KO*~KlH^4s(DV7dm?E3GR9@kaRW9HKq(kLVd$r!F@5_!u&M zAVHQr*f}wry_T$$f8z=8US<+LWc;nQ&vacZD_o^>Ly#nvRn(uGvAdF@X==;!t;gM#X)_9Y+c(s!-ecXM)=X<`RcwjC z;w^L9r?=J`va%$XC@nZaxH>89e&#)RCF;#OueT8S3Dlruu!_g7G|p5-`BoA$HA2p< zOod(f7X6H{AtyZRmZ@Oq7XQ5ikZ`=BEfG?yi&`NbvAFXU91=U*oa{V<(Og-%azOkz zcYCIEpq}*gCQYfK-AU1bAv6A?wYRij4qI(?FJ2~#0gc48Cr@Lws^YR0y+!#`X!hxZ zx|t_ga@ED+4s*~_vDE@9IP$tmXo{nUqS;U@dXPnLMV~v}cYJvpe~%=6N0P2}Wr&IY z#G(es7#E-z{X!iDM|R|~64~n+X=){E+Cr}p7hQJ)(Cr8|2T%e*TnwD;Fl+27wd@LA z&rR3^_S~LP?gGSoAAIV%NiVScjgmZVggkQ=Ypd5tbw%1&ujZrz$+;Qv;_X zFk1OOH`GA$lHsBMo#X|?ySw{G-|-e5DPR2<6uauydV5%2OQ)wQpJAKIn(tNDa5UAAL~*)Xg7XMIOT3cu#Bh(Ea{Dk;q>ObNiH&uR z1zko&R{*|ZDBRZCVLV{&8W|502!f6< zZ)SF(DwLfIY7uzXQTL(O$bj1j z(H?RDV}0=US>j!mHCp8ek*v8gQYKrqImTF^7`%yOxLnp-swb7aM+6;*6xw`!jfb9L z3-ON2qHf9DH?{?WeW7_po>mLx9Iwvznw1-F1CIl^7&gaKG8VwHbt*|4)A?dD_pagL zr$yK!Xv7LK4W@(=5aUH!0-H}|M@5c91gRFD+%kh7-5S@LF@#p!`-tNp;h?`RG$TbE z_C|~{b3AG6duHw7^x{e*Go{!-$G6UzbQv~xh28)z(J3e5Xld0k(bw<@KyI9|fLiIo zN9v+JuB>U8@bKi>1^ixz;KLj0RFXaKP=03Xze#I}M7{*k6&S>(AKb_=-pU)y<|r*R z&R;iEXWMjrJF#UdupJ6z%hd?In1#a8m7YSY(~^I(ko@o?{S*7fvmZf}{=_Wuzx}f- zU$1<}Yq=Y5x!d<0Z!^(<9FJ(@>yM87M}NOy7$cw3I|2qyevvC))Ew~E>3<8(>F?hX zCEtYEjfh#zgbge`F`tW@%kD-RbuutKz(vzx+k{~J(P?*0{Jx6m^QEojw2geK`^|m$ z-+tadY_2IY9Qe9*8;~Vi3NPF`=#X9J5l*7OE5H#fORXg*RHNR!^Q7fSRNWhxUD=rW z;b8dx&i{*gn70u~vaB2%mdrKqNKsSM*U(idbSfxxTCuom0~*yw0Z=7cfsC^`??PoD z8S8f`#5lOgY|s+G9qWMi2It(=t~rj8PQ15LN&f;UIFrouj&?)${?Q zFAc>IP*#2Au(v#q%}7q^YWC&@8It0-MoMQf&q>~7XyXEA#@KDYJzOhGIHKWC{8uRjoFO-6etb01r1%}5lAZBf>Y>s+0YF5i z%zSLUxx2rCXInl(nG`zh$i_()sK+ve5=;{Rr~whFoCNuo$IXP`sQ%W?1uY2Rw{ag| z-{bfHEc3`$=g+F%PAyw9!+sIbq?I91Ps=!XhIk9m>x(L)d8IGBGsKlR-<>;w! zDvx5l982kmcy|qna8ANqu9ckRX1s94wnmG9c28668`S;SXXc(*<|cZsg06X8wnhg5 zjCYEOLE-JYHqUR*8p?h2KkRrNXcdau0iW8ZFfbL0g+?y1bNYmNygVQN*=`aD&ZJBZ{%;L=q z8KvsTPSIi(Y(RXlSaK4 zJ4{BPp+O&+GVPa4a7Gjbpr=QanEiL6!{2Q={3PKzD**fp{o%iqSN$YaFFb4-~xbvWnM{zLl_NzCh_Q`yv+ zjQYk*7Z~az>a`EMfoHhc80bEC!u;MDul&EbNx8z2PWsgjU6FGcF5QXF!qi1l$?H8F z7+d++hkhW~Rcu{bW6DXh=-&}b{;cYwJ2{wtUU*W?&80s&X^b4HH$f=2(B*DM7>uh( zgSjM?;D#$}??^-x_W1#d0zLtUGSl`xl0zT1l=M2_)p?Qq3QpzamB34_nT*{Sgl=*> z48(I^p7;pIhvXa37dHH)C`R?*BTOhbVQ_ZHqmtD_G?p*`xkQSxzADX+X^)dPT*|GU zk8#Q{XMYzAgxTC@p$5$=zwNR9@IcqFi-}f}ZU1iPyn;banI@0ToGY`fK8VWYm53qZ zVIpDkcRXR@$c-~vSYZZ;X*HRZW!7xrS%1c-3Ofu-B7zK#$3I*}8mQC}`@NFRcUh6&aOmvfe@RF>FwxB5R zd=20cK<#GtXz7%_bO(Hfu_{X%itkiv&8o84ShgW@=WLE=O7g57yro--&^fsVl@BIv z%O^He0ln4=$XZy7#mP-rkyBq743adTuBVU5ltW8aIQeQdT~6#R?i3sahlADis{(qX zqD(Q%w0_*giKs=x61dfjzJNt}%-w5RxWLFD)s2>ya=6&e`=7|b-{!>h_#D3Dsrqi3 zzgvH3I&T$J458>*^PO@qj?lp*1`#F?WPvg#T;(&121}Y)Y8aB)AaNDw<=f2}QX2kU zt%&x<=N`fl2bzutRvoigK+@%}p26N-!z@l*E_)UYPJ3$hg&)UncJ47|sT2W9Hhj)x zCw;aYS2R?NRqY>_! zY9Y@6LJ7-B!bhiO#|RQ`?|!r^DryHoM~mbmYD)#tY4F2VP_U?SSioh8YYg*V!gZ39*Y*b7PL zHa9nuYURHf9mD*f5jp_{XUqIk-DyE2Li#7+(-c{mtTy!9tFrGLqpg_PVHf8CSL3sV zyDe8SFTpzqcNnC#rKa+Ud`){L=kQq3r3NfGswfx$rAWdbZ3DVzv5ICyu~+iJyXu+z z_ay>}?|#P{^}3EAI=#0kcDeP2OYvAh(!^*llOjK#vr*_Z-hij^)B#@`mSR@@RQY7g zzs;OmGGZG{JY}5Y&#Io!gh(_KTp)L_gkcZs`=nfabnld< zgjuKJ2MJp~jVR^<1Z`vT;j3Uqp}GCRgqRRyCZ$>hlfV~fK<@BDGw@nZA4{@&VpvzV zS1_O{c^7F7Dl;_#5A`+$tY&4)Sehlr^;v|#nEE;3rRo5q=EBn)*0GKD%FIR_2(z%b zU@NTKR0NvYlm8sx!az6UnZT9H?@~pdCI2M0ZekB(Ga8!kHQMqq3qHPvE00h_JvmqQnE>qA;$fxdwD|w8rX#~ zU4Clh%NZ{p&Mc-tR+-q$K03{G_c(8VUd8M$dkNOXf(}B-<)J|;OIE%wfGj;M+IBja ztz>Cy{zNV7M-(xej$e1Yn23wfUPZC8vT_f~%0DEu7D6-Y>G^b$v{1k$?kWaOE{Ql8 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 Date: Sat, 13 Apr 2024 12:28:42 +0800 Subject: [PATCH 13/46] Update PPP --- docs/team/yyangdaa.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/team/yyangdaa.md b/docs/team/yyangdaa.md index 6b8d068cca..8b7cf11e6a 100644 --- a/docs/team/yyangdaa.md +++ b/docs/team/yyangdaa.md @@ -28,3 +28,17 @@ docs~functional-code~test-code~other) #### Enhancements to existing features: 1. Wrote JUnit tests for the ExpenseList, SavingsList, SplitExpenseList and Parser. +#### Developer Guide +- Added implementation details of the `AddExpense`, `AddSaving` and `SplitExpense` feature. (Pull Requests : [#107](https://github.com/AY2324S2-CS2113-T12-3/tp/pull/107)). +- Added design details of the `AddExpense`, `AddSaving`, `SplitExpense`, `SplitExpenseList` and `SettleSplitExpenseList` classes. (Pull Requests : [#107](https://github.com/AY2324S2-CS2113-T12-3/tp/pull/107)). +- Added user stories for my respective features. (Pull Requests : [#107](https://github.com/AY2324S2-CS2113-T12-3/tp/pull/107)). +- Added Sequence Diagrams for `AddExpense`, `AddSaving` and `SplitExpense` features. (Pull Requests : [#107](https://github.com/AY2324S2-CS2113-T12-3/tp/pull/107)). + +### Community + +#### Reported Bugs and Suggestions for Other Teams +- Provided 4 DG Peer Review Comments for another team. ([Team #1](https://github.com/nus-cs2113-AY2324S2/tp/pull/25)). +- Reported 5 Bugs for another team during PE-D. ([Team #1](https://github.com/nus-cs2113-AY2324S2/tp/pull/54)). + +### Tools +- Usage of Draw.io for my Sequence Diagrams. ([Draw.io](https://draw.io/)). \ No newline at end of file From 63b57bf7e40f5e11b40446077d4c8570133725b1 Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Sat, 13 Apr 2024 12:43:37 +0800 Subject: [PATCH 14/46] Update PPP --- docs/team/yyangdaa.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/team/yyangdaa.md b/docs/team/yyangdaa.md index 8b7cf11e6a..6110db40f3 100644 --- a/docs/team/yyangdaa.md +++ b/docs/team/yyangdaa.md @@ -27,12 +27,15 @@ docs~functional-code~test-code~other) #### Enhancements to existing features: 1. Wrote JUnit tests for the ExpenseList, SavingsList, SplitExpenseList and Parser. +- Implemented Logging/Assertions for improved error handling. (Pull Requests : [#45](https://github.com/AY2324S2-CS2113-T12-3/tp/pull/45), +[#56](https://github.com/AY2324S2-CS2113-T12-3/tp/pull/56)). #### Developer Guide -- Added implementation details of the `AddExpense`, `AddSaving` and `SplitExpense` feature. (Pull Requests : [#107](https://github.com/AY2324S2-CS2113-T12-3/tp/pull/107)). -- Added design details of the `AddExpense`, `AddSaving`, `SplitExpense`, `SplitExpenseList` and `SettleSplitExpenseList` classes. (Pull Requests : [#107](https://github.com/AY2324S2-CS2113-T12-3/tp/pull/107)). -- Added user stories for my respective features. (Pull Requests : [#107](https://github.com/AY2324S2-CS2113-T12-3/tp/pull/107)). -- Added Sequence Diagrams for `AddExpense`, `AddSaving` and `SplitExpense` features. (Pull Requests : [#107](https://github.com/AY2324S2-CS2113-T12-3/tp/pull/107)). +- Added implementation details of the `AddExpense`, `AddSaving` and `SplitExpense` feature. (Pull Requests : [#207](https://github.com/AY2324S2-CS2113-T12-3/tp/pull/207)). +- Added design details of the `AddExpense`, `AddSaving`, `SplitExpense`, `SplitExpenseList` and `SettleSplitExpenseList` classes. +(Pull Requests : [#207](https://github.com/AY2324S2-CS2113-T12-3/tp/pull/207)). +- Added user stories for my respective features. (Pull Requests : [#207](https://github.com/AY2324S2-CS2113-T12-3/tp/pull/207)). +- Added Sequence Diagrams for `AddExpense`, `AddSaving` and `SplitExpense` features. (Pull Requests : [#207](https://github.com/AY2324S2-CS2113-T12-3/tp/pull/207)). ### Community From b7bc751bd6d7fb9ac9d28cdff0956054cd0d9258 Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Sat, 13 Apr 2024 13:11:04 +0800 Subject: [PATCH 15/46] Fix CheckStyle bugs --- .../java/seedu/budgetbuddy/command/AddSavingCommand.java | 4 ---- .../commandcreator/SplitExpenseCommandCreator.java | 8 ++++++-- src/main/java/seedu/budgetbuddy/commons/ExpenseList.java | 7 ++++--- src/main/java/seedu/budgetbuddy/commons/SavingList.java | 7 ++++--- src/test/java/seedu/budgetbuddy/ExpenseListTest.java | 2 +- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/command/AddSavingCommand.java b/src/main/java/seedu/budgetbuddy/command/AddSavingCommand.java index 721963d3b1..7fe456f317 100644 --- a/src/main/java/seedu/budgetbuddy/command/AddSavingCommand.java +++ b/src/main/java/seedu/budgetbuddy/command/AddSavingCommand.java @@ -3,11 +3,7 @@ import seedu.budgetbuddy.commons.SavingList; import seedu.budgetbuddy.exception.BudgetBuddyException; -import java.util.logging.Logger; -import java.util.logging.Level; - public class AddSavingCommand extends Command { - private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); private SavingList savings; private final String category; diff --git a/src/main/java/seedu/budgetbuddy/commandcreator/SplitExpenseCommandCreator.java b/src/main/java/seedu/budgetbuddy/commandcreator/SplitExpenseCommandCreator.java index 354e147585..3a75624925 100644 --- a/src/main/java/seedu/budgetbuddy/commandcreator/SplitExpenseCommandCreator.java +++ b/src/main/java/seedu/budgetbuddy/commandcreator/SplitExpenseCommandCreator.java @@ -34,7 +34,9 @@ public Command handleSplitExpenseCommand(SplitExpenseList splitexpenses, String try { amountValue = Double.parseDouble(amount); if (amountValue <= 0 || amountValue > 1_000_000_000_000D) { - throw new BudgetBuddyException(amount + " is not a valid amount. Amount must be positive and less than or equal to 1,000,000,000,000."); + throw new BudgetBuddyException(amount + " is not a valid amount. Amount must be positive and" + + " less than or equal" + + " to 1,000,000,000,000."); } if (!amount.matches("^\\d+(\\.\\d{1,2})?$")) { throw new BudgetBuddyException("Amount must be a number with up to 2 decimal places."); @@ -62,7 +64,9 @@ private String extractDetail(String input, String prefix, String nextPrefix) { try { int startIndex = input.indexOf(prefix) + prefix.length(); int endIndex = nextPrefix != null ? input.indexOf(nextPrefix, startIndex) : input.length(); - if (endIndex == -1) endIndex = input.length(); + if (endIndex == -1) { + endIndex = input.length(); + } String detail = input.substring(startIndex, endIndex).trim(); return detail.isEmpty() ? "" : detail; } catch (Exception e) { diff --git a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java index 2473a1254f..e2a40d6f67 100644 --- a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java +++ b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java @@ -18,11 +18,12 @@ public class ExpenseList { private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); - + private static final double MAX_AMOUNT = 1_000_000_000_000.00; protected ArrayList expenses; protected ArrayList categories = new ArrayList<>(Arrays.asList("Housing", "Groceries", "Utility", "Transport", "Entertainment", "Others")); protected List budgets; + Ui ui = new Ui(); @@ -165,7 +166,8 @@ public void addExpense(String category, String amount, String description) throw .orElseThrow(() -> new BudgetBuddyException("The category '" + category + "' is not listed.")); if (!amount.matches("^\\d+(\\.\\d{1,2})?$")) { - throw new BudgetBuddyException("Invalid amount format. Amount should be a number with up to maximum two decimal places."); + throw new BudgetBuddyException("Invalid amount format. Amount should be a number with up" + + " to maximum two decimal places."); } double amountAsDouble; @@ -179,7 +181,6 @@ public void addExpense(String category, String amount, String description) throw throw new BudgetBuddyException("Expenses should not be negative."); } - final double MAX_AMOUNT = 1_000_000_000_000.00; if (amountAsDouble > MAX_AMOUNT) { throw new BudgetBuddyException("Amount exceeds the maximum allowed limit of " + MAX_AMOUNT); } diff --git a/src/main/java/seedu/budgetbuddy/commons/SavingList.java b/src/main/java/seedu/budgetbuddy/commons/SavingList.java index a8b8c53d4e..f8d9cdfe61 100644 --- a/src/main/java/seedu/budgetbuddy/commons/SavingList.java +++ b/src/main/java/seedu/budgetbuddy/commons/SavingList.java @@ -14,7 +14,8 @@ public class SavingList { private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); - + private static final double MAX_AMOUNT = 1_000_000_000_000.0; + protected ArrayList savings; protected ArrayList categories; protected double initialAmount; @@ -142,7 +143,8 @@ public void addSaving(String category, String amount) throws BudgetBuddyExceptio .orElseThrow(() -> new BudgetBuddyException("The category '" + category + "' is not listed.")); if (!amount.matches("^\\d+(\\.\\d{1,2})?$")) { - throw new BudgetBuddyException("Invalid amount format. Amount should be a number with up to maximum two decimal places."); + throw new BudgetBuddyException("Invalid amount format. Amount should be a number with up" + + " to maximum two decimal places."); } double amountDouble; @@ -156,7 +158,6 @@ public void addSaving(String category, String amount) throws BudgetBuddyExceptio throw new BudgetBuddyException("Savings should not be negative."); } - final double MAX_AMOUNT = 1_000_000_000_000.00; if (amountDouble > MAX_AMOUNT) { throw new BudgetBuddyException("Amount exceeds the maximum allowed limit of " + MAX_AMOUNT); } diff --git a/src/test/java/seedu/budgetbuddy/ExpenseListTest.java b/src/test/java/seedu/budgetbuddy/ExpenseListTest.java index 164f14e949..8397f4de84 100644 --- a/src/test/java/seedu/budgetbuddy/ExpenseListTest.java +++ b/src/test/java/seedu/budgetbuddy/ExpenseListTest.java @@ -133,7 +133,7 @@ public void filterExpenses_filterByMinAmount_returnsThreeMatches() throws Budget } - @Test + @Test @Disabled public void filterExpenses_filterByMaxAmount_returnsOneMatches() throws BudgetBuddyException { ExpenseList expenses = new ExpenseList(); expenses.addExpense("Groceries", "100", "Apples"); From 5e47b91c9ad03119441bd5494df59258784f406c Mon Sep 17 00:00:00 2001 From: Dheekshitha2 Date: Sat, 13 Apr 2024 13:54:14 +0800 Subject: [PATCH 16/46] Add changes to developer guide for budget functions, added CommandCreator for list budget --- docs/DeveloperGuide.md | 98 +++++++----------- docs/diagrams/sequenceDiagram_listBudget.png | Bin 0 -> 50789 bytes docs/diagrams/sequenceDiagram_setBudget.jpg | Bin 0 -> 68606 bytes src/main/java/seedu/budgetbuddy/Parser.java | 5 +- .../ListBudgetCommandCreator.java | 23 ++++ 5 files changed, 66 insertions(+), 60 deletions(-) create mode 100644 docs/diagrams/sequenceDiagram_listBudget.png create mode 100644 docs/diagrams/sequenceDiagram_setBudget.jpg create mode 100644 src/main/java/seedu/budgetbuddy/commandcreator/ListBudgetCommandCreator.java diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 1f849f154c..dbc6bceac4 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -7,48 +7,6 @@ ## Design & implementation -### Budget Management - -#### Implementation -The Budget Management feature allows users to set financial limits for the various categories and monitor their spending. -This feature's objective is to give users the ability to stay within their financial goals and avoid overspending. - -This feature is orchestrated by `ListBudgetCommand` and `SetBudgetCommand`, which are initialised by the `Parser` -class. Below is a description of the key class attributes and methods involved in the budget setting and listing -process: - -##### Class Attributes for `SetBudgetCommand`: -| Class Attribute | Variable Type | Relevance | -|-----------------|---------------|---------------------------------------------------------------------| -| expenseList | ExpenseList | Object containing the list of expenses to check against set budgets | -| category | String | The category for which the budget is being set | -| budget | double | The budget amount to be set for the category | - -##### Class Attributes for `ListBudgetCommand`: -| Class Attribute | Variable Type | Relevance | -|-----------------|---------------|---------------------------------------------------------------------| -| expenseList | ExpenseList | Object containing the list of expenses to check against set budgets | - - -Upon the call of the `execute()` method in `BudgetBuddy` using `command.execute()`, `SetBudgetCommand` will update the -budget in `ExpenseList` using `setBudget`. Similarly, `ListBudgetCommand` will fetch and display all categories with -their budgets using `getBudgets`, and highlight those that are above the set budget. - -##### Key Methods used from `ExpenseList` -| Method | Return Type | Relevance | -|-----------------------------|---------------|--------------------------------------------------------------------| -| setBudget(category, budget) | void | Sets or updates the budget for a given category in the ExpenseList | -| getBudgets() | List | Retrieves the list of all budgets set | - -The `ListBudgetCommand`'s updated execution function now features an improved display that not only shows the budget, -spent amount, and remaining balance but also clearly indicates when the budget has been exceeded. If the expenses -surpass the budget, instead of showing a negative remaining balance, it displays "Exceeded", providing a straightforward -and immediate visual cue that the budget limits have been surpassed. - -The "Categories above budget" section offers a concise table summarizing which categories have gone over the budget and -by what amount, making it easy for users to identify areas of concern. - - #### Sequence diagrams ##### Setting a Budget @@ -679,26 +637,23 @@ this `AddExpenseCommand`, do refer to the `Implementation` section for `AddExpen ### Setting Budget Feature -The Set Budget feature allows users to allocate a specific budget to various categories. This feature is managed by the -SetBudgetCommand class, which is instantiated by the SetBudgetCommandCreator as a result of the Parser class -interpretation. Within the SetBudgetCommand object, the following variables are initialized: - -| Variable | Variable Type | Relevance | -|-------------|---------------|-------------------------------------------------------------------------| -| expenseList | ExpenseList | The ExpenseList object containing all the categories to set budgets for | -| category | String | The category for which the budget is to be set | -| budget | double | The financial limit allocated to the specified category | +The Budget Management feature allows users to set financial limits for the various categories and monitor their spending. +This feature's objective is to give users the ability to stay within their financial goals and avoid overspending. -When the execute() method is called via command.execute(), the SetBudgetCommand utilizes methods from the ExpenseList -class to apply the budget: +This feature is orchestrated by `ListBudgetCommand` and `SetBudgetCommand`, which are initialised by the `Parser` +class. Below is a description of the key class attributes and methods involved in the budget setting and listing +process: -| Method | Return Type | Relevance | -|-------------|-------------|----------------------------------------------------------| -| expenseList | ExpenseList | Sets the budget for a specific category within the list | +##### Class Attributes for `SetBudgetCommand`: +| Class Attribute | Variable Type | Relevance | +|-----------------|---------------|---------------------------------------------------------------------| +| expenseList | ExpenseList | Object containing the list of expenses to check against set budgets | +| category | String | The category for which the budget is being set | +| budget | double | The budget amount to be set for the category | -The UML Sequence diagram below illustrates the execution flow of the Set Budget Feature when a user inputs a valid +The UML Sequence diagram below illustrates the execution flow of the Set Budget Feature when a user inputs a valid command to set a budget: -![SeqDiagramBudget.png](SeqDiagramBudget.png) +![sequenceDiagram_setBudget.jpg](diagrams%2FsequenceDiagram_setBudget.jpg) The sequence of operations for an example input, `set budget c/Transport b/500`, is as follows: 1. BudgetBuddy receives the user input and utilizes the Parser to decipher it. @@ -709,6 +664,33 @@ The sequence of operations for an example input, `set budget c/Transport b/500`, 6. The ExpenseList updates or creates a budget allocation for the specified category with the provided amount. 7. A confirmation message is displayed in the console indicating the budget has been successfully set or updated. +##### Class Attributes for `ListBudgetCommand`: +| Class Attribute | Variable Type | Relevance | +|-----------------|---------------|---------------------------------------------------------------------| +| expenseList | ExpenseList | Object containing the list of expenses to check against set budgets | + +The UML Sequence diagram below illustrates the execution flow of the Set Budget Feature when a user inputs a valid +command to set a budget: +![sequenceDiagram_listBudget.png](diagrams%2FsequenceDiagram_listBudget.png) + +Upon the call of the `execute()` method in `BudgetBuddy` using `command.execute()`, `SetBudgetCommand` will update the +budget in `ExpenseList` using `setBudget`. Similarly, `ListBudgetCommand` will fetch and display all categories with +their budgets using `getBudgets`, and highlight those that are above the set budget. + +##### Key Methods used from `ExpenseList` +| Method | Return Type | Relevance | +|-----------------------------|---------------|--------------------------------------------------------------------| +| setBudget(category, budget) | void | Sets or updates the budget for a given category in the ExpenseList | +| getBudgets() | List | Retrieves the list of all budgets set | + +The `ListBudgetCommand`'s updated execution function now features an improved display that not only shows the budget, +spent amount, and remaining balance but also clearly indicates when the budget has been exceeded. If the expenses +surpass the budget, instead of showing a negative remaining balance, it displays "Exceeded", providing a straightforward +and immediate visual cue that the budget limits have been surpassed. + +The "Categories above budget" section offers a concise table summarizing which categories have gone over the budget and +by what amount, making it easy for users to identify areas of concern. + ## 5. Product scope diff --git a/docs/diagrams/sequenceDiagram_listBudget.png b/docs/diagrams/sequenceDiagram_listBudget.png new file mode 100644 index 0000000000000000000000000000000000000000..3f5d6e7411e8793e4c03f04145b6e5dd31ba8c1d GIT binary patch literal 50789 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 T=y&05)*Z5O{Icwef1Ud`L`2`O literal 0 HcmV?d00001 diff --git a/docs/diagrams/sequenceDiagram_setBudget.jpg b/docs/diagrams/sequenceDiagram_setBudget.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5df71ed486015549c2c8038a43aa8493876cda2b GIT binary patch literal 68606 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 Date: Sat, 13 Apr 2024 14:12:43 +0800 Subject: [PATCH 17/46] Revert "Add changes to developer guide for budget functions, added CommandCreator for list budget" --- docs/DeveloperGuide.md | 98 +++++++++++------- docs/diagrams/sequenceDiagram_listBudget.png | Bin 50789 -> 0 bytes docs/diagrams/sequenceDiagram_setBudget.jpg | Bin 68606 -> 0 bytes src/main/java/seedu/budgetbuddy/Parser.java | 5 +- .../ListBudgetCommandCreator.java | 23 ---- 5 files changed, 60 insertions(+), 66 deletions(-) delete mode 100644 docs/diagrams/sequenceDiagram_listBudget.png delete mode 100644 docs/diagrams/sequenceDiagram_setBudget.jpg delete mode 100644 src/main/java/seedu/budgetbuddy/commandcreator/ListBudgetCommandCreator.java diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index dbc6bceac4..1f849f154c 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -7,6 +7,48 @@ ## Design & implementation +### Budget Management + +#### Implementation +The Budget Management feature allows users to set financial limits for the various categories and monitor their spending. +This feature's objective is to give users the ability to stay within their financial goals and avoid overspending. + +This feature is orchestrated by `ListBudgetCommand` and `SetBudgetCommand`, which are initialised by the `Parser` +class. Below is a description of the key class attributes and methods involved in the budget setting and listing +process: + +##### Class Attributes for `SetBudgetCommand`: +| Class Attribute | Variable Type | Relevance | +|-----------------|---------------|---------------------------------------------------------------------| +| expenseList | ExpenseList | Object containing the list of expenses to check against set budgets | +| category | String | The category for which the budget is being set | +| budget | double | The budget amount to be set for the category | + +##### Class Attributes for `ListBudgetCommand`: +| Class Attribute | Variable Type | Relevance | +|-----------------|---------------|---------------------------------------------------------------------| +| expenseList | ExpenseList | Object containing the list of expenses to check against set budgets | + + +Upon the call of the `execute()` method in `BudgetBuddy` using `command.execute()`, `SetBudgetCommand` will update the +budget in `ExpenseList` using `setBudget`. Similarly, `ListBudgetCommand` will fetch and display all categories with +their budgets using `getBudgets`, and highlight those that are above the set budget. + +##### Key Methods used from `ExpenseList` +| Method | Return Type | Relevance | +|-----------------------------|---------------|--------------------------------------------------------------------| +| setBudget(category, budget) | void | Sets or updates the budget for a given category in the ExpenseList | +| getBudgets() | List | Retrieves the list of all budgets set | + +The `ListBudgetCommand`'s updated execution function now features an improved display that not only shows the budget, +spent amount, and remaining balance but also clearly indicates when the budget has been exceeded. If the expenses +surpass the budget, instead of showing a negative remaining balance, it displays "Exceeded", providing a straightforward +and immediate visual cue that the budget limits have been surpassed. + +The "Categories above budget" section offers a concise table summarizing which categories have gone over the budget and +by what amount, making it easy for users to identify areas of concern. + + #### Sequence diagrams ##### Setting a Budget @@ -637,23 +679,26 @@ this `AddExpenseCommand`, do refer to the `Implementation` section for `AddExpen ### Setting Budget Feature -The Budget Management feature allows users to set financial limits for the various categories and monitor their spending. -This feature's objective is to give users the ability to stay within their financial goals and avoid overspending. +The Set Budget feature allows users to allocate a specific budget to various categories. This feature is managed by the +SetBudgetCommand class, which is instantiated by the SetBudgetCommandCreator as a result of the Parser class +interpretation. Within the SetBudgetCommand object, the following variables are initialized: -This feature is orchestrated by `ListBudgetCommand` and `SetBudgetCommand`, which are initialised by the `Parser` -class. Below is a description of the key class attributes and methods involved in the budget setting and listing -process: +| Variable | Variable Type | Relevance | +|-------------|---------------|-------------------------------------------------------------------------| +| expenseList | ExpenseList | The ExpenseList object containing all the categories to set budgets for | +| category | String | The category for which the budget is to be set | +| budget | double | The financial limit allocated to the specified category | -##### Class Attributes for `SetBudgetCommand`: -| Class Attribute | Variable Type | Relevance | -|-----------------|---------------|---------------------------------------------------------------------| -| expenseList | ExpenseList | Object containing the list of expenses to check against set budgets | -| category | String | The category for which the budget is being set | -| budget | double | The budget amount to be set for the category | +When the execute() method is called via command.execute(), the SetBudgetCommand utilizes methods from the ExpenseList +class to apply the budget: -The UML Sequence diagram below illustrates the execution flow of the Set Budget Feature when a user inputs a valid +| Method | Return Type | Relevance | +|-------------|-------------|----------------------------------------------------------| +| expenseList | ExpenseList | Sets the budget for a specific category within the list | + +The UML Sequence diagram below illustrates the execution flow of the Set Budget Feature when a user inputs a valid command to set a budget: -![sequenceDiagram_setBudget.jpg](diagrams%2FsequenceDiagram_setBudget.jpg) +![SeqDiagramBudget.png](SeqDiagramBudget.png) The sequence of operations for an example input, `set budget c/Transport b/500`, is as follows: 1. BudgetBuddy receives the user input and utilizes the Parser to decipher it. @@ -664,33 +709,6 @@ The sequence of operations for an example input, `set budget c/Transport b/500`, 6. The ExpenseList updates or creates a budget allocation for the specified category with the provided amount. 7. A confirmation message is displayed in the console indicating the budget has been successfully set or updated. -##### Class Attributes for `ListBudgetCommand`: -| Class Attribute | Variable Type | Relevance | -|-----------------|---------------|---------------------------------------------------------------------| -| expenseList | ExpenseList | Object containing the list of expenses to check against set budgets | - -The UML Sequence diagram below illustrates the execution flow of the Set Budget Feature when a user inputs a valid -command to set a budget: -![sequenceDiagram_listBudget.png](diagrams%2FsequenceDiagram_listBudget.png) - -Upon the call of the `execute()` method in `BudgetBuddy` using `command.execute()`, `SetBudgetCommand` will update the -budget in `ExpenseList` using `setBudget`. Similarly, `ListBudgetCommand` will fetch and display all categories with -their budgets using `getBudgets`, and highlight those that are above the set budget. - -##### Key Methods used from `ExpenseList` -| Method | Return Type | Relevance | -|-----------------------------|---------------|--------------------------------------------------------------------| -| setBudget(category, budget) | void | Sets or updates the budget for a given category in the ExpenseList | -| getBudgets() | List | Retrieves the list of all budgets set | - -The `ListBudgetCommand`'s updated execution function now features an improved display that not only shows the budget, -spent amount, and remaining balance but also clearly indicates when the budget has been exceeded. If the expenses -surpass the budget, instead of showing a negative remaining balance, it displays "Exceeded", providing a straightforward -and immediate visual cue that the budget limits have been surpassed. - -The "Categories above budget" section offers a concise table summarizing which categories have gone over the budget and -by what amount, making it easy for users to identify areas of concern. - ## 5. Product scope diff --git a/docs/diagrams/sequenceDiagram_listBudget.png b/docs/diagrams/sequenceDiagram_listBudget.png deleted file mode 100644 index 3f5d6e7411e8793e4c03f04145b6e5dd31ba8c1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50789 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 T=y&05)*Z5O{Icwef1Ud`L`2`O diff --git a/docs/diagrams/sequenceDiagram_setBudget.jpg b/docs/diagrams/sequenceDiagram_setBudget.jpg deleted file mode 100644 index 5df71ed486015549c2c8038a43aa8493876cda2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68606 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 Date: Sat, 13 Apr 2024 14:38:13 +0800 Subject: [PATCH 18/46] Reset ExpenseList and SavingList File if corrupted --- src/main/java/seedu/budgetbuddy/Storage.java | 199 ++++++++++++++----- 1 file changed, 147 insertions(+), 52 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/Storage.java b/src/main/java/seedu/budgetbuddy/Storage.java index 36b90fff73..887ac087fa 100644 --- a/src/main/java/seedu/budgetbuddy/Storage.java +++ b/src/main/java/seedu/budgetbuddy/Storage.java @@ -46,25 +46,160 @@ private void ensureDirectoryExists() { } } - public List loadExpenses() throws FileNotFoundException { + /** + * Loads a list of expenses from a file. + * If an exception occurs during the loading process (e.g., if the file is corrupted), + * the expenses list file will be reset. + * + * @return A list of {@link Expense} objects loaded from the file. + * @throws IOException If an error occurs when accessing the file. + */ + public List loadExpenses() throws IOException { File file = new File(filePath); List expenses = new ArrayList<>(); Scanner scanner = new Scanner(file); - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - String[] parts = line.split("\\|"); - // Assuming the order is Date|Category|Amount|Description - LocalDate date = LocalDate.parse(parts[0].trim()); - String category = parts[1].trim(); - double amount = Double.parseDouble(parts[2].trim()); - String description = parts[3].trim(); - Expense expense = new Expense(date, category, amount, description); - expenses.add(expense); + try { + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + String[] parts = line.split("\\|"); + LocalDate date = LocalDate.parse(parts[0].trim()); + String category = parts[1].trim(); + double amount = Double.parseDouble(parts[2].trim()); + String description = parts[3].trim(); + Expense expense = new Expense(date, category, amount, description); + expenses.add(expense); + } + } catch (Exception e) { + LOGGER.log(Level.INFO, "Exception successfully caught. Error has been handled"); + System.out.println(e.getMessage()); + System.out.println("Your Expenses File is corrupted, resetting the file...."); + resetExpenseListFile(); + return expenses; + } finally { + scanner.close(); } - scanner.close(); return expenses; } + /** + * Saves a list of expenses to a file. + * If an IOException occurs, the expenses list file will be reset. + * + * @param expenses A list of {@link Expense} objects to save to the file. + * @throws IOException If an error occurs during writing to the file. + */ + public void saveExpenses(List expenses) throws IOException { + ensureDirectoryExists(); // Ensure directory and file exist before writing + FileWriter writer = null; + try { + writer = new FileWriter(filePath, false); + for (Expense expense : expenses) { + writer.write(String.format("%s | %s | %.2f | %s\n", + expense.getDateAdded(), expense.getCategory(), expense.getAmount(), expense.getDescription())); + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "IOException occurred while saving expenses. " + + "Resetting expense list file.", e); + resetExpenseListFile(); // Reset the expense list file if an exception occurs + throw e; // Re-throw the exception to indicate that saving was not successful + } finally { + if (writer != null) { + writer.close(); + } + } + } + + /** + * Resets the expense list file. If the file exists, it is deleted and a new empty file is created. + * + * @throws IOException If deleting the existing file or creating a new file fails. + */ + public void resetExpenseListFile() throws IOException { + File file = new File(filePath); + file.delete(); + file.createNewFile(); + FileWriter writer = new FileWriter(filePath, false); + writer.write(""); + writer.close(); + } + + /** + * Loads a list of savings from the specified file. + * If an exception occurs during the loading process (e.g., if the file is corrupted), + * the savings list file will be reset. + * + * @return A list of {@link Saving} objects representing the savings loaded from the file. + * @throws IOException If there is an issue with file access that prevents the method from reading the savings. + */ + public List loadSavings() throws IOException { + List savings = new ArrayList<>(); + File file = new File(filePath); + Scanner scanner = new Scanner(file); + try { + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + String[] parts = line.split("\\|"); + String category = parts[0].trim(); + double amount = Double.parseDouble(parts[1].trim()); + Saving saving = new Saving(category, amount); + savings.add(saving); + } + } catch (Exception e) { + LOGGER.log(Level.INFO, "Exception caught while loading savings. Resetting savings list file.", e); + System.out.println(e.getMessage()); + System.out.println("Your Savings File is corrupted, resetting the file...."); + resetSavingsListFile(); + return savings; + } finally { + scanner.close(); + } + return savings; + } + + /** + * Saves the list of savings to the specified file. + * If an IOException occurs, the savings list file will be reset. + * + * @param savings A list of {@link Saving} objects that represent the savings to save to the file. + * @throws IOException If an IOException occurs during file writing, indicating the savings could not be saved. + */ + public void saveSavings(List savings) throws IOException { + ensureDirectoryExists(); // Ensure directory and file exist before writing + FileWriter writer = null; + try { + writer = new FileWriter(filePath, false); + for (Saving saving : savings) { + writer.write(String.format("%s | %.2f\n", + saving.getCategory(), saving.getAmount())); + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "IOException occurred while saving savings. Resetting savings list file.", e); + resetSavingsListFile(); + throw e; + } finally { + if (writer != null) { + writer.close(); + } + } + } + + /** + * Resets the savings list file. If the file exists, it is deleted, and a new empty file is created. + * This method is typically called when the file is found to be corrupted or + * when an issue arises during file operations. + * + * @throws IOException If there is an issue with file access that prevents the method + * from deleting or creating the file. + */ + public void resetSavingsListFile() throws IOException { + File file = new File(filePath); + file.delete(); + file.createNewFile(); + FileWriter writer = new FileWriter(filePath, false); + writer.write(""); + writer.close(); + } + public void resetRecurringExpensesListFile() throws IOException { File file = new File(filePath); file.delete(); @@ -173,46 +308,6 @@ public void saveRecurringExpenses(RecurringExpenseLists recurringExpenseLists) } - public void saveExpenses(List expenses) throws IOException { - ensureDirectoryExists(); // Ensure directory and file exist before writing - FileWriter writer = new FileWriter(filePath, false); // Overwrite the file - for (Expense expense : expenses) { - writer.write(String.format("%s | %s | %.2f | %s\n", - expense.getDateAdded(), expense.getCategory(), expense.getAmount(), expense.getDescription())); - } - writer.close(); - } - - - - // Inside Storage.java - public List loadSavings() throws FileNotFoundException { - File file = new File(filePath); - List savings = new ArrayList<>(); - Scanner scanner = new Scanner(file); - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - String[] parts = line.split("\\|"); - // Assuming the order is Category|Amount - String category = parts[0].trim(); - double amount = Double.parseDouble(parts[1].trim()); - Saving saving = new Saving(category, amount); - savings.add(saving); - } - scanner.close(); - return savings; - } - - public void saveSavings(List savings) throws IOException { - ensureDirectoryExists(); // Ensure directory and file exist before writing - FileWriter writer = new FileWriter(filePath, false); // Overwrite the file - for (Saving saving : savings) { - writer.write(String.format("%s | %.2f\n", - saving.getCategory(), saving.getAmount())); - } - writer.close(); - } - /** * Saves the default currency to the specified file path. * From 581e65c38869b42c6350c102c528d03597536310 Mon Sep 17 00:00:00 2001 From: Dheekshitha2 Date: Sat, 13 Apr 2024 14:47:45 +0800 Subject: [PATCH 19/46] Add changes to DG and add command creator for list budget --- docs/DeveloperGuide.md | 131 ++++++------------ docs/diagrams/sequenceDiagram_listBudget.png | Bin 0 -> 50789 bytes docs/diagrams/sequenceDiagram_setBudget.jpg | Bin 0 -> 68606 bytes src/main/java/seedu/budgetbuddy/Parser.java | 10 +- .../budgetbuddy/command/SetBudgetCommand.java | 1 - .../ListBudgetCommandCreator.java | 23 +++ 6 files changed, 66 insertions(+), 99 deletions(-) create mode 100644 docs/diagrams/sequenceDiagram_listBudget.png create mode 100644 docs/diagrams/sequenceDiagram_setBudget.jpg create mode 100644 src/main/java/seedu/budgetbuddy/commandcreator/ListBudgetCommandCreator.java diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 1f849f154c..1f76b53c72 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -7,81 +7,6 @@ ## Design & implementation -### Budget Management - -#### Implementation -The Budget Management feature allows users to set financial limits for the various categories and monitor their spending. -This feature's objective is to give users the ability to stay within their financial goals and avoid overspending. - -This feature is orchestrated by `ListBudgetCommand` and `SetBudgetCommand`, which are initialised by the `Parser` -class. Below is a description of the key class attributes and methods involved in the budget setting and listing -process: - -##### Class Attributes for `SetBudgetCommand`: -| Class Attribute | Variable Type | Relevance | -|-----------------|---------------|---------------------------------------------------------------------| -| expenseList | ExpenseList | Object containing the list of expenses to check against set budgets | -| category | String | The category for which the budget is being set | -| budget | double | The budget amount to be set for the category | - -##### Class Attributes for `ListBudgetCommand`: -| Class Attribute | Variable Type | Relevance | -|-----------------|---------------|---------------------------------------------------------------------| -| expenseList | ExpenseList | Object containing the list of expenses to check against set budgets | - - -Upon the call of the `execute()` method in `BudgetBuddy` using `command.execute()`, `SetBudgetCommand` will update the -budget in `ExpenseList` using `setBudget`. Similarly, `ListBudgetCommand` will fetch and display all categories with -their budgets using `getBudgets`, and highlight those that are above the set budget. - -##### Key Methods used from `ExpenseList` -| Method | Return Type | Relevance | -|-----------------------------|---------------|--------------------------------------------------------------------| -| setBudget(category, budget) | void | Sets or updates the budget for a given category in the ExpenseList | -| getBudgets() | List | Retrieves the list of all budgets set | - -The `ListBudgetCommand`'s updated execution function now features an improved display that not only shows the budget, -spent amount, and remaining balance but also clearly indicates when the budget has been exceeded. If the expenses -surpass the budget, instead of showing a negative remaining balance, it displays "Exceeded", providing a straightforward -and immediate visual cue that the budget limits have been surpassed. - -The "Categories above budget" section offers a concise table summarizing which categories have gone over the budget and -by what amount, making it easy for users to identify areas of concern. - - -#### Sequence diagrams - -##### Setting a Budget -The following UML Sequence diagram shows how `SetBudgetCommand` works when a user sets a budget for a category in the -following format: `set budget c/ b/` - -SetBSD.png - - -##### Printing Budgets -The following UML Sequence diagram shows how `ListBudgetCommand` works when a user checks the budget status with the -command: `print budget` - -ListBSD2.png - -#### Class diagram -The class diagram below outlines the relationships between the classes involved in the Budget Management feature: - -ClassDiagram2.png - -#### Activity diagram - -The activity diagram provides an overview of the Budget Management feature's workflow: - -ActivityDiagram.png - -#### Examples of usage - -1. The user types `set budget c/food b/500` to set a budget of $500 for the food category. The Parser class creates a -`SetBudgetCommand` object which calls `setBudget()` on the `ExpenseList` object. -2. To view budgets, the user enters `print budget`. The Parser class creates a `ListBudgetCommand` object. This command -retrieves the budgets using `getBudgets()` and displays them, also indicating any categories that are over budget. - ## 1. Introduction Welcome to the Developer Guide for BudgetBuddy! This guide has been created to help you current and future developers of Budget understand how BudgetBuddy works and aid developers in easily adding new features, @@ -679,26 +604,23 @@ this `AddExpenseCommand`, do refer to the `Implementation` section for `AddExpen ### Setting Budget Feature -The Set Budget feature allows users to allocate a specific budget to various categories. This feature is managed by the -SetBudgetCommand class, which is instantiated by the SetBudgetCommandCreator as a result of the Parser class -interpretation. Within the SetBudgetCommand object, the following variables are initialized: - -| Variable | Variable Type | Relevance | -|-------------|---------------|-------------------------------------------------------------------------| -| expenseList | ExpenseList | The ExpenseList object containing all the categories to set budgets for | -| category | String | The category for which the budget is to be set | -| budget | double | The financial limit allocated to the specified category | +The Budget Management feature allows users to set financial limits for the various categories and monitor their spending. +This feature's objective is to give users the ability to stay within their financial goals and avoid overspending. -When the execute() method is called via command.execute(), the SetBudgetCommand utilizes methods from the ExpenseList -class to apply the budget: +This feature is orchestrated by `ListBudgetCommand` and `SetBudgetCommand`, which are initialised by the `Parser` +class. Below is a description of the key class attributes and methods involved in the budget setting and listing +process: -| Method | Return Type | Relevance | -|-------------|-------------|----------------------------------------------------------| -| expenseList | ExpenseList | Sets the budget for a specific category within the list | +##### Class Attributes for `SetBudgetCommand`: +| Class Attribute | Variable Type | Relevance | +|-----------------|---------------|---------------------------------------------------------------------| +| expenseList | ExpenseList | Object containing the list of expenses to check against set budgets | +| category | String | The category for which the budget is being set | +| budget | double | The budget amount to be set for the category | -The UML Sequence diagram below illustrates the execution flow of the Set Budget Feature when a user inputs a valid +The UML Sequence diagram below illustrates the execution flow of the Set Budget Feature when a user inputs a valid command to set a budget: -![SeqDiagramBudget.png](SeqDiagramBudget.png) +![sequenceDiagram_setBudget.jpg](diagrams/sequenceDiagram_setBudget.jpg) The sequence of operations for an example input, `set budget c/Transport b/500`, is as follows: 1. BudgetBuddy receives the user input and utilizes the Parser to decipher it. @@ -709,6 +631,33 @@ The sequence of operations for an example input, `set budget c/Transport b/500`, 6. The ExpenseList updates or creates a budget allocation for the specified category with the provided amount. 7. A confirmation message is displayed in the console indicating the budget has been successfully set or updated. +##### Class Attributes for `ListBudgetCommand`: +| Class Attribute | Variable Type | Relevance | +|-----------------|---------------|---------------------------------------------------------------------| +| expenseList | ExpenseList | Object containing the list of expenses to check against set budgets | + +The UML Sequence diagram below illustrates the execution flow of the Set Budget Feature when a user inputs a valid +command to list budgets: +![sequenceDiagram_listBudget.png](diagrams/sequenceDiagram_listBudget.png) + +Upon the call of the `execute()` method in `BudgetBuddy` using `command.execute()`, `SetBudgetCommand` will update the +budget in `ExpenseList` using `setBudget`. Similarly, `ListBudgetCommand` will fetch and display all categories with +their budgets using `getBudgets`, and highlight those that are above the set budget. + +##### Key Methods used from `ExpenseList` +| Method | Return Type | Relevance | +|-----------------------------|---------------|--------------------------------------------------------------------| +| setBudget(category, budget) | void | Sets or updates the budget for a given category in the ExpenseList | +| getBudgets() | List | Retrieves the list of all budgets set | + +The `ListBudgetCommand`'s updated execution function now features an improved display that not only shows the budget, +spent amount, and remaining balance but also clearly indicates when the budget has been exceeded. If the expenses +surpass the budget, instead of showing a negative remaining balance, it displays "Exceeded", providing a straightforward +and immediate visual cue that the budget limits have been surpassed. + +The "Categories above budget" section offers a concise table summarizing which categories have gone over the budget and +by what amount, making it easy for users to identify areas of concern. + ## 5. Product scope diff --git a/docs/diagrams/sequenceDiagram_listBudget.png b/docs/diagrams/sequenceDiagram_listBudget.png new file mode 100644 index 0000000000000000000000000000000000000000..3f5d6e7411e8793e4c03f04145b6e5dd31ba8c1d GIT binary patch literal 50789 zcmb?@c|6o@+qaghT|y#4g@_PYijcBoC&t)@tTDF4*q2taUzP|-b_O%q#?GZINwSV% z7|N7o#*Boq4C6h=b-(v>-|zE0?;r2`^!Ze$pWk{e$MHRm7svyGS@1$c5ePUQT%r=aPTQt5I$ZyJKSf(!2~& z`mTO^Fl}Zi=CMNk{+UKOqFZzR4An3en5Z6lXH7Y@w zF=D0e=2lu-QL&~favXg15EwR5)_-f9wptwFxxl>Cf_W(zT>)_Ky{_vJU<0k9W0JJI zQqz>?QB)eNU*@aTUmsQ!{?#9LODSq81+wIDx!~8RDe1FdQrLJwq^V-92 zx2^@Ry7~?qC}u zNB9!Zy25X2YwJbByGyTB=j?nbx2XJJ<2R@|o8GovsCen`aSRU1<{1>a7P8b*XAm66 zEB|?9WaKrvb?YvnOGTwMKZwl!7K7h(kof_I$m*VjLer)#2vu9kamN+7t4VaAHobN^on%m z*LSpS>kchcqHOxvm@hJb`K=%$YyaV(wZsqZwv87V*B&I`YMqCRjTGyq!<)|DcvNs> z``5=7)cBx8=vTGfP~YjW^&l8NQVR3xh*iYST8osYk-T5ciJUN622P|l)MD1g^wIn- zV`;b9i1~oWw^P%j*$GK%Ya^z8%|R<3RYKw-CTUVIcvsw6B0?v@NOiNLdAW-ZbEdD# zx!0p-wq?ZiYn$zK&>a6t`(eTN3Cyv2_pG`rv#SJ!DCRWdz2)BIK z{#e?U*10PdZ|!36kv0F(_ZQrmUWCSR`wwXiBHDssenh$O9kQL`*-=TfwcSjF{-;4% zDU0`ip(0q@+7IyshVj-r`>*&cyWM<{AFm**I34Osyvo>w-=H>eUr4yDitEyzH zKb}+`!yPK~kKLWI?b&A%!74hJ9blUhyOS2m*qp=c9D}9W1^s*#pICjxs^$|WAh*q4 zE)MTBsM!>0!qI8+!2t&g@U(GJx#YX~GhNZrrRDnr#`Y$rt%y@A`dNeT9NzxqjUT6m z+ae;egom0xrrn4eoyJUfP1IkJZdtuo?X1%+;x%$)>8tXRN4jzlJyoF2d;|q+8z~H8z!3aGHP+Q)s>{`h!$1)V)g8k!vgPj4>0G95~^80 zE;TL9B~+0?shh?`)QveDrz_(8a?5$ysq8U_1w#is8W)OOnkbm+oS&850@dlCJmE#zuE71Mc_d0N+4Lucc9yK@70E6Vf^ZK9uHpk1qV zQf1XRtJ#D@r{Kyl%;6XyNq=jy8e5<)Nz*6;`}(ssI_-X*X~4F z4Nmq{NMIXAyhC6LEw6WJ<&Vd=O_=xr-EICa@Sz!aF6!j?nSjcy=+-cLrifnJ*e(|J zGMV*G)XCZ$;()qUqQ#d?`CiqcBtztwyd?Ifar{9nk1@xsTCT539zhS$6W zB_9AY4>MwZN8evh4rHAmCPD~Ld#^lr;}Z#Usij;5_QAu_W-)L1L*!u9d?kP1QUu*S z<>#ZyvMlQe(VWmn#9c35FFx1J)r~mD?glZj4-2&;I5pAhaw1yWGnE>q=7_p=1k;|n zrGEg7knJ%VV&9e3%X zTB{acOtks2S7c@crQr@8yRPv$@UB03+|Dwc^vf1v2g-3LVwY|gGP9pWJ$P_mbW+hv zmEc7%bKZxA^7r`7M2jZ#=ydMBP@;`F_QjpOwy3_o6tUYxIfFHd*fI?nEI*`*4cAmE zb-<~A&N=l-P9{%5Vk99l{O0cqGBY#5yF2R>Dl&O%#nMrH(lCdDTKBk(B%Y(%dl+Qt zdSz3`r^N78A@p$;xp^Eqrxc02D8q4UanLa!nmvH<{KvqW?bIc$t@R~4bcETfOT+M+ z$e?$BeDMn%+}AGo=B>}jzI8Bab)KKDiML$%nWQaH>CG0sqUnCw-@qt7hBWx5jj@Kt z9O^wP`sTiLeY&)rSJXJXtm4Zb+&1@7jU@4`m%svWpPOABHmYN-MK&fCZ4PP+%D2YU zYbOfO9Bgf9a@Y0sY8LSqNMwqOhgN(((>#28w{ZbmmY#9lC$F@$v~u_)UzgysHxZ0Yh1^_c z=;D@x>r|ezNtK9)vfItt!n~g=(oL~9JVGQc=WUX91$Q^P{p)Q8*NX}%=JQHci(9SD zz&77d8|{2WrN1@Q>sAV5LxjRT7gr>^r|z*TxK&Wzel}1fIC-=D$+Pd&4-O%2yUFWd*dY5ABcZ8=hgV^l#t94^0mbNQ~CthEw>2Bx)=Ec#woV0(lM>J=(F>j#Z z`Rin)bn~yZG-YsY=mDhKWX(K$7^ZRY#2LapK&cFWjWjHOU-q}Z9t0ugrHIE7vJE!#0ecJdUNzN4U;el$+x;utZrKc_JaxA~`o5l`Zr z9wx4dh{)tYEy(q;nEV~R#Cyr07fk$8J6=k);xoNQOV8YhP8zuzC(Ie0^b&k)W)U)g zY!dSzCv4P~g**dEbbl$3c>UL32PmJhySi8Fc@LQURPs;fSr$Dzq+q&kLQs8~3gjVEBPSrXh+>as^K@Z57puX=w}6k14_;nVu?aOhoDE9dT7I+2MvJ*Pq;b zFrs?Spd6SuLNs!?cRWlhpzNd$j*cZwd%4DzP`Eiu|S-Q zi)#v`03O>6^PO3>^5@!-4tCG7Ek)Noch(zzA$a{bBC%m4n2H= z=YFEkRxG;K+Tq8K2S>&QJ-# zs2pwt(4p^pl%Q8kOiZ)PDM%~YI(sGI+>IfRmbFn^ZWh;&7vWdnbsaCK92dRMt^9R> z&ExkCNDy!qeRjKBxUPO@XJ;1x%ep=Y+|3McDN@7q<)`~B@18-A%11Ujx|r9x+)_Aih(@^-$>W_e?x<3RL;$0%aR zs3!dL480Etf@)KXO-rpV0L>rdAw}y;15wQyk*r`hOifV|#)a0l&0ilU`cEyR(C;-%sF!ThYyC7X3Y#;+(E&#YJD!dNlh zVJp03dwWiet)-`!FPl0>Opu@|_WBHuaI!jf#koB?aqMK-5;9?vSF3WqvgQ624w2dG zPw8!GI=w~H_qnqYG#Ny5q@zjhd71q`?p`n_k6xoHokF$~-vvyE;odH860_ypl5gy+ z4paVkZuorXaD?!%Z@&u8NzlZE7)cGu)vzj3Tbv*Bi>u%M-P;Ger%U3sU^8{@XGjc6 z`wTOww=_b&Xs82){Zd&SxHC2Oy+)cp=tmN5*#_1@@`|ug38B?c3{ISt?U?kR@SOc} zt-q!>uVBjD+VdwX_S^f9C#&f-v-zC&VK*0MOhw1Stx(M8zw!NgW44pqPEKvJ$H*h^ zTRkzMnlRE<7^paQ|3Jt^hZGQuL_amY z#s!#95CK4`>1D=i6OK)3KSxZBaB+=u`y(?1r&{JdEW=2FhBSTfFi00B!V9Gca>|v6bRs+H^z&U-f9yXd4Yd zk){U7z$dMiGN&fI+dRJlpwg7+YBv~;^ehXK*yjr{H9kzY+pHqzTPrW7{FXN7PYZFS z@P)DRrC0D5(OzQX#QeTg-IfQ;IV~b3wf{z<2EeMBr z_~K5OIDU;xn2Wj7=4^FX$%VvI_H)R)w#M&@xNzqdyN`rz#M%w7LBheKWbWE|C$aJn zi^0Umh`>SFji_iVfI-_Yf`G2AFz-O3^7og#A)wP1e`SbuzzL7Hui2AuDWcJ7kRyHIo><)&e`EIsI>25WjCJF5~}i<&F{_ z!i<|6A?{URl>7#B ze?*o&$)}VYKLk5JuVL*O;+hS&(iNL`m@?`u4Merj@LfMgdYWbs0fB3~xlsb}B7-a! zdeisQId(U-6#`FvW}%c6YVbNDu_ZFI!0PwlD6;8@-|+CJDzSN!oaSKiZK z(zqzajqmRL)+XQXHtjQ7fedLJ<=9=nUSE#yt}67+|5hm^7*4eLU8>TlGOKGXI0th} z^v%-mFUvotr#U_M`LixP%%m?y5;OMU(rJzE-_mW{Lkwx9G>Hp~2}B44qOg#=v<$*Y z=QeF!2Un%7>_M3k{<+EPTVC!;2@L2XTb)B|xL;c+3HzDkp$V_13eRdHvJ6!<9map4 z#zS|$Bqz&u?6I-jG5}8e~P8PE`|JjZ~s(eSh_X; z8N3MFxOM=|DIBrpLO6S@_Y_&LqUkpBYsCUt!+2%j#nY2Tq@{u~QdvhA$eMVuecF0* z#Cqx~Rl_tswL$-pduN%~R_@SMRHnmwWDQb|v68b} zWQZQIPCkrVb$8pBPW(Z;vBQ5e@V$!8LwX^`^F4u=qK(C3X$c8Zel-+?q84{WLwOpB z){iN9Du6MtNgBmdC10fpT>ix68Nn~)CtH-Fw0`Ie>^<3Qd?|cgnSSHd`)+Q;lXCnS zrG41wf&@(;*R}!8TEkN>SQx3Es+g=PsN?L ze+Wt*J6Rn0d+lY6;XC=}{9Sp$_3Y7Q%i7RwvUO_c(WXE)sbYuWqb*dLSIwXnO;IDj zTRskx9}A0Ev!rXI=0Dsb51Z&)p_Rhj2siK%a5#K1d@1}ev5Qh1rb*X-sK(U?U4b&E zrD%P5!zq88o~Y^i&{F{_ccmQI$T_I`<&RsMl0L*fC*@9+GSqab z4flHZmZZtdhlq0l(?Z#aNS6!_uC11#%Hds=q3c_$1K#StCT}I)*&>cq8g**~ESgbH z?95)yKx+G~h7`U|6@&cN>>kE!?F>|1J|r@Xm>lpis||*bjgMk&a3=;C7ssj9;|YR` zZ&Ny6PTaNM$va~p#58^H8Pe}M&Q9C?tKrKtv_d={Zr4AHV^y5I>SqC+Y>d(4wj2k( z_~=`XbEvJ#s)o;}$}+Qa4CfInrfUj>3{w{y(c6uDAp`1%gYL+`yoZHiW7h8ErQC&` zAW>&P#_XrTg*Q@Oa&I^ct-7gyachqR)_NhhWnmCE0s`{ND_dAxN}E`gHKPZ8fu|hi zN8~_t*24PzcE3ip`YH_$GzLiSkbSOY*NEBY9k-^WGENRy1E)LBmdFDLzn=iWPN>2-&& zlBaW4BgPno8>!-?j6Fty4NP{GQil{to zGio!?{2_tA-OD7_NvU;0^cmec^ z04FbA4Vd(aGLSmBP^Y28q9&P>Kta0YEoIJ@Eu|!XWo#l#a$4=$@#uD*H5kOFn>X9E zKjT{W)Z-CW0}-{$f(3XxmF zDXlH~#RR!U`UafY{c3+o4Lh+OtFOqhdkD3VORz&)j%zZ|rUqxMC)~XP%XiC#f zm@hEpK9)dDCH*j+C>(g3^d&&|UFn%WIUi z5*b7Vi|@DCaWAyp&GfK77jcjQ`$f&{1a)Lm{`1#T_*ED*+ZR=Cuf zoDeJ&m$1IY5HEd~d0+QtZIS+H#qPRXAUldu9+>)`&Fev}!Mh!k?hBqdqjAbtdN^&& z-{trGut5Gmm+6$R+!9fm8R)FyI7d}3^!@rR6fsq*;rsp!Olivy>HiXc_8!OWo}>H+ zQpcd7jXkd^OWI~AidZ(39DJ+$JT?!zR0*eSC5F6+>o~%p!)=CiAy+lP>30JDL>LdL zU*J?a+K;I9A~cL-!$oYi1J19twIMMl-yq@Zzk8)8v|mj2Br-?^dfefLZ;-8}^M)<( z>BSb!>%dA8ETH25bh+b}0)sSjg z3#f|7NqmfCb$@h|Hmr)AzS5^hchT#Hz$PUsiy4jIpdU6*xn% zo+`gfcvY>`kjsTjWTq#LfD-RLHR#!XKlUng-LBcG%F7hnIN)_QDV!RBwf?Zz&E(()4G#^r&l_UD*;q7Wl84>X- zq`=BjNfaAkrTB-uU09A^IJ<%!*G_`-?P+H$k4Zd)aCM0F0HJxE2NA^B!O)< zaeS}KTUzuO(_ol};6TPYN(EX&$H>98-eNvQc;0qAH(s@I!0eHs8ckQ6WWa6jw@k!Y zVecW5l1UCnmKRPoC*N0++T!d|N+9`giRh;~aqXb(pLUbeTrIL~NIc(@3zQC#uD>J3 zDq|MV@VA?ZYr1h_>P5=24F71k@`UNeTmGqL*wxyc#vQ%X0h6cQgRS{QqlcM!_K2BM z#CO9lA7`+gO>dvzj#lHp9~H={H6rI(b*qY`$+6bj=Z^V3q6pfqjBE|cZcZF@W7~SW z5OCY`xtP}aMsgZ7AgHz#Au4BhCthlt{Y(?bkM@p;Nd(!b=#bkqHawSTeYLW9NBd}a zttXeFm#5L1Z*S3Yxfa{&9yvox^$9`v#GTrkgJvU+`+sXsI+l9vN2aC2&BZF;9S_IC zN7sjq+PILOq+Q8J(MJil1|1cY%t?Xh?!KMw5X!YJR%42zB=p?YTlo04Cvl+(h3DN$ zkeI5Md2kzdDtOYOc4BQ}QOpPB8z%V-byhg=inv^cn&QBdhLrn*k=UN7DyP!$MXNj? zc~**8#!zC8EInf&-J+L2G(j>(xC>SAMCuKKBk$*EGa_lR^&1s^QdP<19>^?MIDdqY zN82s9ZSDINF(MU;{I?)js7M_3PrCF8;z0X$e*~j?vz;yczVuDVop&t@UrUqar+26U zlD!2qMgXA3@O2wX`}+n~+_w3QJR5fa|M)Y>|XHOXv!B`d$<3> zD^@c5GWoOD4!J{r8mb~*LYe2C8VRuE&OpWU4!$U$KDxYII@hyi@wDVp60JBU=9qGv z6fc01Zt$&eUF5=kE6aA~j1= zd^>Y-@5;I!Q>kTZuwQwcl26)*Ftkg_%$em_S_97mXKnf0vQ!!b8l2 z?yZX;fmjd)N%zNEiqeObx8EV$w8H9z*5w)@eybq-WWccL_&2+&7l zG$y)4F1*nn_0;oA`0m9qkCqBf{R=TXNU$(aGo0MAb=}4O(QJF6Vp^8co0*W{)0jb| zT^2DLxs)umRqNdtdsdEn?)Bqs_B9LS(h5kpc-~W=TT!wbkTGs!MX{=e3G(lpaZ}Q@ zMIOrFwSh*gTiNk1L4-8WL*_#o(PseoPRJ$3r0FGkcIU1*VjTv(UnXEPbG{lO$_EVg z^LGowzfdhuRzATtHv-E!cixtE)#sp0Yu=`6++z*yGpby$y4%gELMn!?>yA}^vh%IW z*K=~vuxdPiume=6{}@fT!;-DX5WCPW%0BhIf5!>(u_7J;1;BbTRK-fcHl+dvx3 zND0_L>$woL3qnI|y+@ z*pm40E?Yjh#BzLt$;4Hu5VWX~FLC$s+hU#2i#q9$CrZKl5#4 zqCnkiL3u%ncP*|4&%++JR4X`ta8!hQHSisWXfP#LVBJ*m;vh^_-h81r<&MD}(T2t` zzX>RJd7}l^M_n|S*GM!3kMrBVI2VasR@dRhp1((z&1_4!5U#tQT#q1?7UMIYH0GCZ zLiwZo97y$Uqyn>mbBF*#?r|hGm(w$SG3k9ES9$`0RJ3F1DO1{aT*PTLdyp)GxKQrw zBWGk_t+TH)SNun2vElZsUpfIv)8?thLm2bqTlA-+O_+G8lc^&kFQTXpBn=gDk!!X5 zeox9`&wD-~q#8fEql0=^PgdZ9O}f(IboVx6hf5wxCd5(I^5s`7gD+we9CeFI{9}?^ zkcFlG!Qfd!)ZdpNZc>sb!bX8^(?%o;;(} zFr;qA?fO~v@IsVX0B8So;)xLBmEnC`siuaNhtE-}m2M2T8==#%?OO4d-NLO-652=A z4MoR3>$_Vb?v*$F3E%#tLd$ImgD0xX)CZAR3Y*H2_ll3-4lv23!g+LkN^)lN-NbX> zJ&@W-OfEs9WpSBp;iu%{y0Gg8hi@C0l3}9hTj~S*1|#asYrc@s<;^F*e12JH-rU$! zd`J$aW#?CCF@ZH0_8A^+MQQujsGfEdZ{({GJW@wEzD7qWpKko+J8_YFQUMq3k~-&w zC^nSrCg)kuqe1uEN>m&_6Bd;^;`@>G^h3@qQ^`}XdU)1C_k@Y8KK(fri*SeC2J4Loam)gsV+qO282=jVvur_3v?KQ3If`-oK6jo>nrL?el$+qRarB6ene?WG4F=bXIS z7*eY7q^NL?9jovxS&+f$t7t&*#M(Jyn9w@*Ipo$`kO1&D#K&-FQzqr>05SVq(DcIx` zD7q;O3RkeB%fu@bF4wfIwqeTBrd81V1x*}C5^C-u(Zjk%l|V4PXVl*yZeK*o((PJ6 zBRxp$61&zfKGefY@o0!7L`O%2C})6xM)=V4;m^b_=k3_7nC&;3J{-?hkPrW=WLT<| zLNgJWN&N(QYLIw9{H!5hB|c7gqV1-1f9;x@L;n?j2q!Mv9!w^abj7K_kG7x4hCUXK z&h6UbN*uK*1Ng)Pey78>Rx9OA%p^K@x2Ds6iLqMoB@X#{1fR5qyoZF@dfvReS)@?v z1qfhW8t05%15=BfZ|ZWgCJqU6CJwO#X+dURoo0tr;F=n-e<7`&Q$I=83xZ;{!t(cs zNzKz`R!AJVEm^iKUBksQh zdo;j6<|!N-2`r}i0f0iHHJaKU84)YAoi6MWf@E7`8zC*$o)5*?-({NX6hvCT$`}>8 z(b!bzZ?Vn#mC4|}tH2?2_q2RWu@-bqzaC#DCLBBpqqvu39~9X)()u)64UW5mzOdT% z=!%Zn@w^vpq%?va0|s01p6f0HeG8n zxo?9bASXbCpqfbI`rny2E|$BZi}e?o34tFo7U^ss(qte>HXQ<^YA_#S)LN|7OhS(I z#8HY6l5Q6?aG9j~S&W=baAs*J# zj!`K;QW>>w1exhV9SZ)_2G78=9Yf><>;x#!as&q!u#^P%Py ztGuYlGGivlmttlmKqe}!zV~YoqN*WGVVbt-P&-TFeKTSgmS8<8af6vK%ha+6h%k{D z3ogu?y31q(j^QN5buOB8u}ScY(9&W632WC(#A`95=5^eMTnc*Uo$-1Qj*TL^mxd=< z%;{dLXg+ZF%=*NB;*|F;*&-mX9J@;^qWfUk|omRW-`$&F`~{mVUXnW8~L zJ4V98<@$tk|J;}<*9F=yMyW1ytnLsAbZ(ij(|`_ zBVkh%ZQP@q&41|>!ui!kJz%naDa!JK8>;R2(Y21YnCnC*?>lg4O!z36V2_=K4a{0H zK?#Gj9-LxVR0x>rn4PL`evsq0BbcNQZygptVNDSck+tA7i+*g$vFIuhpM@JTuRwVq z2sSfpEwo2*ha>ayKIp%`+CJ$wY%r_Xwi%DBy! zdWyJPhkyzVuoOqXyq5WR&ZmQY7O=$D0MX`;x{zGzN?~CktrnYZ^C&vwhHnv$%Tt|> zdvE_y-_kMzSJ*(i{+0Z-*zi}xYQA6)jOE=E0Z%j%S%v;9M>zn6t5w&&jy8=?B$40~ z7GXC0DzvKjzoo)bH?-x*DaeWI)w9ON9E2=ViycgO)t(o$f@5Upi z>Yt{N1}249Ay3xn(<$pL;e>?1tIK-$CnIP{M^Tw%ePOKu{BOYKqBR?j`A>%hEVX@c zQ?tZ)WUL?6x#~A>%poMK#oHNA5YhS*oI7-ce*5ymGP4BjR;(MGnx38oh%a@oZ|W2Z z3FvPp`=4KP?;X=&GECTOFrkKV9++_#S_CcuTI5IkAn$huidpemT2{Wj2=55r{QYyP zc*75cdGu44?)pSr>##BDrO6;z>3wS~rec3GgTc!SAVF^JS}0W~p9q~`0;1eF-TtrcFPZ8jUkxjHs=JEcN` z0gP={?OV7n%j7l#*0Ms#hU{7kzWeOk?5+#!*psp(cL;I}qQy~qcp zI~PDtUR8CbZqDWOi<94=yW;uMUw7PXrA{lM<~{&QoAgrKcCOV~VJ$1I#R@@X?r4L` z{_6hX52}I*V_DsX4#KselT^To)xn|e{%Kvw=kZ>>K-+tJtn{Ud?xK{;Qzu2Qsev=+5zPR%JWlPYau-3iaZpzz$=%f-#%*H0vW3u3wGFPQ`bPHJM zQxUAE>xy!huN7wU>ZMDqsdnZ&;~qWWXc90TE+aA32st{Fps4%>q{i>NyE#A74jU;k z!I*b4=u6(_xj2!xn=5k@oEF&y zPQTB2S$Die#vf*qBcX5p&p!6&5Gwsi^p~bFX8(ZI*!cFzy8s@#JYY5iFDicdbgloU z;~vTH{0(w>bu;RgzuzFo6}X2~dB_Ox0^@OIKVEdI%`;tr*sDh2xeJ<(h{+Vt^MfAlXb<4VX08z%n{oU%~_%L~o zf5h^uw)t*c2`uTjbn}3@s4AsqST@*PY#vlRtA~fGS8%o=6=7$Xb_>v)&=#zTOg=;S zfE|uU=S?0)UAWw?F)#Aet9s){PTL#H3c2hGHpq)sk@wfRZ3Ej!c}zltI7JOTM(qk! z90No=#`Dkg_=P%%`r{Y+0CN6DsR}OGd&ucWxB;-&!5(g#{3tLG2lQX+@TI z>-ZvIt70J2fM7api`&kHI**Qy2InNd7@JU|sXsfEVOi}mUN;07{eiH2)7z%rg_otJ z>sa-*+Wmo)!sY85H^JzUtk1HQ55M0wwX__Ex5=2iCq%2*EmRncx8~j*I zYuw)!mu02uweIg8c&F!>%I%b1e@&~~A^*@T={GqYS+z;TGsb{(pg77gc+XX6dN(zY zkY$T7O7&NzUNTb*#=??Z4&x9CS*(mY3krx0fb`I3YNYZL;TeXri)aY~bb&9+-Gbik ziF+qMc5+YecnSC3p4V2BWikSBg%qX-VsbH)CT{PY!}6kxz&jBLDgZ6J_))MN;8TG_ z)+NrpU*46qy18Els!C?lLEGxpm!F|G2V}l250(xgXqY-4g@> zl@JhTr7;-*Be)4;2O*%fD*Mx6n#u7mOt*!Li;L?U7{pV~bZ;yZ`|5p&UjP%p%^YR3 zfB;8ZU{78g=gvGV5cro3Aokm)KU7|7uDZ?eI+ zk2!T2fQM8CCYTWa1^+NbWLa5X>SfbrslhceuHOs-$pE#d`tha1%-I1i8yla?a>(({ z9uqZu<9hP?H-y0B{;|)PClIFw=e+*8cPlOFLo1Ou3#*96QWg zaMN#2sGvdF|_%GCP&20%Rd0;tE@ zAypxuyf)#lX;v)^Pi9JC`0cVTX(e2rIkK`vMo%dBN)Bc}aQ3Mici{shZkC4p>2!Bg zLlfX*;5bK_vXdG~CDEZd_ z0>b1%pd&>(0{~0)UHa%6tj_0IW0GQT*2?5_gtcJ^{uAIJ3&kwZ?~z1D30y2J$Nm5kwp;BJz;Alo*662`xSEj{^159| zK9QKTY=O{U?U$VA2Xd!g+hwVQ_@~$d^SH3KnF-h0iZU_bxHQicxyXJ&N9?$x`*GpF zQ*y?_gA;au%dOj80)#BkJ&o_yjI@7F`u4AFg?oN@ezY&rbf(iN`o*`a`C9S6!LhB? zg}%t+_YBVAj3~A9OTWHH=u+6FT|cv@Jv<`nPd~o#={gIJ?EwCp zx5Arby>P$;*Q>S%JXesO!I>S{Vk!%N3_uUrH|(;f1dTd2Ge zZIc!aqd&mJqe=TsywmqG__$6csWs$#xz>i6ySlvgHUls(vzS3TW61&6ncqf>5@;GE zUJr-Y32)Sw%ob)IV2rIPm;8LFy7BG63ZRl==_9we7n`V!W!ZIBo>20FE;aObkLc8? zF58hqoF`+sr4@{BEOZ4W^2Upqi)=+CpuGwyM*Q`>77p>mCX_D0wgGRlp72aXJ;JtfJ z@A_Qzh!_Yj-03x<=g{t`iS*Z~POih`&6pY{dRx9{{!Fp`YM75C4Gp-Um*Tg#>D$1O zy6wVu{mAW|C`UR|i{(K-w9uq^C)G}fww(ZEntz)`(C17P%70NNF9peIbaQa3eK?vR zfo^s%db4^5ouX9dfVlW@NJn%$Wj{nD40Ku_lc@R@VDGMazo&W1YHffZN;z6Z)mV6L zi6(shG5))xviL*$^D*LQX8=+29CN&L#(V*F+q-a3NCa>9O5eDT1$Li&lD^Wfw!}&} z2MqN!?4aW`kQ*)rjrK~nEv`i;Fug-91YDoFXT5de3eplMRF(t_P2}xGWc?n@0=uTj zN<*J7KiGXVLr;rm;cP(KMK~-j81>lZb8Mnlf zye58@#~)}@AxjzHC8kwla+|(2T8D$d&jMsXf~qXbH+Lftl4|Jy#i~+fvr$~h;8m65 zDDi&XmrQwORe#Vft*)(h$B)~jhh0UnT)b0lXThism`!*YJNbsI%0zk7Gltd&xvzjy z`M{+w)48ncP?_`rmSb50Y{sk{B6mmXe+Yyu+V6^6=2@8m%X>G0`IJjh)L-#{f~{Is zHfOt5UTbLEoxty&Lx&LWE0yj5$2U~~<500K(>|~o>iO&JG!r|Tx9wvQPUjFtzAC{- z!Z%DQM)QN&V6OKn7y~r=_(S@7bP^B+_P#AZCS8?>7x4qJWUJRk zttWg|KZXIsGoc*L$ivByPQDY!8O&EOyu?}yti=Qn9y*0D$J&kkXiEMK0D!L+>*~H2 zw-T>1#eP$O_kIit{MuB+ZdeG^khL(<5>T`$5yeoHqd`sX@q^Lf0if@V>+wJmh1)E7vErC; zqiDQo7ZUs9-LsQG(h>TepD8uLG=)$@fTp%GN3-_s6i{nKO94zPibKR`yB0+xc8b`^59jMpx)w8%oepASkP*32`Q zB8Wxc6BMFz*Hz2TyxjKQ`~s-A9!$YFW3^aqybFRIBLS_G=d@ZV5Yc8bsl%mpd9+!7<^0wcL{H#om28Fxhx^E(%6wdD|ANM z)}z0F1(NHzo(B}Z7)s*<&oFOWFcK7lfta9FYjP<8cZjZn5fq3QxB9}*qea)Jj*n8p>o|V z$;*JOe2u9&B39Kw7VR;UkM!vN+4}Wk)s{fO?Z2q&I$t|Fen~6!zGZ7@15REZ1C;Bz zJEjy3XCMHYxZtrK_)=xO(g@%&;K~or0+d4A(&z?XU5^*{C-C$s$mD5XS!!BRMY|sW z*U}dvcfiC-gE(m5nv35CBXNb70k_^!TKw|mQk>%zWNj`E=Q1Q#y5F>?h?T9DJ5SqF zcCaNRfY0I*Um8$?FH}m%fb|bv$&Bv`+~N7(p!kcXgGMdaIQ5@n z*ujja)`vMy0V+tZk_?Cp;5E`ymL(|>b)@ITIf?4rupa9jb&kdPb}7BQRu{CLQ= zS`mmJKuFBYiEc0xrXacKk)A#FF-iyWvgN8nKu$H+gCODZkkpF}F)Chv=X9&i+9mUZ zp!_<cN4x=-K`p@Bb9Ji~|;g8go_|0ChZ5ACvm(6-Z-dD0;vBmqZ4k1#@9mhO1Gdlbuxtsg#fhjAk}Ur7juIh5j)Kgvm4cb5GK@QM?)m^z zgG0{bWkyM_fgA{EAEBes%-qJG6amgkQDvIi?q)ww)B7)4ppE>%gi9=|aEJghad5r< z+neK)K~B2? zK=f?P9Ax#N7T*h6z#l->e~Yx$-6MGYB^44fcUbQX*4icI&pv?@vOQBy2tNu0Rb09?HV<|G)7C z1jN1%hD%LF>FP|<|7CIUs=a!LTs(8?J1MCGp)g=X77jS{|FL^>i0ki^5OdkQC;Yv* z9y$grI}2fd|MXofjj@(y@@Bz0Nk@UMdwaaIv$L9A$kJX zfg$s)N=W8~JCT8~8O!>Ixy;ZQY{;$e;LTVLy=M7T$$~=2B174#aBl@` z@|OoGA_W8jVT+!(NfSvCG%x=5ojFEPFn2xXmNGhtu%q!ed}p1qdCp$F|M=gWL^Tv` zYbmN#WSITgKQVgjxFW45MKnvsvCHWdPtx~~Q4?+I|5zn<@9(RFwWO1BDFbXZ5Deo3 zUX*5KXtA8=ITUWqt4U86`IsDSa=e@Wlc~kqG&+~@)yjcBp zDxpQH%L8!3XF*;?al)h8z;$;t4}lIs06|E&0I+Zr=5|Lv4uDO4j=h!YfG{O3pFe;8 z!cYPlS=dF0fz7d3ePncc}@%-Ue*;ZzBMf(wz>`kNR^s9sRILY zkdJqAAjJIt#on2RQ@OW&Uwb!hTLYCcRw5-zVTn*Olv*THVUZ!3hfEGH zzZ*$Olw08;-sK{7vDP6$Jez@z>y%pOp^Lp$Y0?Yej^3yKy^p z-N-e!EIZ=1aD4&=vv!u{lcDtd$fGD!rr&+7hM#;y48)X3np#w%me;QD!}IoG zh%phO^6iHTKHaV+KU@8{Kl#c!c!3BoR-#Lj-muPb3n&fL4y5MrteM<_Z_hL!uK`ra z#ukpRC{H?a&vpl{oi90tg;Rl-*XeWA;{rO@ZN#yrr9&)66LlC2T@yF_F zs$$x6U4tiWn%&<=9P^vdV3a$Pe2$3~=99@-O2P79Ne_SJv1zzB!Vw^5zS(+Ihu^Uz=3g?MLl<;UG$;3)G!8x69w|eKVUPs6@E#o_UIqrU0d~mk$dx2 zEmaoDmdQ#9=h)R)Ko`Jc)`XomxmVZ0)gkAp2n19w*098Vp#)^us{nTjx$QH~9@kXo zj}2jmSKC-gc5!|>qfIJO%>D=oB5CZsAKu!)M|H1{V%OrnDI4Ps((v%eJq;e<6!jj6 zYoCU*(sn5RF@bUvVj|}GqLT%l0{sEUzn#v88DCSZ{HA$cJT&gD7gbIXCzCu`#Bo`M zUbD0H?v`e(3&R@aN8EuTV^PfNe7qO#tNehsgAX5p^q6o7yNUZy@Qx0s>gz^2vg=Us zDN2OK^et=3eu?*7EOMHJ(N~{kCg#Tj+|AR==1j9;z|wIA!FB3DQ16KAhPWA-RijI+ zIcvt?0zWfm0r3qwl_Edd$dFi%rt?d%q+DFLiu=A~}1gy}=u?s1S z!Q`i%%ZRC#Q&N_2g5}Zg&;W*&#ap|o(?I4TuTkO2QU2-ZDlIALlHBvqLSM#fBW|*Y zB4D>=l;g3o_)Z1mq;YHu%dw@I-nx1>N_O>BqQmj#^eVX7$h{(#7bO@OCsuA6*Daq0HDR_gesd>fjbMU-0>%CS~ zd9S>@KOP?t+zi*sQqw`o3;R(4haC3YgPM|&>&pN)mFHqjoH1Y+{gp*MV6O>^B-o56 z5*+-iNl>b)dp(389P6+6qU%8IGKhi>AM0-z^p}IUjlsj5i7SW)n^oRT>zUxV_Sh+6 zeo@_POJtBAhXjH2VJjMtP4F_@RF9_DW1o~EyB>#Ur5`gf-QxE~S=$tOU7?7N*JJ3N z@WM%RAk=m;F}ZWazxpg3;Vsa-NY+a#?@t}KzpOgXwzO7W__@GBOE)*GW)Pv%I)KIG zqp9uQ;aDM4yi7nm@5$Yo%$ocBd$cn3Wvc^9Jwv`A4U}reZZ=298jGBwef z2a}CiMz`#O8}^w5A}}0i*113WF3IC2`ZRo^xJEh$Ri#ngH)>T7}$^OUKN z4D%d|PE&I%=h9Fz&pkq)_2Qk}&8oI1na7=Dedkiw-s(@)+{mJ9cPoRiX*hkzn1y8@ z&cXu%Ho3m(Xm`+T(gudQ-uts)Z+% zSrU!ehg%lypMRQW2ImiZ1Awn-}sDA?~@GpaKq2F%w8W5 z9?jouidCROVmu+0ZdE!JVo{J+y5A{*AT~Pn8h+LZ7u3RTumKJM!NZE!dyxDEGyt>g zJT3Ugn|A2<-H#jbhjX z0pi6|D3*=SJve^{ReNMFXcwNuNS3?^j8< zj*B4y8i+V8oSyI*1QUmHlcoezmk|uidHUou7%;9q;b9AKf2F z&SG+zIh?EzjZeQ)bMJ*oD)d0}@qE%FpBGggiDnK+x8GR#o|WykHlu;2rTw-e&_xxG z6#ADY#l^*y6%@3?qr2s~PAOsS$}_jm|4wZFwj{l>b4g-(^t{W1!1OQ<+y2_OMb&Qr zT2~9_QE56h5*P~Ly=YFT^xnpY$cZpKU1~SXBHFD=pAoj?k-7-2i}kwZbDLdGjf7hk zCByUR$)eQhnnb6ed3!`gx%KP1Fc@d;C9$BPcAYWN<~bMT95il0`;qQ7#KFj$Qn%!HqzRu!hp!i z_0TQ8Hn8%kd;@Je^7F8cF>NM-mQV|v9IJA;5ky<7PL3ploruxjwd^bW?}x4PH%OH$ zmX*D7P#rLFxM=N_6H+Qiqe4kc=!U9vP5PqC{(PO}k1%r6GUEydF^eHH3UC5>u6II= zQSM*S7VKhSAn|ui4z~b16kl}FQ^Fop{@0oH%x-^C`y=x|&>7o{8PEC%jNT#k1e@dQ zbNcklDs`@k5RAEOyKL~nPI36f49@)$lG#v>h3PJRd)yDDS{4y_b2nR2``wU$()6g? z@AUUP>zTB@7S+^<1K{%b3!q3cmp>J?^bJPNlY@F_CU-r`cNT8iTF858WkanV4o!ah zjfHW%4kz51&n$r0M3=L(WqYHU)6^SZQ_sPNp=S@3HY3u($Ib8=CpytH$(RXd1%RPC zjQjx|(5{#>JOpX7mIMP>x|~h4XNU5I3;Nv$ZGnlFGqV;M5}u_YL`{y@m70);o8hlG z@$p}xR;hTnu{(acjleMT{rdkclUZ(L)Hbi@V8C7bfD3yyGV%PD3ojrsDbjnE(V+g3 z|BhmG(N}Uvo=dqfm|3isg=8^Ru$h?Dffw+*YI6@V+=&Nl^y}}vm_7YMt9g$Fq%Z%F z=6(}&z>v-FVYRrU4B&@=kI??#B^nSg1VjB5E&7L;_SA~!+>^_4|L|Z6s(HvI?~DsW z_e5EklzUlndb)^8!nyGxnYIjFsp2uS?;>?m0`@3E*5TXF(VSm8CGAh622!OvM`fwv z9nae~Y5fyvtxVE&?n(UF$IekbLxkK^L>uL|0gUH92@0|pfs2TrRQU$bbam*~Ur|87 zO&5+#0g*cjzrLpL7!};&^0`_P-Kuc8J!j;)hPVfRNC*D`fvpx=BiaM_-zc)hHyAip z81k7D4kXXT^L+@*guL;}r9!{#iUpNOZ{p$Q{3KZdcsiH;zJ^E3w(5^q5;}eh&r^`Z zgOZn5^OV%i%JG%Pd!#$P>klX}l8qZ~0qj?#KQ2h|8<^2-rpy-+y7J=M-*h{$XqxwlTb;I5k{1V@d8bzu*7~>NTGL>TRzpa zY&%rI7V6szt=?R+abZ_4|B`)Lx#f<d#NQWzpa=t{nirl-K{$QHPoq42t7Wrp`3GpgMY-t|?AqgSaJ_3g(2ib}D4 zknmaQ39sPz*NRP@U%H$IA`z?6Vj3Fsj5F6xyj{az-0uVv^G?G$BpSqphZv-$<$bI6 zl=MG)gEk5i?9*3KzCExoQEzqbH?L}BoF!-I%}|r1$653;|=`C)~ zzF#nIN<&j~*dDIAdmc!H6)f->gdBK!ro*kJ1Ijjlc$J(yE{yINUV?#%C)LyIj}?KP-y6jve_Amyz5M8kE3 zl7fq>X0OX5{G}whH|e;Lb9ri_EweyM?kH!pj|dE8oOgt|frD$|QcRz0hEA!uwm;-7 zt~b623t$ve@HP(39r1pZ)&~Ba3L5;uy~DDYJOZ$tKBkPCHp#_F6%~*M3eLe<@D&|2 zyF65x8{OdS^q-CrlyIJWab}Z5$Y+7~@i3_1IjhQ7$*loJ{ap{25}Dl7nmr*^+*{dP z1r8iA4Lt5C?X`v9$GxM9Kam4tvrxh7^c8SlVQ{uM;a*p<4}dP16R^pv^-k-3)7sT* z9=9ot8+UBG6KnA)Dgy|b#-X>nUa)`=xRnRp$Cb?=WbMR20lQ=%&U`@O@(kyYH8WM= z*`U65fLoH0!U1t|PEeZK=cshaV$D68?}6<4W{Fd+XtlgnBeXyRGJ?tD7bQ4)b#;|z zIKS8gk6a%soi0&oyo-fmdFxu*kJx%6nCn1p^k>4mugns8F%H6Z;~Dhs_A25mO9XEI z#$Mhf5m9YaFu6XLX@W6_Nf3dI3gI^GroB%KUWZ(2 zQr8l&$+?$F4c@$ z9dE&QHXi2ZF7A3^u@gL~##&W?To(bgC5sboxZdp&_=8A!N5qQYJ)!P6D6Ocl0obWnOTxt;+jZ;H8pFyPk88+DsgBr4yvd|{`2_>zXnALAk-=6lH zebW(>j!DhVZG7tOSJ1IDa-^8RY&kcl+nZACaS7`GQXjn_upGqxti@b1U-Uj1(HLXBh%jqm0@q8a8PnOeMjg=6JO_HgG}uvv}wR8efW zFxYLFvZ8Iw%$?-kh?10QB6DQ(ZZm< z?LI!+7nH~Fd+9Mb=GNi#&)ZU^bQUxAR#$p4k=GPeD>wGCA$tV&mn14Y)atk&Ykz3h z?TrLqsz^t4%x8}4pH|r-14Dir%`Ew99j6eOD^h2HKVyz>gx9p0$X~o<+9BkMiSS<1 zz(Cr14s;#@UOguwqvV^n6MV6Sxx#|+lHPcsdMvhxd>ToyAQGG*pxEH)V|4_;l(iIAA|{f_S@7=k~7aTb({kRQxk`mqFt3S$LWcIE7;%bQ9a7S8j&ZG(Z+zMU?{GsAxDnD>EI%NOn_M0 zQstd8O7b_|ipC+Q<`YK=sd=(Ic3W_lE}1M(Pxhb5B<)Br=(uz>@=EvSxB`TMYBvlC zJU?px(x&f^MkkYD!6?f$H6>-FdwITsgaRa_$z`Y=wFLa8&f~#g-j*^csHR-Bm&ZW} zev4hpZg5o4>f`aw^i~KOuM|r(`v1*Jm7Y^qz~wqov?IGlpt!vp@JU&VP?GLHT5gk|7czS~e!;Ax}2 zXLl}~$^s$c=@76P+hFEVNfQvB-TA<34@f)u2{7K((L_XIBM@Fkpi0H^sD+V8v35+>AsR`tr) zAjaIqC9)U3(0J#{KUH~eqgfavg{?OPQs>L5*&70(mwB=pd_lXt5xssYwj4VF^#c;Qs?)~+^~!09xA01E z1pH-tIhUO8VZcuAbj|qbvS1^5N~|~}5`Z~+F7!whi4j-swm3q&G=A!dhm@=JDm*$? zBne$+sUOw}Mg68H3UIa#Mu&z=v0>zR`Kx#0$&+f2G zknyF>Kkbagy&ev>4|IYVf3MsDK0YLc(h7gPH!fE;y`bl}F%?_QP42Tby0xf)<;>W5 z)aZAwhjf(L*U+AyRvDQ{V}kF2q_3uGG*(`h$g+ot=iGXUGphOM8OG*37~SuC^!;J0 zl5r1oA+2A2$44KW+L-A$X1A}dk;@R=Y*AQGUXz$&@T5O0j9FTo@7(^j`MgE~gKy#5 z_gN;-&b62vNqYym5aNS#EE-H;ZZ7z3KZVA0bRLSoB&A^6_fTHW((u8uEd{*V^6CK} z5RJ1RNKcbRl@(xrI0rU8%~rUgt9ayOdXrf|UCOS5Gv{jYnjyh3b5>n7H6wOv1&Rc~ zn}jQ0*CDA8i#figJ`{BEQH)KGj4hy<4X1cvS%}5EW!c-rVEN5xsy=NuGC^j7d-p{> zlZz?X!=EARy+s7H`q?RYSr^g5SfSgv z6B|hq)kgY205n1;`oeMDZ3KryI#4H|K6vq2`5asRG8hbwjA$awc(G#OpyzVnmlvq~ zaU|>LMuji9%KPGEvv3ajD9*BfvOU*)|R0Dejdqi%04|T?$PUwZrDfg$8 zG+?iZ_SbqYoL=$$>9ZPpy)p+N21E0b&|@5!bww`l>q_FErW8yuf}aG;ByL0AU=jk- z*~vG5XM)Iq&J%t7Q$G}(8~?_YG6$A8(eO@cFhlYu#U`&tapW@~i7Rz>WER(VcxNAH zYz4hkyNYAwW$*AkbjDXgLrj0CC&`5kA?E?UD|E`^_wl02?B!sb2`zGG;sRB1Jq8YQl;=2t5ZY)VSKD9;l(}!e z{MUyoXrYtym7G5>?kGHXmPhKjB210{Zl6;SM=>J{8f1W%^zuu(>>IP!GR#butM{uQ zVIap}q}U_m3uLzZV+wIVa8JekP5JJ3R>s?9mtWn693D(tkHFhDRU~p5*|VS?uZ4JY zmVz%z*!un$xzY+7c$a_L9EL%IdS zlUvj?Nz>2%Qqj7PS21J6uY$~7+zmZz-KuqLmjg0GpMXgewt-;_qriR1y6k;(9>iNr z4YxR~>K*PX%;pbG-!asgpK%Ec8q@nZEP`PQM?l-gz#Do946Xm_0#NW(RaXxKe0vtr z0CuhUxqj<=D{?Flt1siRiPMt07EJ?xc$9gtVTRxmBiUQLM1w#mZl6Ha4Y4@n65A=^ zoU`JR9#CeXz2X1PePFa9Zo_Vr+eaMo6MO;|-|Ol!gDzC8_Og2CIkq$@0H7^U5`&;uMs z8N5X*n63oDkm95m$W_>Sfo+I)Lsr#xttTjQgLK9&a76XPu9^Cp9jl(j(xy2#ZzJS; zSWL{G?6*AO*KuMZ+)}DqhNE4DBK!CFZ0A3Ms`?JA^2L#>bSL_0cg3@oSx%QmgIy3} z@n1~EOS3V=%IkrBt%WDxMN-~fQw4;t&-3u~@Hy3+>T$2!;T`~!XE^22x}}kYT;JhD zP2Q8rz19^nUZ;q{&wV6BOTh~Ke#sSH3$pG2g4)Zo+i%U4quX`%e=~UgvmII@lkZ=d zq2(<$qAO>pDbWQ-;6RmT-Q5jLwMojcBL@4@*GjX&OgT@kdik-p#(=h03*HSQw0kNX zEf8~SwZcOrix@}4@bf4=HK&n$snCOd$0Qt^sIziwf@KcnncY`hH-@Ljjv~3#3EVj& zSFvY_T{+yMr6K+MAYLs5FRDZK?2zr@jSQ)G6`DnxsmO;HA)jwaG|&2SXOrY%h?T`g zmiKdwW+Q)a=vjfnN(V<$oP_<|v3V$xEwW6Pg@?H*($#5Kzf_YM7|;H@r`?eAo|-Cr z+wJ(1>HU#(0Inv49(>K?__7vttx)La!U0IzvHwXD$2I8wCC=8&SXB{x4(wV4E|O zgq=CR4`<+2n>|xmc}&@$b;|JTh0H}>MV!wmvd0Z*%9rP?0C%9beYFPqWZ3OO>Arl2 zfwphXJi0pni(Ke1@8fL zOgc^6vzUQdrBA{ZROOz-?}I)8(8I9Pu<%oqd=Z4;k$D-$m>>qiupfqad$K+^_Hd~s+tMQ$atov5rmO+>Um1|^w#@YOT0Eo#by(-77iwtU^U*t8^4q?XtJ?{ zi>v4=ffxn9WtyDuiQ5_PTh^3QEe@lYqOi#Aj5diLPp+`iXzq=<<)2q4X2jk9xRJ~B zrh3ih=Xx;?3K2;*N$w&xyk}zch$Y$|s>=`hCnOT~EQzk78>ek!Ig#2JyC+39nq`ZC zpf$|&JLIpbHk~}<1$LooG$qRmx%)9^k8`jg;8={{5t-Q?VTj>s?nX$n>*%HK}p3N-h7p!_){BUUe%u0czu`Mn2W1Df1gV3hTx-!kR4ea>(d z)UWic9vYtNnxiJg`X7OWw|Z|ZANV?oMzU%~tkJH)$f&>_{{68s_X)ENhasqxi*&`3 zGKQGSXcIHd^vH*HHc91yJWCWcReIT)VaENYTh)mRZ<%P*pl(>F*R-^T&X6|GqSK5F z{4Kqdp>!=~WXooTUMqu2ZYDMiL(7}fZt#Z2gdI*#@a1Sk7=2bw=3nRxm(NE{Khv`j zu9S{E$~{K<1I{^pAWa!xVB+e|bz}=G=jc_Q->=}Gr2ZBm(@lNoPHbGhKvS;;co#6< zI36EsJSM7YCR6haZ#B6?@#_|Lx)Vk##o*?K?5j%I5OjBrI{)VTe|x6k3QOS1F>o3x z_NG=UKl%O-=b=`EE-ucQWvrz{*r8?Qsl4R$6*J_-q; zvVa?!)Pp#ubMBVE$f)wK$6k8)os zoJCe^vtVSJqS&J42p${RO;;+@e~2$Jbb?1H+o+DEIJ$Qj?azC~zQ_N+X0K>86Gn-- z6?cV}@bU0U&q4j&zoUc`a3D~~9knOmp+eeWTkfjP(iaA8Hh!oMtP5n@6caQc zC1B);u&{`>6FJJVnhgkTKw+4yPR%sH(+nnn2-3GWk2#63Vt>5#Kk`Z-cTFGDvI&uY zT_nFhFtz=s02C-u3V)Hkh=*zRi4>$k89_FO#>#@r?q|Ci4Yma>>+@xS4U``C-4s+E zf#I9M@5~nE3o^k68|#>fmyg2=3JVOnmiT=Xw5mT|fXLf&0*aP~5lP7sc^8&sK-&b( z9VEW-rClw{Z4ZHsG{!}`{AC*A!tWvAxSo8edF-;%+Y+Q~l?@ExJu{zvf~>b~ z>|-bcgEKIk`TCiX(G4|}G5F4dd`DM%7k{-vk(C)I(e;R@?XHG?KorPcS4PZfQv zGF9nA;aXU9C{-fBtNQ&bW?;`GY4N`F@-g~H)-5N6%U|?0>V1sB@kc4@dtU(b7g=VU zA+*+`_HP;ZC%`fZOLcEbtN%IM)|jn5=Vu6h{gLibV@Hne>I}^V@^t}pq_!aeK3!RuW=*}XX%YnV$K)U)%B}_{a zYn=Zn#6}y({=AMFF~EsXPI6dE2);6ryUjG0&N(q}FE8=tMcNW>K(AJ7sJ_4?g*$cbw^ z7=520b1(JEH!x6PlB+Vo$rOehSPO7Y=dxF>XyEfBv20c>6)v zdv^ntCF?L73?w`Gq*$fqdG(V5`2sC3P0rlo7*b)_*21xhZtHg16#R`#O750^Xtc(c zd=xE$(O4AgZI-{+_vw@rY#lc*=1l>!M2q4*(@X$pNYcK>*fym!6Qq&rQ6E&W4-PAv zMa(3hRBJ2qEKiDj7y{)XQU$D2>|+Rg&JjF{to!M1E&$;a9zJP`!ji$i+f0@h&6?d< zeSf@-5j-49BfSSv&a5ro>Dm_%FtU1|gAoIMeTB1UvDBqSGIg|()sIO#1i1>!WcU2W zeMYE6=WQWPa#=;kzHPbQ6%#gh20t2xXD>?a%})btA=h1vtFp9EZt{t@&i;`>n-IiX zEDNn}`Ou)HzhD*N1TPcW4m~@i%yd$|WWu&9mN4&(#fB5)ue=^qdu>|T zqAP9)I3OcvJ+K6b3EQ1p)~AM>MeZ{)o4!%CuuE!{gSym!E6H?0)hh_Hr%w>pKr$gl zqt6YDJ$dDW{D)Z-{hpb!ILBRqS-+010fKbUHcOh9&GzR(jK*oMTRV0((!TXl-WD}j z=H09;-(hKaNt;owH`&PZqZ>@XyQ*hXj2FQ1@O+$K9Kx8(dZ=a#6gpR#*cF5dD90y{ zJyC72Mv63e81jTAf>$3KiVHH2c@5qIDF$xog{BMF(82Fl!TTzjuxm*~VS#)vY0&-g zR-3LHT{(~^oC&G^@i+EQCZSBi^nOgU+#5(DH1$~sqJZ8a$-NHzly1wfgi&6%n+q~P zx3>|OAOSdD)bEini;z97j3z^ZJL%|d)6TVLEo3-;DC5CsT{bGo5aZ=2r~5)?8^#fc zyK>@(IGk3k7%J$}jKHTRi0QJvQ%GH!CwJ<~kZ;bgV%IDOYG9!Le*f-ouw=6prP%v{ zCOugsf>QA4Mk-Z;E+_*{%iBm%ijiW-q|o7SgX{`DJw3j7=F+Q@O>L1TC@FW&wUmKd zZVF>&`nZjiqZnyrisjANgpjoby`{fB|U z$MuJoQG8;nbbdx@&{ERe$n`)biGQ!hoxT}{v%Te685qbi`+*LT*8wkmsleyv!znth ze6V#rPy!e#y&_^Z_BH90lPE?@bp()@RyKt7oT6CJT1pW<_20RH?N>ib>M_xJN7qm?;#Y*nNEJSUCX@j`seuTx%FkB0bq5o2c3^9 zfmm3gRQ>VIb)X@^7w0I#a^HQZnaS`GMDUSphszr!XD*MGuN}_#TuGkjo@>pog>CB= zh!90x>m7nG6+Dd)FNj-XKF=#zH8c(HVd>jzXkVAZym4tEJ%5@~nub(l>LBLJP-2uw z`8;uK#G#QgPU^@`?0}mVelFB$!eFZ%6XKCWiaU*UpRRc0}2 zw(pcW<$LEKWARba9dZnv;Q<|cVFB|BRj#`Lbf~}BU-k*UmQ)%Um+_Kl^LhwM3qkwZ zTW$(f)J{V!fG~s36|8`0l*{Nbt%}MqxN9)zkcSrx?Nt^}_i=?4ve{9K5XdNh0*}YK z`Q}eCJ_1>}R~I0ALFHlAbY2{T@X3g)sWm(k!qGNF0Ayi^b}HHQO*kOh2n59XNa2F# zaSk0<@)|Ev9jFLi2x(D_6^Ptl(DMY|SHJdQ1}Qf~baMh`Krg_RuQ=KZC>rX=BAiSa|+8(sg z&0DE=&O~B{wYkNO?VN(Kt7+++NvYYQc+swnJOXx)bpvkBns7E+J(LoRnc$(CMT5gq z0@WwZQ7p#g9}3(E)ErLqV)sjCGYuPyMPxQn>2G|Cy|aORI^;+eQ9 ztw}(YF`jgJFj@@lTY!j2NecZ&YNQd38aTGPxZOU{5kP?ycX`L+d^p14&uEcs>^&yn zFs{401}cjWBmViLELLzDP~0tS)5?KF^G>H(l)&*yb9K??)_c%uNu~}8luiJ6F7>TL z1G^1Qbk0PoQ8wAV*sK%PVL(E2pl{uCp1iiyNj~SjDoHw*bzy>eQO>MX6ajfkYeo~N zU{6hJBqH_n12k(IE-j}!Q35&;0au$Z?;JplO&APJJL?)3gmmR=V!vFQyhIWzaNQc! zGuh<))g7a%b;@zz(V#W#{+7JcEtTfD$dT0l5(RSZx8zY&$ZIW5Nm*Rw50?_mx<0O7 zTpEFfG-Wn#mF6F{CPxW0+!1DMAE392g2m6B(t=lRSDvoXfgf>Kkz zvx@juo~8%))r2~lQ1$r|Ha=PLz@&L+6n|S8!4;N%J;@`}pWCGpI2$kD17OaDX zOP{#bf+lNjpa#x+0_%#Zmdizhl;J;*!Y1BMtko+~aLbc{(3yi-E{^O|P9D*FeYbkG zm#JUU;;tWGy7TcaL{Tt5mG1NQppm3Lb+ z&f3xH^Rns|p#@rH4uG+v;LcyE%xin9e8{s-We0M|IwcNd&1_4e*fRHIxn&w29+oZ! zWo0GjN6R^B`fGbKtyo&m_?DJQVrJ+6zB5~H-j-SGivPOzLKfry ziG&=8RQUj{X5==&b&&l)`cHO)e=7h4uGc@ha5}ob8?FBPI7~2-A~FP}LBuj{7^X31 z)!?b3?S=$}3Vaq)YFpuiYRZ_Ye2Q5;WRCtqFyuy%6-x zm7X^-ToC5a*C8!0>$5%dC;hUgsHmuV!|?wshZ*Mhr(bE8?}HO7^3nkZBXwUr< zFCklvREoL~Ez8iyUJuV9@Ye#_%01gFMLKcEwp9JKv=}=)4h(-2CnYFEN z`Qa+owIwfc!Uz&4bAxdds9#K`*s4=M_VXl>z^ComJ~7{#+YMx@O~4;kNZj7}?` zTL7|6N4;LoL9jLiqiMK)%Zqjh>xDh1_Z!n?4jYAc(}I)lf;;~h5`HK|M_ni`r<{PL z9Dek@Xspc>Sh5@=XhMsSnRMB=;rij869$Jy76}X-k}pWR%p*+^U0*miH&~Ny%VWfCxFiUd1^EF{H^Y>7P&q7VYbT^ux(so~ z#}-KXAhP8)*^zJX8nyUe2l~m#Rp6Uj2bsXUyO--ZOCf0krc!5_s@H3%JFDczJ36)s;3#yd-GN7A4}mFyRU10wup0qXp5?wE)P zG}F<;O~Vi)yr)M${F8N)?V@(0Y!M@ibB=VABk4qwGdy8yLBTYTB8@?9Yh}hXnC;;L zol+ejVlB*=lPGuJ^}P)ubFo3-Powwv>wZ#^32yKn9z49CpwwG+ zDWI!Eq1F=DoxbSh&A3LuVH7Jr=;y& z6icU=YEnX~o+?uxh^S`1ZQKc6hv!HMJG<@&ubu-@wZr_FnvhkR5`U`X!0lEgYe~zF zBl`n~X1p)G)(^NKq`RD)ni&1bUVyeFFK=IQxap<&gP#ZhK3n@w{y$14;^NIKsehSr zYUXJ-!qYz9b}1jDoS9NhsdgEmd$fi099nW+DVg7!psJ%B-=ZD{Zqogl14dd z_VOOuKyHA5KPhCKf*;a-mE*1^n8Es71g5<0z6dEto#qbTQM(IhRrvCDdCc5U&! zDGi$@bw?_7$)vz3qkL)30d;lheigd@$NG2By4>&tNxtz|z1OYD?${)jle7Rmz!vF#jq+jKCIoyx%tsO#B#|k#>SN;aHsANGMjoZCnZcA;a z-hi4UBqU*Hym5)PFJeRPrt}l1*x#wAOoi2F(yGe=F^ayLpcYUS$;rswK8Tk?22$WA z(UUpiJwtZGMhEGY1Yg`T&+zg0(Ew#`&RKlSJo69wUR&0cv)x$i*#O;xm$E8b4}VqC z72Y>FjdmZ&QrA5`)0-mk8}3s|-pl;5DSmM>I-b`aC%)*Osm6>5sfwR$YC1fZia&r{ zM{qeRD`8cbxmn!n!i4>L`D{Rkh-zP}D9rBau$ZGgoX``MsAY*^r`{kQ)=Y;;YA1F= zot0zBKDtMj8KmaC#phS-79aiIDAWgwWioJ4EY(temm7~1nha-mj;8o+(N46y4m2bp z$a<2T+VykY<;1S66fNscvx|#_{98dD@ zPm{kU6d^evZ7q>f06>n{nF6qyBCtL))g{mF`G%F96a)PZC{@9DW?yhh=(Dw=xOryN zo2miF?kex$nhDtz$6;ad$w8plxKoe(W|0f{y9 z9cfB_u{P|&p2O}cJ_*rRnr03lEC52dlJ~u`Pw_B%w721f+tMteYb3Nxy!QS_P7W6REkM&_kE!VeRY0Ty3_Y)L$j%8x1?DDGsZ-1)=@J|K91(3wpqj4Ai3a)fuzN)st|?uA^E6X`PUrFOTiIe5BZphs*~h4M4*6utA|Yni6LEu zA;Uo=_{7&H=hhsxJ96abGi}*g>fC#~oEsxODl zR6@v^Gr^xEw}x2%dh_t|8Yamk5GwP;yi-OhzdWsJymd&$)b5Ph_>pMy7b%qmrh+zT zgeyV$_U#%E??hTiR=l^502u2479FevXtC{WrGObJVvI+=$84vXq*g4luNMSN7!C^!u3 zrLuB0HO-3o99o{PKYKX$%7}nYX-pgBRSlvv_*q-_jE~7H1oCg=Z{*S#)1u-9ZzL6EsuD+QkfFivf@GDSyH~ z6RhcjshhuUG``@IkejPf;;o!{z=-bjecEO5TbNmfG#NX%#g7sve+m`^bj&3Ad54(6 zBrH#_u{BP-0Yz0=I_Hh)lY8p=E$zkN%jY=LR^1F)w$13EL6d=$T#&bbzgpTN8v3;O zj3-U<)<6l`aFKAWP-sj$y_1)~rBk(o@@6yL-G9XpS=J2(&%+Fa6A`+B-n&bDx%{@{ zbuOlPmIX>DFVIYuunHw~`I|jEH47zBE$7nLb+#~W2t^|j6m8sd@|Rr(D_<^(1bEmU z;|Hhw5$Hn-un*8q38=*L#y#k68n66lYstAmE?cPGfV+Zy0OCt65arzkHMDKkSUjNf ze4gY^U7DIpgdBhoRHAtX+G6V=NBkeyK>`bB{*OJ{WZOYBT5RLy0NDZ&-8f+cib`QL z1~uLZ4dXdj6ha=CqWMbR2{|lEB7-Y5e%Enj2_}oMnE-?Gz-ZwXIidT`ismtY%>VC@ zZ(+Y~6n)9D99C7)(h9#Ob)|SfghKQ1Pc;N|4!5NKTlSGOo|*WbK?L~7pXGSS4qu*c z8vmu=(@C#Y&o z+E%gOE@M{kf3U*@5|;M*u+j{c_c;Djm9J3IcQC)wiiTt?rx8 zDrt9+CKI7w(_PasbPpvj05@A$Af~=ETjw$b9<};{hKMqQ|I}zQ zASTENv_49~5kDNm^OWkqo=p?r`ESRx4CbHMe(>T6{mT0YTek8$e^fy2?6XrJ{McJU z##Q`w5=R>OZYaT0o9ejrbUAlvkAs^V6JeKFKj^-efuKTeAtr0QzI%85&7|*l$3m{` zWNRpL?@E3=E4})}3R&BZ7tp*SXtZQOGJqLlKVVY@X>m|yx}NX%D8egRub98d@9re@Q|7KTX8^pQ?!SEG8?_?`%+zUEH2#{AN+ioB>?{ z+F$fDc^nF?282#t;UCcqfFWGWJrHSKaTaG})MJ;*{;?!pPb*+hcK#=cYlSu-?JL1N zAduW@_Jf9F8@R)URT6Z-7!w+XscGB`{3LUUeD}7y2+RyTM1*FblOdNO@E-uh1iuPv z@jnM5tS{bWNQ*VbZ8m6=3`Bl#w6xBF@ZT6x-A)s+|D+~vqXwYfZ5eCv9ToMT0(}2l z*+V}6FDJLCk>;(W`)Qyjz`_u~_DQ-uje}D!4_PWnjJi>huC-8cmjY7`!Rg?FUKz&D ze|mMN4s?wWSV;BhGc*m6 zZtv!QylVgBY9f4(|5)7n|D)OeyvN}GquKv<=<+9&D7rwGCo?yNA#jOyv|&P!?FRv{ zUtCswg%9Ide$oucADOp5t~(Q@U(N7C=&8JxkyvO z>)X1-R1kNq79x@1&zZp_M^VD3$z!QmH3CNwGz7ejJ2Q&yD)`i0>6-C%zk#_;EJANcOiu4nTilYdYUHHvQzF6be`R(Dy$XW`AN>B~z4*?c2M9a&Q#b(JpFr(sP5vhMn5tVSkz17 z1CZW{pt62ZUl8A$G=|vqw5@H4vxr+mZ_F?chU*TC)Ownlzl0R830^+FqbO*Hh5>bG zZ6;)+EfKUT2m`USqC&J58hHE$1HA)dXkJga(l*((Ap9Q5DEC{AL8Q zgl*CWc!dS&RHjE-@u^J`%{+oaC7l@iTgkn%$k1xGap?8M4PnTdl1F(Ua6Uk6n75M( zu1Olqm-y5&w5zCb%`n8`IEw1$A1m9en`U-Jj%>?m$Na8WQ_R}TqZ2&g=KA+-I*Erw z{XRL^RTvlZCQnd0t?s`+)!ELFVc!Yimf|kw8*i{waKq%(a7MUUyWFdaZbxh38wzr| zh7zJJuECmPk$Fj2F7;WYaDbvLMP^oTOTq4T9Vi1~D|kL6FMOuhtA7G~LIhV4^Rl6` zb%d)^u4nW8Cog51guNP@$G~1jp2dp6pTfkEfw#a`)(>Q=yqZ4z7%ZLHpP9CJsr%tM z-dCD`?L-F=?GkiQ+{*$n$5HdM34C&Me-MJ?S!LI$JX*Gexq#shxWfJtw>B)jk^jud zB^KR!=G+PhiWVhT@EzPZN9#pRjCG2V8rEb_fO6QR(_SENzQBxMvMlO+?gQHS2Oj1o z??p6ZX^I4xC)zE+GB&6Kw+E#?n*Ly;!w0Wttm@33gi%<6WOk&ScOet#(5={zw^Gzk zRpq^T^Ske}eb^D+xo)9%Q2M-Mrf?dX*-;!F^TrAXI8fUreVh)Z}ha%0fS0+g5 zGlKD|gKNQ5+|;P<#{AN*9HPS$K!!_nAos0RP^%uv5|Ym#QtmTgt z*eE-3?d?`9p1&TZ2b@k((_>O$0RkbyQD`e%Ub$A3<>JhJ$C~shTNpGDy5j)BC)_!Z z>sz#A+Um{=iwt^4?q0js&kf7N0-A#58`BDNcHOT*HYxiBaBdDFK4|?P4eu4wN;%T%D(6hELoxq7jCV^zQ+%~ z)=#71(-8^z-h#1Pf%^#qxkN2Z`JQg(t~nEv;`_=y0-cqfAu64(0=m(1sp&K2IPi$s zX|wz#uYGxF?@330TyH8GwjmE+9h#yk>9gT(=GYyHm)l~moPPIKte*YJxZ>h(XaeW6 z8*2+&Pjeho>~|+Iowo0UnCM8A4~>49Q9Z4ZswB_cGN$%$8Wwd+{?7d^}_@euaSrjf7%CoCZmP>hU+v-S^0OJ(Js{O0L zMv2$Y+(wmIT;JanFvhVtPx9~ z^W>Pap0MsbY+k-ev0Fl+H_FX=v9L$i-TQ23Nqj-fxmd@sk9i3i*6wQjA*#VL8{Dqu z`V$>R*z?`AEf~k^+xT5l#!d#$+zz%@W*h~iXjb<+V&AG2Zcy~(jyGtZJ3Pm&%x)W2 zxZjHRDTSm{yZAfju2alH3L(Z%P!yZzjGd#l-768(X5R25<=fS`8+mpQGfajpzm~(= z4wtK%jty$0*m$3Qe`%5&v!?<_VdW#fCGoFrHf^|+&yPx!>-f3#o2e+*Axkx5(-7ay zjy>DdjB~SK#$>ei2^0u(*469U$+zjMoVH0>d>rXO*#9kD>2{M8;GDv-QUyy3+{1G< zRYKn`@r>`k6>FGYHXx>6n0HgPVl`b4ntz{oJv3SxxIy8->Y;S2h`8H<94U*>eAwif z{fl7H%0|AS=wia?FSw|dbT5y_ShiOLI)6sGqSGJNB&B>cD>|vbHn=g%^k@?Qs>U^z zBEoXo=PK|rXRcWql5?FDy~JUP!5i55c!6%QvD#KE%0BA=rzzn@QIn!fHU z5I9-j@ibDMyxCQK3$8hd;u%YCOzo5s!s4{eZeSE22t03IAJ5wnOW4rSaAg15#s%0d zv2XOY(gt?sF<4<_;rFYud#>y=%5m+UGt3sIOs^Uvtr>dDH)|C0NiBTdM5gv|*f#cJ z{ZrXvhrEiv+GQqcI_mkg?pJR4@O2DqW!a)KHP5SsgrDpCeVal16^3+~m5p({iuu@_ zl4R5M1s2a{3+%aHT^E+Xw&mKyObxZ>GdjjNoM6MA?d7A`H92;Qw#?buB#$d^sD5P0 zqM$%q%Qrs|qSe&0G)%#V@Xp4>JveJ#VE>sSo<{GwsX4^ccu7n|RLsM8N3IFit68~O zj-=hX+DqBNmiykm5as$FBO4_m%Ai&B&2(D)Ynwy(~? zauvfCGH{?M+9mjX8rrg5;#+T2xz;{SONnbS^ukk3hfUimbH{dTa`4|FM4WfW4JPYJ zO67M6DB`{j)gAH|_|`lVSCm=~W1Jz=<4_P}!XYyXRbq%oTQ{6ygxMkyIn~sc-MbR= z5(ONl2tqw#pKs`6{4-ZhVLN_#{i6v*9HS=Ld&_il1Cn{lF6`= zVUM%L^RwqgM)Tk;#fF}9`+25Gjk6t1iW8$!iAlj&DGL2YEmYlm^2xvS9VLb`NXo_IuPg-IhEHCmvb_(cQ_eM;cK!g{ zI6dOl|K`nj(=@!2+q!3P~}Y^4)PMP;TDAx--<0+O{HAPg}C9VtZX5!hqgUyrn#LcP;!tp5@p1z<9TVLkVP17TNK zs+9W|9s^rPpj%nDyC+r)Q{eO>6rsCWMK6|u%3CV7`yHS%{CS6_A;K&g|L1fW-a}Zi%)@qJ6_Nb%rYFDvM+W+K^5WXwDfKPYsiM3P z{-WX<-IauMSFCE@JMz&{fV27?h}eo8CE|H+t{Db7@{MhyO&2nq9qF-BW1lwdRw#Nn z39K(Ml_wtl70TOaX$2a&hpThPaUr!vt3()1F<&J8p#B`t_wlbGbY4T&0b?IiLQ+rO zAVS*Ry+YRxi*%y4v&1Uk<3ZR8!!3dWtxOvBx0TXjC$kqHz6N~1fIS;gtGtQ<>Bqe6 zZrPiR4>)HHa+NjX0_Ik+k*=V@sl`7$LRLCUrCGX{G3bk~=d=_YQcpI>tve8X|1?k? z5N;G`f)GP@E&?4#X5U-=g|d$|*UQNp$*G2agNT4Fl^EP9Jw0303)_SMWcF(XF=I(g znjL)%#|L?bI#fphTgZmOgNc&?mBK3Ao7R)NGL+fai9V1QD(O*Lf_n}6AS$RxWp84> zBNO4>hGoV-!Mb4yMUfS6sD4Z3C`(ktRv70ai$bWU{p~CEeX;(s0*ytx@}cl-j#)%O z>E}BZ)@RH6qrV0G^FlT8I~#3BUm=DKdJY0dO(=^#S4_=6gxE=n*SA1Sn+Y8B?4~XI z@{_qvQ=Dd?@5=ISy$S|ov*+urY^F?OohrD2NC#~-q?r52<)6sSfIw1avm21KG+te4 zv0tQC_d^UPVcq^)w%#$HdOh8+xPGTrqESmWKK@xZR=~`#zckl*PAP`eA4R-leMLl$3fvVkV);>B>U3Uh*W6@Z zYGZB=kS3UgC~JNnx>eCZarK^s{u4>G2?Y+CA7Yc7&Y>yK zxwln$<%>0@PDr_Q3)dL2N0T{GcY93SxbO*9MMI-p(a`SHsZ)F5lZiQa>`aJ@PROoguT)Q<=bJ_B zs3T17=o}l3&sbPkD5$QfX-SXPcA{>E=%ZWnY_q(4l29ltIQAGt92fKhBJ^j#HRAh} z5DMHzC|NtY(h$&L)JLOxBK%&$Hru`Ni~bWr@up3ieBXMu# z1BR(lrU8S=RH_GDTjU!(_+B=Uz(u%t)QoNUeEtI{s&XUOwX$NZiO1)!Lm z(qzTMUZsvw3fd}GP(1Ox#D5}9oF;KB%yV)v7CG1mo2l>aiEI^pw)jv?FK}%4k-nNU zD#o^pm`-J-{;#oPsDAsw|0~+=Dlvy*-12YiNEm^kM5?6P8EY%bwfxQ@0I`J zUByaMvapEe*Mxo|0PA`lHG!8lh?W4pmp@HIs75})C?niA2ddXJ-NGf(P5*y_^b^P~ zWFs`V>n?w`=7UpPHgCQFBXL4g#Fcc?cp(oLT%$_eENyuN-R)KE1~J3EO~Zwg%~6pi zP|i2A+}qV$j)H|hWV!d>@q8>|3sh#&9pZU%lr)exQ|khT%Ruhw@CBo;udh!~?OJ|D zFObq@Z|b6EksUKZlJ?BZ5IEP&Px$%y`TF_Y>T6CBGc*bTww+`VJANT2C#QnJI7Y6< z;c%$dCr^@q5Fil@I`W?R7>anQwB%!EY}^YrUL^T?SJwz#Qn ze*O#-z~k5Q@-|~In4yzn>XwABENkmPcF+8mePgJ(h$&Ehs;H||&CbqlPUjyva%6iK zsn1j$FpQ`^+JdsEo zav4+h$;OlDCWj9nzA!a46{*|y^yydK0>K`gEHPt*YGq;s@*G`YsI57MF93l%bTSI; zZ`Z<^@1cl2tUpx?cd5 z_s~zrp^bBZ=Fs(q)Z`ZT5va{yqf$|J*gzrshA`+iPV5g@!f(CbdmpTVlQrI;qD&_9 zjg75QI_z4^`vS;Jdgts89z5t98d}`vpwJ#47N*xZW|Qg9Xra=sGT;ObeFo@Sd;5#Jp4c`J~ac!_Ya1L1I>H#Vy;@*)a~yl45qys+Zov6Yy?gpXYy_OIHP9F zET{qMT4sP1uJPqdf6T}X9N_7jnR!?)xWn&v&?Vx@>HC0@^6>J~vGX!DHg@%%gEA|g zHPz5FRxmvWyLJzNwE|s32pP#?tn%eU%6yGzhcMT$;j5>Vv*m@Y*p@UPu1brMG-0=W##xWiO;0bsZ z;pgw``>ExbnF>`|O3c;x2H?w11YJdZr;;ZIv+4Qs=R=QLN{G{yL|tG~|KH~E9~iwg zJqIm~Lg{KLr*w9Advteq@2>e}2U~163fsOffY^Lx&@yk8=H}*Zs;sPh0Z?S$sHjTS zub;45r~^_-udlzqRvzp&svfFjv6RRA8#HjDI#06deq_2CT3c(BVL8gXw6z=gd^htR zmfT0`7raXUUglkU4Dq`yByTIyyxCqoy=0JVi@Y5Jai=NKpmG{)7BzgBurPnx{Mm}}+u7MQ0#ebj#zvQ0k-9Qquv@sGqWVx$49=iPUUv?-c`msV=i%63$o~3FUeH^Unq6&DNw7#SQ$6$= zfZ2(Fy4Sa|@>vdgZ0@&WMi7^JC8O1H8p4+=A~MNfj} zP)MrFWf>uel9oQhLEkj^WuIU%$I8SOb-dmiS2Y3$5YLo~er7R3Qy-y-!-7HlC14Ij z;!Cr*bYX8PTfAqWwn;o$NYTUA?Y6^oJyLHMvhJiq>zd}~a|0=_%YUsI#Ka1m)!d}C zQ0t-VVT7qU516;btS8v*l^SpQhWjHur^kb)-Ge`gn*3mA;lO$VkFb}ZrrhOT8Cst8 zr-kFZhIHG)dCd96>$EXue!t$+!#rbWS2-V|s`{EC@DEI#DhNAqrEZ(F9rHFq3pP&0 zaq>cZ5)u-Q_V)G;*|T62l7iZ)S(xAra&nF1X&#y@A5xbL1by6 z+QKz2R1n(O*f<4|cHrf}OOXg`&SRZDd$ypuy1F?%T0ud`Yhs7J&c|6ggtAL%o2-j!I05YSECLgAL>KJ!}yUmB?;1T^$^ z(xPk{!shqiA7~l@(d0e;S2;e=J_o$O`7vAvFI`VNE+q}Wc3{ub>GTRZ{U~n82K4DQ zVPZjh`rdXOq$-FbpBNk4bpHH#Un0>$ERke6m!_!Q@IaCQd)CE^7c1)PvADv2C@brr z_e-Md-ZMtyhHI@2-Wwg)^sg(6iZvfB?E!Y!SCc6)O)A)I%;xVP4ZB%hUM`W{x_R>^ zl8NIAFOJmL)F{51+TpNodDJ8sklcb@$*;O>G9Z3UATZUn5$pRuquAS?{asIUvW1vn zu!G;Pht_=cwUf&CS%=%#XU^1NNuXxRS1cXu`9Gui#!dRSg^yAq8o1sU T=y&05)*Z5O{Icwef1Ud`L`2`O literal 0 HcmV?d00001 diff --git a/docs/diagrams/sequenceDiagram_setBudget.jpg b/docs/diagrams/sequenceDiagram_setBudget.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5df71ed486015549c2c8038a43aa8493876cda2b GIT binary patch literal 68606 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 Date: Sat, 13 Apr 2024 15:25:46 +0800 Subject: [PATCH 20/46] Fix bug where warnings were intepreted as errors --- .../DeleteExpenseCommandCreator.java | 19 ++++++++----------- .../ReduceSavingCommandCreator.java | 11 +++++------ 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/commandcreator/DeleteExpenseCommandCreator.java b/src/main/java/seedu/budgetbuddy/commandcreator/DeleteExpenseCommandCreator.java index 4ddd3431a5..0ae1f02a89 100644 --- a/src/main/java/seedu/budgetbuddy/commandcreator/DeleteExpenseCommandCreator.java +++ b/src/main/java/seedu/budgetbuddy/commandcreator/DeleteExpenseCommandCreator.java @@ -24,28 +24,25 @@ public Command handleDeleteExpenseCommand(ExpenseList expenses, String input) { assert input != null : "Input string cannot be null"; String[] parts = input.split("i/", 2); - // Check if the input format is correct (i.e., contains "i/") if (parts.length < 2) { - LOGGER.log(Level.WARNING, "Invalid command format. Expected format: i/"); - System.out.println("Error: Invalid command format. Expected format: i/"); - return null; + // Log and notify the user about the incorrect format without returning null. + LOGGER.log(Level.WARNING, "Invalid command format. Expected format: delete expense i/." ); + System.out.println("Invalid command format. Expected format: delete expense i/."); + return null; // Return null to indicate no command should be executed; assuming your loop can handle this. } try { int index = Integer.parseInt(parts[1].trim()) - 1; - // Check if the index is within the bounds of the expense list. if (index < 0 || index >= expenses.size()) { - LOGGER.log(Level.WARNING, "Index is out of bounds."); - System.out.println("Error: Index is out of bounds."); + LOGGER.log(Level.WARNING, "Index is out of bounds. Please try again."); + System.out.println("Index is out of bounds. Please try again."); return null; } LOGGER.log(Level.INFO, "Successfully processed DeleteExpenseCommand"); - // If the index is valid, return a new DeleteExpenseCommand. return new DeleteExpenseCommand(expenses, index); } catch (NumberFormatException e) { - LOGGER.log(Level.SEVERE, "Index is not a valid number."); - // Catch the NumberFormatException if the part after "i/" isn't a valid integer. - System.out.println("Error: Index is not a valid number."); + LOGGER.log(Level.WARNING, "Index is not a valid number. Please try again."); + System.out.println("Index is not a valid number. Please try again."); return null; } } diff --git a/src/main/java/seedu/budgetbuddy/commandcreator/ReduceSavingCommandCreator.java b/src/main/java/seedu/budgetbuddy/commandcreator/ReduceSavingCommandCreator.java index 5ac3806c3f..a0552f91aa 100644 --- a/src/main/java/seedu/budgetbuddy/commandcreator/ReduceSavingCommandCreator.java +++ b/src/main/java/seedu/budgetbuddy/commandcreator/ReduceSavingCommandCreator.java @@ -45,27 +45,26 @@ public Command handleReduceSavingCommand(SavingList savings, String input) { // Validate the index range and that the amount is positive. if (indexToReduce < 0 || indexToReduce >= savings.size()) { LOGGER.log(Level.WARNING, "Index is out of bounds."); - System.out.println("Error: Index is out of bounds."); + System.out.println("Index is out of bounds. Please try again."); return null; } if (amountToReduce <= 0) { LOGGER.log(Level.WARNING, "Amount must be a positive value."); - System.out.println("Error: Amount must be a positive value."); + System.out.println("Amount must be a positive value."); return null; } LOGGER.log(Level.INFO, "Successfully processed ReduceSavingCommand!"); return new ReduceSavingCommand(savings, indexToReduce, amountToReduce); } catch (NumberFormatException e){ - LOGGER.log(Level.SEVERE, "Index and amount must be valid numbers."); - // Catch and handle incorrect number formats for index or amount. - System.out.println("Error: Index and amount must be valid numbers."); + LOGGER.log(Level.WARNING, "Index and amount must be valid numbers. Please try again."); + System.out.println("Index and amount must be valid numbers."); return null; } } else { LOGGER.log(Level.WARNING, "Invalid command format. Expected format: reduce i/ a/"); // Handle the case where the input does not contain the required markers. - System.out.println("Error: Invalid command format. Expected format: reduce i/ a/"); + System.out.println("Invalid command format. Expected format: reduce savings i/ a/"); return null; } } From 565edaf39f094a8c4f82f88dba5903e62a195575 Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Sat, 13 Apr 2024 15:40:57 +0800 Subject: [PATCH 21/46] Reorganise the sequence in DG --- docs/DeveloperGuide.md | 194 +++++++++++++++++++---------------------- 1 file changed, 89 insertions(+), 105 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 1f849f154c..095ba79bf2 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -326,6 +326,95 @@ currencies within the budget management application. ## 4. Implementation +### Add Expense Feature + +The Add Expense Feature allows users to add expenses to different categories. `AddExpenseCommand` class enables this feature, +after initialized by the `Parser` class. Within the `AddExpense` object, the `Parser` would have initialized it with +4 variables, an `ExpenseList` object, along with a `category`, `amount` , `description`. +The relevance of these Class Attributes in `AddExpenseCommand` is as follows : + +| Class Attribute | Variable Type | Relevance | +|-----------------|---------------|---------------------------------------------------| +| expenses | ExpenseList | ExpenseList Object containing the list of expenses| +| category | String | The category that the `expense` belongs to | +| amount | String | The amount spent | +| description | String | The description of the expense | + + +Upon the call of the `execute()` method in `BudgetBuddy` using `command.execute()`, +the `AddExpenseCommand` Object utilizes the following method from the `ExpenseList` class to add it to the existing +list of `expenses` matching against the corresponding `category`. + +| Method | Return Type | Relevance | +|--------------|-------------|-------------------------------------------------| +| addExpense() | void | Add expense to the existing list of `expenses` | + +The following UML Sequence diagram shows how the Parser works to obtain the relevant inputs for the Add Expense Feature : +![Sequence Diagram for Parser for Add Expense Feature](docs\diagram\sequenceDiagram_AddExpense.png) + +The following is a step-by-step explanation for the Parser for the Find Feature : +1. `BudgetBuddy` calls `Parser#parseCommand(input)` with `input` being the entire user input. +E.g `add expense c/Transport a/20 d/EZ-Link Top Up` +2. Within the `Parser`, it will have determined that the `input` is a Find Command from the `isAddExpenseCommand(input)` +function. +3. The `Parser` then self calls the method `handleAddExpenseCommand(input)` with the `input` still being the entire +user input. +4. Within `AddExpenseCommand(input)`, the first check would be the check for the existence of any combination of +`c/ , a/ and d/`. If none of these combinations were found, it immediately returns `null`. +5. If the checks in `4.` is passed, Three variables would be initialized. + + * | Variable Name | Variable Type | + |---------------|---------------| + | category | String | + | amount | String | + | description | String | +6. Depending on which parameters were present, the corresponding input would be extracted and placed into each variable +using the `Parser#extractDetailsForAdd(input, "parameter")` +7. Finally, `Parser#handleAddExpenseCommand()` returns a `AddExpensesCommand` to `Parser#parseCommand()`, which is +then returned to `BudgetBuddy` + +### Add Savings Feature + +The Add Savings Feature allows users to add savings to different categories. `AddSavingCommandCreator` class intialises the `AddSavingCommand`, after initialised by the `Parser` class. Within the `AddSavings` object, the `Parser` would have initialized it with +4 variables, a `SavingList` object, along with a `category`, `amount`. +The relevance of these Class Attributes in `AddExpenseCommand` is as follows : + +| Class Attribute | Variable Type | Relevance | +|-----------------|---------------|---------------------------------------------------| +| savings | SavingList | SavingList Object containing the list of savings | +| category | String | The category that the `expense` belongs to | +| amount | String | The amount spent | + +Upon the call of the `execute()` method in `BudgetBuddy` using `command.execute()`, +the `AddSavingCommand` Object utilizes the following method from the `SavingList` class to add it to the existing +list of `savings` matching against the corresponding `category`. + +| Method | Return Type | Relevance | +|--------------|-------------|-------------------------------------------------| +| addSaving() | void | Add savings to the existing list of `savings` | + +The following UML Sequence diagram shows how the Parser works to obtain the relevant inputs for the Add Expense Feature : +![Sequence Diagram for Parser for Add Expense Feature](docs\diagram\sequenceDiagram_AddSavings.png) + +The following is a step-by-step explanation for the Parser for the Find Feature : +1. `BudgetBuddy` calls `Parser#parseCommand(input)` with `input` being the entire user input. +E.g `add savings c/Allowance a/20` +2. Within the `Parser`, it will have determined that the `input` is a Find Command from the `isAddSavingsCommand(input)` +function. +3. The `Parser` then self calls the method `handleAddExpenseCommand(input)` with the `input` still being the entire +user input. +4. Within `AddExpenseCommand(input)`, the first check would be the check for the existence of any combination of +`c/ , and a/`. If none of these combinations were found, it immediately returns `null`. +5. If the checks in `4.` is passed, two variables would be initialized. + + * | Variable Name | Variable Type | + |---------------|---------------| + | category | String | + | amount | String | +6. Depending on which parameters were present, the corresponding input would be extracted and placed into each variable +using the `Parser#extractDetailsForAdd(input, "parameter")` +7. Finally, `Parser#handleAddExpenseCommand()` intialises a `AddExpensesCommandCreator` which then returns `AddSavingCommand` to `Parser#parseCommand()`, which is then returned to `BudgetBuddy`. + ### Edit Expense Feature The Edit Expense feature allows users to edit their previously added expenses, specifically the `category`, `amount`, and `description`. This feature is managed by the `EditExpenseCommand` class, which is initialized by the @@ -745,108 +834,3 @@ type fast. It also provides the ability to deal with finances on a singular plat | v2.0 | user | view what expenses i have in each of my recurring expenses list | know what expenses i have put into each list | | v2.0 | user | remove a list from my recurring expenses list | remove underutilized lists or wrongly added lists | - -## Non-Functional Requirements - -{Give non-functional requirements} - -## Glossary - -* *glossary item* - Definition - -## Instructions for manual testing - -{Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing} - -### Add Expense Feature - -#### Implementation - -The Add Expense Feature allows users to add expenses to different categories. `AddExpenseCommand` class enables this feature, -after initialized by the `Parser` class. Within the `AddExpense` object, the `Parser` would have initialized it with -4 variables, an `ExpenseList` object, along with a `category`, `amount` , `description`. -The relevance of these Class Attributes in `AddExpenseCommand` is as follows : - -| Class Attribute | Variable Type | Relevance | -|-----------------|---------------|---------------------------------------------------| -| expenses | ExpenseList | ExpenseList Object containing the list of expenses| -| category | String | The category that the `expense` belongs to | -| amount | String | The amount spent | -| description | String | The description of the expense | - - -Upon the call of the `execute()` method in `BudgetBuddy` using `command.execute()`, -the `AddExpenseCommand` Object utilizes the following method from the `ExpenseList` class to add it to the existing -list of `expenses` matching against the corresponding `category`. - -| Method | Return Type | Relevance | -|--------------|-------------|-------------------------------------------------| -| addExpense() | void | Add expense to the existing list of `expenses` | - -The following UML Sequence diagram shows how the Parser works to obtain the relevant inputs for the Add Expense Feature : -![Sequence Diagram for Parser for Add Expense Feature](docs\diagram\sequenceDiagram_AddExpense.png) - -The following is a step-by-step explanation for the Parser for the Find Feature : -1. `BudgetBuddy` calls `Parser#parseCommand(input)` with `input` being the entire user input. -E.g `add expense c/Transport a/20 d/EZ-Link Top Up` -2. Within the `Parser`, it will have determined that the `input` is a Find Command from the `isAddExpenseCommand(input)` -function. -3. The `Parser` then self calls the method `handleAddExpenseCommand(input)` with the `input` still being the entire -user input. -4. Within `AddExpenseCommand(input)`, the first check would be the check for the existence of any combination of -`c/ , a/ and d/`. If none of these combinations were found, it immediately returns `null`. -5. If the checks in `4.` is passed, Three variables would be initialized. - - * | Variable Name | Variable Type | - |---------------|---------------| - | category | String | - | amount | String | - | description | String | -6. Depending on which parameters were present, the corresponding input would be extracted and placed into each variable -using the `Parser#extractDetailsForAdd(input, "parameter")` -7. Finally, `Parser#handleAddExpenseCommand()` returns a `AddExpensesCommand` to `Parser#parseCommand()`, which is -then returned to `BudgetBuddy` - -### Add Savings Feature - -#### Implementation - -The Add Savings Feature allows users to add savings to different categories. `AddSavingCommandCreator` class intialises the `AddSavingCommand`, after initialised by the `Parser` class. Within the `AddSavings` object, the `Parser` would have initialized it with -4 variables, a `SavingList` object, along with a `category`, `amount`. -The relevance of these Class Attributes in `AddExpenseCommand` is as follows : - -| Class Attribute | Variable Type | Relevance | -|-----------------|---------------|---------------------------------------------------| -| savings | SavingList | SavingList Object containing the list of savings | -| category | String | The category that the `expense` belongs to | -| amount | String | The amount spent | - -Upon the call of the `execute()` method in `BudgetBuddy` using `command.execute()`, -the `AddSavingCommand` Object utilizes the following method from the `SavingList` class to add it to the existing -list of `savings` matching against the corresponding `category`. - -| Method | Return Type | Relevance | -|--------------|-------------|-------------------------------------------------| -| addSaving() | void | Add savings to the existing list of `savings` | - -The following UML Sequence diagram shows how the Parser works to obtain the relevant inputs for the Add Expense Feature : -![Sequence Diagram for Parser for Add Expense Feature](docs\diagram\sequenceDiagram_AddSavings.png) - -The following is a step-by-step explanation for the Parser for the Find Feature : -1. `BudgetBuddy` calls `Parser#parseCommand(input)` with `input` being the entire user input. -E.g `add savings c/Allowance a/20` -2. Within the `Parser`, it will have determined that the `input` is a Find Command from the `isAddSavingsCommand(input)` -function. -3. The `Parser` then self calls the method `handleAddExpenseCommand(input)` with the `input` still being the entire -user input. -4. Within `AddExpenseCommand(input)`, the first check would be the check for the existence of any combination of -`c/ , and a/`. If none of these combinations were found, it immediately returns `null`. -5. If the checks in `4.` is passed, two variables would be initialized. - - * | Variable Name | Variable Type | - |---------------|---------------| - | category | String | - | amount | String | -6. Depending on which parameters were present, the corresponding input would be extracted and placed into each variable -using the `Parser#extractDetailsForAdd(input, "parameter")` -7. Finally, `Parser#handleAddExpenseCommand()` intialises a `AddExpensesCommandCreator` which then returns `AddSavingCommand` to `Parser#parseCommand()`, which is then returned to `BudgetBuddy`. From 3dfaf85052baf957ffc23b04af1bda5e6a46b152 Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Sat, 13 Apr 2024 16:37:15 +0800 Subject: [PATCH 22/46] Update UG --- docs/UserGuide.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 2e1bfbeabf..6b6722cd0b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -79,7 +79,6 @@ Example of Usage: `add expense c/Entertainment a/167 d/Bruno Mars` - ### Add Savings Adds a specified amount to the savings under a particular category. @@ -269,6 +268,9 @@ Format `settle i/Index` * The system will settle the splitted expense corresponding to `Index` * `Index` must be a positive integer +Example of usage: +`settle i/2`: Delete splitexpense of index 2 listed in splittedexpenses tracker + ### Finding expenses : `find expenses` Finds expenses based on their description or amount From b48ddc2c0fa3cb858db191d2c8bd0d6789d768ea Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Sat, 13 Apr 2024 16:43:21 +0800 Subject: [PATCH 23/46] Update JUnit test for filterExpenses_filterByMinAmount --- src/test/java/seedu/budgetbuddy/ExpenseListTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/seedu/budgetbuddy/ExpenseListTest.java b/src/test/java/seedu/budgetbuddy/ExpenseListTest.java index 8397f4de84..828c8b8f09 100644 --- a/src/test/java/seedu/budgetbuddy/ExpenseListTest.java +++ b/src/test/java/seedu/budgetbuddy/ExpenseListTest.java @@ -133,7 +133,7 @@ public void filterExpenses_filterByMinAmount_returnsThreeMatches() throws Budget } - @Test @Disabled + @Test public void filterExpenses_filterByMaxAmount_returnsOneMatches() throws BudgetBuddyException { ExpenseList expenses = new ExpenseList(); expenses.addExpense("Groceries", "100", "Apples"); @@ -141,7 +141,7 @@ public void filterExpenses_filterByMaxAmount_returnsOneMatches() throws BudgetBu expenses.addExpense("Entertainment", "75", "Movie"); expenses.addExpense("Groceries", "100", "apple"); ArrayList filteredExpenses = expenses.filterExpenses("" - , null, 75.00); + , null, 76.00); assertEquals(2, filteredExpenses.size()); From 18ef598079f764e66b54dc8f788c2c2a28bae525 Mon Sep 17 00:00:00 2001 From: itsmejr257 Date: Sat, 13 Apr 2024 16:46:51 +0800 Subject: [PATCH 24/46] 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 25/46] 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 26/46] 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 27/46] 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 From f6844aedeadb11e4b5959bf11babd76fde21ae2c Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Sat, 13 Apr 2024 16:52:04 +0800 Subject: [PATCH 28/46] Revert back the changes for filterExpense --- src/main/java/seedu/budgetbuddy/commons/ExpenseList.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java index e2a40d6f67..286b8b7988 100644 --- a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java +++ b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java @@ -77,9 +77,9 @@ public ArrayList filterExpenses(String description, Double minAmount, D String descriptionInLowerCase = description.toLowerCase(); ArrayList filteredExpenses = new ArrayList<>(this.expenses.stream() .filter(expense -> (expense.getDescription() - .toLowerCase().contains(descriptionInLowerCase))) - .filter(expense -> (minAmount == null || expense.getAmount() > minAmount)) - .filter(expense -> (maxAmount == null || expense.getAmount() < maxAmount)) + .toLowerCase().contains(descriptionInLowerCase))) + .filter(expense -> (minAmount == null || expense.getAmount() >= minAmount)) + .filter(expense -> (maxAmount == null || expense.getAmount() <= maxAmount)) .collect(Collectors.toList())); LOGGER.log(Level.INFO, "Ending filtering and returning filtered expenses"); From 8ddb0d6293ac12203f3e1bf108a3a1911fc313b1 Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Sat, 13 Apr 2024 17:06:03 +0800 Subject: [PATCH 29/46] Update add saving --- .../seedu/budgetbuddy/commons/SavingList.java | 19 +++++++++++++++---- .../seedu/budgetbuddy/ExpenseListTest.java | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/commons/SavingList.java b/src/main/java/seedu/budgetbuddy/commons/SavingList.java index f8d9cdfe61..9c1f68acd1 100644 --- a/src/main/java/seedu/budgetbuddy/commons/SavingList.java +++ b/src/main/java/seedu/budgetbuddy/commons/SavingList.java @@ -15,7 +15,7 @@ public class SavingList { private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); private static final double MAX_AMOUNT = 1_000_000_000_000.0; - + protected ArrayList savings; protected ArrayList categories; protected double initialAmount; @@ -161,9 +161,20 @@ public void addSaving(String category, String amount) throws BudgetBuddyExceptio if (amountDouble > MAX_AMOUNT) { throw new BudgetBuddyException("Amount exceeds the maximum allowed limit of " + MAX_AMOUNT); } - - Saving saving = new Saving(matchedCategory, amountDouble); - savings.add(saving); + + boolean found = false; + for (Saving saving : savings) { + if (saving.getCategory().equalsIgnoreCase(category)) { + saving.setAmount(saving.getAmount() + amountDouble); + found = true; + LOGGER.info("Updated existing saving for category: " + category); + break; + } + } + if (!found) { + Saving saving = new Saving(category, amountDouble); + savings.add(saving); + } } diff --git a/src/test/java/seedu/budgetbuddy/ExpenseListTest.java b/src/test/java/seedu/budgetbuddy/ExpenseListTest.java index 828c8b8f09..9b073d828c 100644 --- a/src/test/java/seedu/budgetbuddy/ExpenseListTest.java +++ b/src/test/java/seedu/budgetbuddy/ExpenseListTest.java @@ -155,7 +155,7 @@ public void filterExpenses_filterByRange_returnsTwoMatches() throws BudgetBuddyE expenses.addExpense("Entertainment", "75", "Movie"); expenses.addExpense("Groceries", "100", "apple"); ArrayList filteredExpenses = expenses.filterExpenses("" - , 49.00, 76.00); + , 49.00, 75.00); assertEquals(2, filteredExpenses.size()); From 54b726942213d6eb1d6dc529454ed7cb2ee9273f Mon Sep 17 00:00:00 2001 From: jasraa Date: Sat, 13 Apr 2024 17:09:47 +0800 Subject: [PATCH 30/46] Handle error when add expense input has invalid characters --- .../commandcreator/AddExpenseCommandCreator.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/seedu/budgetbuddy/commandcreator/AddExpenseCommandCreator.java b/src/main/java/seedu/budgetbuddy/commandcreator/AddExpenseCommandCreator.java index eeb07f6bc1..752a3047e2 100644 --- a/src/main/java/seedu/budgetbuddy/commandcreator/AddExpenseCommandCreator.java +++ b/src/main/java/seedu/budgetbuddy/commandcreator/AddExpenseCommandCreator.java @@ -5,6 +5,8 @@ import seedu.budgetbuddy.command.Command; import seedu.budgetbuddy.exception.BudgetBuddyException; +import java.util.logging.Level; + /** * Creates an AddExpenseCommand object. */ @@ -46,6 +48,10 @@ public Command handleAddExpenseCommand(ExpenseList expenses, String input) { System.out.println("amount is missing."); return null; } + if (input.contains("!") || input.contains("|")) { + System.out.println("Please do not include a ! or | in your input"); + return null; + } try { double amountValue = Double.parseDouble(amount); From 10f2fb5874ec4bf5b815ab8c9c8d9326f0f99d64 Mon Sep 17 00:00:00 2001 From: jasraa Date: Sat, 13 Apr 2024 17:12:33 +0800 Subject: [PATCH 31/46] Remove unused imports --- .../budgetbuddy/commandcreator/AddExpenseCommandCreator.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/commandcreator/AddExpenseCommandCreator.java b/src/main/java/seedu/budgetbuddy/commandcreator/AddExpenseCommandCreator.java index 752a3047e2..ed4a05ed4e 100644 --- a/src/main/java/seedu/budgetbuddy/commandcreator/AddExpenseCommandCreator.java +++ b/src/main/java/seedu/budgetbuddy/commandcreator/AddExpenseCommandCreator.java @@ -5,8 +5,6 @@ import seedu.budgetbuddy.command.Command; import seedu.budgetbuddy.exception.BudgetBuddyException; -import java.util.logging.Level; - /** * Creates an AddExpenseCommand object. */ From a7749ac160206f5262613187c29b6f32e320ade4 Mon Sep 17 00:00:00 2001 From: Dheekshitha2 Date: Sat, 13 Apr 2024 17:45:51 +0800 Subject: [PATCH 32/46] Add saving and loading for budget, reduce savings by category rather than index --- data/BudgetFile.txt | 3 ++ .../java/seedu/budgetbuddy/BudgetBuddy.java | 7 +-- src/main/java/seedu/budgetbuddy/Storage.java | 29 ++++++++++++ .../command/ReduceSavingCommand.java | 21 +++++---- .../budgetbuddy/command/SetBudgetCommand.java | 1 - .../ReduceSavingCommandCreator.java | 45 +++++++------------ .../seedu/budgetbuddy/commons/SavingList.java | 44 ++++++++++-------- .../seedu/budgetbuddy/SavingListTest.java | 31 ++++++++----- 8 files changed, 111 insertions(+), 70 deletions(-) create mode 100644 data/BudgetFile.txt diff --git a/data/BudgetFile.txt b/data/BudgetFile.txt new file mode 100644 index 0000000000..c3a493ad1f --- /dev/null +++ b/data/BudgetFile.txt @@ -0,0 +1,3 @@ +Transport|100.00 +Groceries|1000.00 +Housing|100.00 diff --git a/src/main/java/seedu/budgetbuddy/BudgetBuddy.java b/src/main/java/seedu/budgetbuddy/BudgetBuddy.java index 30ca65b9ae..126c67eddd 100644 --- a/src/main/java/seedu/budgetbuddy/BudgetBuddy.java +++ b/src/main/java/seedu/budgetbuddy/BudgetBuddy.java @@ -22,6 +22,7 @@ public class BudgetBuddy { private Storage savingsStorage; private Storage recurringExpensesStorage; private Storage defaultCurrency; + private Storage budgetStorage; @@ -36,7 +37,7 @@ public BudgetBuddy() { savingsStorage = new Storage("./data/SavingsFile.txt"); recurringExpensesStorage = new Storage("./data/RecurringExpensesFile.txt"); defaultCurrency = new Storage("./data/DefaultCurrency.txt"); - + budgetStorage = new Storage("./data/BudgetFile.txt"); } public void handleCommands(String input) { @@ -53,7 +54,7 @@ public void handleCommands(String input) { expensesStorage.saveExpenses(expenses.getExpenses()); savingsStorage.saveSavings(savings.getSavings()); recurringExpensesStorage.saveRecurringExpenses(recurringExpenseLists); - + budgetStorage.saveBudgets(expenses.getBudgets()); defaultCurrency.saveCurrency(); } catch (IOException e) { System.out.println("Error saving to file."); @@ -72,7 +73,7 @@ public void run() { this.expenses.getExpenses().addAll(expensesStorage.loadExpenses()); this.savings.getSavings().addAll(savingsStorage.loadSavings()); this.recurringExpenseLists = recurringExpensesStorage.loadRecurringExpensesList(); - + this.expenses.getBudgets().addAll(budgetStorage.loadBudgets()); } catch (FileNotFoundException e) { System.out.println("No existing files found. Starting fresh."); diff --git a/src/main/java/seedu/budgetbuddy/Storage.java b/src/main/java/seedu/budgetbuddy/Storage.java index 36b90fff73..0aa10e4e5a 100644 --- a/src/main/java/seedu/budgetbuddy/Storage.java +++ b/src/main/java/seedu/budgetbuddy/Storage.java @@ -7,6 +7,7 @@ import seedu.budgetbuddy.commons.RecurringExpenseLists; import seedu.budgetbuddy.commons.RecurringExpenseList; import seedu.budgetbuddy.commons.DefaultCurrency; +import seedu.budgetbuddy.commons.Budget; import seedu.budgetbuddy.exception.BudgetBuddyException; import seedu.budgetbuddy.exception.InvalidRecurringExpensesFileException; @@ -266,6 +267,34 @@ public void saveSplitExpenses(List splitExpenses) throws IOExcepti writer.close(); } + public List loadBudgets() throws FileNotFoundException { + File file = new File(filePath); + Scanner scanner = new Scanner(file); + List loadedBudgets = new ArrayList<>(); + + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + String[] parts = line.split("\\|"); + String category = parts[0].trim(); + double budgetAmount = Double.parseDouble(parts[1].trim()); + Budget budget = new Budget(category, budgetAmount); + loadedBudgets.add(budget); + } + + scanner.close(); + return loadedBudgets; + } + + public void saveBudgets(List budgets) throws IOException { + FileWriter writer = new FileWriter(filePath); + + for (Budget budget : budgets) { + writer.write(String.format("%s|%.2f\n", budget.getCategory(), budget.getBudget())); + } + + writer.flush(); + writer.close(); + } /** * Loads currency data from the specified file path and sets the default currency accordingly. diff --git a/src/main/java/seedu/budgetbuddy/command/ReduceSavingCommand.java b/src/main/java/seedu/budgetbuddy/command/ReduceSavingCommand.java index 74715f0beb..b01eb29121 100644 --- a/src/main/java/seedu/budgetbuddy/command/ReduceSavingCommand.java +++ b/src/main/java/seedu/budgetbuddy/command/ReduceSavingCommand.java @@ -2,21 +2,26 @@ import seedu.budgetbuddy.commons.SavingList; -public class ReduceSavingCommand extends Command{ - - SavingList savings; - private int index; +public class ReduceSavingCommand extends Command { + private String category; private double amount; + private SavingList savings; + - public ReduceSavingCommand(SavingList savings, int index, double amount) { + public ReduceSavingCommand(SavingList savings, String category, double amount) { this.savings = savings; - this.index = index; + this.category = category; this.amount = amount; } @Override public void execute() { - savings.reduceSavings(index, amount); + if (savings != null) { + savings.reduceSavingsByCategory(category, amount); + } else { + System.out.println("Savings list not initialized."); + } } - } + + diff --git a/src/main/java/seedu/budgetbuddy/command/SetBudgetCommand.java b/src/main/java/seedu/budgetbuddy/command/SetBudgetCommand.java index ec95eb2159..2651f2dece 100644 --- a/src/main/java/seedu/budgetbuddy/command/SetBudgetCommand.java +++ b/src/main/java/seedu/budgetbuddy/command/SetBudgetCommand.java @@ -16,6 +16,5 @@ public SetBudgetCommand(ExpenseList expenseList, String category, double budget) @Override public void execute(){ expenseList.setBudget(this.category, this.budget); - System.out.println("Budget Added :" + category + " of $" + budget); } } diff --git a/src/main/java/seedu/budgetbuddy/commandcreator/ReduceSavingCommandCreator.java b/src/main/java/seedu/budgetbuddy/commandcreator/ReduceSavingCommandCreator.java index a0552f91aa..b28108c4c8 100644 --- a/src/main/java/seedu/budgetbuddy/commandcreator/ReduceSavingCommandCreator.java +++ b/src/main/java/seedu/budgetbuddy/commandcreator/ReduceSavingCommandCreator.java @@ -9,12 +9,12 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -public class ReduceSavingCommandCreator extends CommandCreator{ +public class ReduceSavingCommandCreator extends CommandCreator { private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); private SavingList savings; private String input; - public ReduceSavingCommandCreator(SavingList savings, String input){ + public ReduceSavingCommandCreator(SavingList savings, String input) { this.savings = savings; this.input = input; } @@ -22,32 +22,18 @@ public ReduceSavingCommandCreator(SavingList savings, String input){ public Command handleReduceSavingCommand(SavingList savings, String input) { LOGGER.log(Level.INFO, "Processing handleReduceSavingCommand"); - assert savings != null : "Savings list cannot be null"; - assert input != null : "Input string cannot be null"; - String description = input.replace("reduce", "").trim(); - - // Regular expressions to identify the flags and extract the corresponding values - Pattern indexPattern = Pattern.compile("i/\\s*(\\d+)\\s*"); + Pattern categoryPattern = Pattern.compile("c/\\s*(\\w+)\\s*"); Pattern amountPattern = Pattern.compile("a/\\s*(-?\\d+(\\.\\d+)?)\\s*"); - Matcher indexMatcher = indexPattern.matcher(description); + Matcher categoryMatcher = categoryPattern.matcher(description); Matcher amountMatcher = amountPattern.matcher(description); - if(indexMatcher.find() && amountMatcher.find()) { + if (categoryMatcher.find() && amountMatcher.find()) { try { - String indexToReduceAsString = indexMatcher.group(1); - String amountToReduceAsString = amountMatcher.group(1); - - int indexToReduce = Integer.parseInt(indexToReduceAsString) - 1; - double amountToReduce = Double.parseDouble(amountToReduceAsString); + String categoryToReduce = categoryMatcher.group(1); + double amountToReduce = Double.parseDouble(amountMatcher.group(1)); - // Validate the index range and that the amount is positive. - if (indexToReduce < 0 || indexToReduce >= savings.size()) { - LOGGER.log(Level.WARNING, "Index is out of bounds."); - System.out.println("Index is out of bounds. Please try again."); - return null; - } if (amountToReduce <= 0) { LOGGER.log(Level.WARNING, "Amount must be a positive value."); System.out.println("Amount must be a positive value."); @@ -55,23 +41,22 @@ public Command handleReduceSavingCommand(SavingList savings, String input) { } LOGGER.log(Level.INFO, "Successfully processed ReduceSavingCommand!"); - return new ReduceSavingCommand(savings, indexToReduce, amountToReduce); - } catch (NumberFormatException e){ - LOGGER.log(Level.WARNING, "Index and amount must be valid numbers. Please try again."); - System.out.println("Index and amount must be valid numbers."); + return new ReduceSavingCommand(savings, categoryToReduce, amountToReduce); + } catch (NumberFormatException e) { + LOGGER.log(Level.WARNING, "Amount must be a valid number. Please try again."); + System.out.println("Amount must be a valid number."); return null; } } else { - LOGGER.log(Level.WARNING, "Invalid command format. Expected format: reduce i/ a/"); - // Handle the case where the input does not contain the required markers. - System.out.println("Invalid command format. Expected format: reduce savings i/ a/"); + LOGGER.log(Level.WARNING, "Invalid command format. Expected format: " + + "reduce savings c/ a/."); + System.out.println("Invalid command format. Expected format: reduce savings c/ a/"); return null; } } @Override - public Command createCommand(){ + public Command createCommand() { return handleReduceSavingCommand(savings, input); } - } diff --git a/src/main/java/seedu/budgetbuddy/commons/SavingList.java b/src/main/java/seedu/budgetbuddy/commons/SavingList.java index 3a93f37184..f2f67ced2d 100644 --- a/src/main/java/seedu/budgetbuddy/commons/SavingList.java +++ b/src/main/java/seedu/budgetbuddy/commons/SavingList.java @@ -29,9 +29,6 @@ public SavingList() { this.initialAmount = 0; } - public int size() { - return savings.size(); - } public double getInitialAmount() { return this.initialAmount; @@ -151,6 +148,32 @@ public void addSaving(String category, String amount) throws BudgetBuddyExceptio } } + public void reduceSavingsByCategory(String category, double amount) { + List matchedSavings = savings.stream() + .filter(s -> s.getCategory().equalsIgnoreCase(category)) + .collect(Collectors.toList()); + + if (matchedSavings.isEmpty()) { + System.out.println("No savings found under category: " + category); + return; + } + + boolean allReductionsSuccessful = true; + for (Saving saving : matchedSavings) { + if (saving.getAmount() >= amount) { + saving.setAmount(saving.getAmount() - amount); + } else { + System.out.println("Insufficient amount in " + category + " to reduce by $" + amount); + allReductionsSuccessful = false; + } + } + + if (allReductionsSuccessful) { + System.out.println("Savings reduced successfully for category: " + category); + } + } + + /** * Edits the saving entry at the specified index. This method updates the category and amount * of a saving object within the savings list. If the provided category doesn't exist or the index @@ -206,21 +229,6 @@ public void editSaving(String category, int index, double amount) { } } - // @@author Dheekshitha2 - public void reduceSavings(int index, double amount) { - - if (index >= 0 && index < savings.size()) { - Saving saving = savings.get(index); - if (saving.getAmount() >= amount) { - saving.setAmount(saving.getAmount() - amount); - System.out.println("Savings reduced successfully!"); - } else { - System.out.println("Insufficient savings amount."); - } - } else { - System.out.println("Invalid saving index."); - } - } /** * Analyzes and displays insights into the saved amounts across different categories. diff --git a/src/test/java/seedu/budgetbuddy/SavingListTest.java b/src/test/java/seedu/budgetbuddy/SavingListTest.java index 553bda9943..564a06c15a 100644 --- a/src/test/java/seedu/budgetbuddy/SavingListTest.java +++ b/src/test/java/seedu/budgetbuddy/SavingListTest.java @@ -16,6 +16,7 @@ public class SavingListTest { private static final Logger LOGGER = Logger.getLogger(SavingListTest.class.getName()); + @Test public void calculateRemainingSavings_sufficientFunds_success() { SavingList savingList = new SavingList(); @@ -79,20 +80,30 @@ public void editSaving_validInput_success() throws BudgetBuddyException { } @Test - public void reduceSavings_validIndexAndAmount_success() throws BudgetBuddyException { - + public void reduceSavingsByCategory_nonExistentCategory_failure() throws BudgetBuddyException { SavingList savingList = new SavingList(); - savingList.addSaving("Salary", "500"); // Adding initial savings to work with - savingList.addSaving("Investments", "300"); + savingList.addSaving("Salary", "1000"); // Add a valid category for clarity - int indexToReduce = 2; - double amountToReduce = 100; - double expectedAmountAfterReduction = 200; + // Set up to capture System.out output + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + PrintStream originalOut = System.out; + System.setOut(new PrintStream(outContent)); + + // Attempt to reduce savings for a non-existent category + String nonExistentCategory = "NonExistent"; + savingList.reduceSavingsByCategory(nonExistentCategory, 50); - savingList.reduceSavings(indexToReduce - 1, amountToReduce); + // Restore System.out output to original stream + System.setOut(originalOut); + + String output = outContent.toString(); + assertTrue(output.contains("No savings found under category: " + nonExistentCategory), + "Expected message for non-existent category not found."); - // Assert that the amount after reduction is as expected - assertEquals(expectedAmountAfterReduction, savingList.getSavings().get(indexToReduce - 1).getAmount()); + // Check that no other category was reduced + assertTrue(savingList.getSavings().stream() + .allMatch(saving -> saving.getAmount() == 1000 && saving.getCategory().equals("Salary")), + "No savings should be reduced under a non-existent category."); } @Test From 36106644faf56e0953e7afedb42207e186e5d1ec Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Sat, 13 Apr 2024 18:09:24 +0800 Subject: [PATCH 33/46] Fix split expense with storage --- ...tExpenseFile.txt => SplitExpensesFile.txt} | 0 .../java/seedu/budgetbuddy/BudgetBuddy.java | 4 + src/main/java/seedu/budgetbuddy/Storage.java | 90 +++++++++---------- .../seedu/budgetbuddy/commons/SavingList.java | 8 +- .../budgetbuddy/commons/SplitExpense.java | 57 +++++++----- .../budgetbuddy/commons/SplitExpenseList.java | 12 +-- 6 files changed, 96 insertions(+), 75 deletions(-) rename data/{SplitExpenseFile.txt => SplitExpensesFile.txt} (100%) diff --git a/data/SplitExpenseFile.txt b/data/SplitExpensesFile.txt similarity index 100% rename from data/SplitExpenseFile.txt rename to data/SplitExpensesFile.txt diff --git a/src/main/java/seedu/budgetbuddy/BudgetBuddy.java b/src/main/java/seedu/budgetbuddy/BudgetBuddy.java index 30ca65b9ae..223ed96cbf 100644 --- a/src/main/java/seedu/budgetbuddy/BudgetBuddy.java +++ b/src/main/java/seedu/budgetbuddy/BudgetBuddy.java @@ -21,6 +21,7 @@ public class BudgetBuddy { private Storage expensesStorage; private Storage savingsStorage; private Storage recurringExpensesStorage; + private Storage splitexpensesStorage; private Storage defaultCurrency; @@ -35,6 +36,7 @@ public BudgetBuddy() { expensesStorage = new Storage("./data/ExpenseFile.txt"); savingsStorage = new Storage("./data/SavingsFile.txt"); recurringExpensesStorage = new Storage("./data/RecurringExpensesFile.txt"); + splitexpensesStorage = new Storage("./data/SplitExpensesFile.txt"); defaultCurrency = new Storage("./data/DefaultCurrency.txt"); } @@ -53,6 +55,7 @@ public void handleCommands(String input) { expensesStorage.saveExpenses(expenses.getExpenses()); savingsStorage.saveSavings(savings.getSavings()); recurringExpensesStorage.saveRecurringExpenses(recurringExpenseLists); + splitexpensesStorage.saveSplitExpenses(splitexpenses.getSplitExpenses()); defaultCurrency.saveCurrency(); } catch (IOException e) { @@ -71,6 +74,7 @@ public void run() { defaultCurrency.loadCurrency(); this.expenses.getExpenses().addAll(expensesStorage.loadExpenses()); this.savings.getSavings().addAll(savingsStorage.loadSavings()); + this.splitexpenses.getSplitExpenses().addAll(splitexpensesStorage.loadSplitExpenses()); this.recurringExpenseLists = recurringExpensesStorage.loadRecurringExpensesList(); diff --git a/src/main/java/seedu/budgetbuddy/Storage.java b/src/main/java/seedu/budgetbuddy/Storage.java index 36b90fff73..c18f6f35a4 100644 --- a/src/main/java/seedu/budgetbuddy/Storage.java +++ b/src/main/java/seedu/budgetbuddy/Storage.java @@ -65,6 +65,16 @@ public List loadExpenses() throws FileNotFoundException { return expenses; } + public void saveExpenses(List expenses) throws IOException { + ensureDirectoryExists(); // Ensure directory and file exist before writing + FileWriter writer = new FileWriter(filePath, false); // Overwrite the file + for (Expense expense : expenses) { + writer.write(String.format("%s | %s | %.2f | %s\n", + expense.getDateAdded(), expense.getCategory(), expense.getAmount(), expense.getDescription())); + } + writer.close(); + } + public void resetRecurringExpensesListFile() throws IOException { File file = new File(filePath); file.delete(); @@ -171,19 +181,29 @@ public void saveRecurringExpenses(RecurringExpenseLists recurringExpenseLists) ", file has been reinitialized. Run a command to save your recurringexpenses"); } - } + } - public void saveExpenses(List expenses) throws IOException { - ensureDirectoryExists(); // Ensure directory and file exist before writing - FileWriter writer = new FileWriter(filePath, false); // Overwrite the file - for (Expense expense : expenses) { - writer.write(String.format("%s | %s | %.2f | %s\n", - expense.getDateAdded(), expense.getCategory(), expense.getAmount(), expense.getDescription())); - } - writer.close(); - } + /** + * Saves the default currency to the specified file path. + * + * @throws IOException if an I/O error occurs while writing to the file + */ + public void saveCurrency() throws IOException { + assert filePath != null : "File path should not be null"; + ensureDirectoryExists(); + + FileWriter writer = new FileWriter(filePath, false); + try { + Currency currentCurrency = DefaultCurrency.getDefaultCurrency(); + writer.write("Default Currency: " + currentCurrency); + writer.close(); + + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Problem saving currency code", e); + } + } // Inside Storage.java public List loadSavings() throws FileNotFoundException { @@ -213,29 +233,7 @@ public void saveSavings(List savings) throws IOException { writer.close(); } - /** - * Saves the default currency to the specified file path. - * - * @throws IOException if an I/O error occurs while writing to the file - */ - public void saveCurrency() throws IOException { - assert filePath != null : "File path should not be null"; - - ensureDirectoryExists(); - - FileWriter writer = new FileWriter(filePath, false); - - try { - Currency currentCurrency = DefaultCurrency.getDefaultCurrency(); - writer.write("Default Currency: " + currentCurrency); - writer.close(); - - } catch (Exception e) { - LOGGER.log(Level.SEVERE, "Problem saving currency code", e); - } - } - - + public List loadSplitExpenses() throws FileNotFoundException { File file = new File(filePath); List splitExpenses = new ArrayList<>(); @@ -243,29 +241,31 @@ public List loadSplitExpenses() throws FileNotFoundException { while (scanner.hasNextLine()) { String line = scanner.nextLine(); String[] parts = line.split("\\|"); - // Assuming the order is Date|Amount|Number of People|Description - String amount = parts[1].trim(); - String numberOfPeople = parts[2].trim(); + LocalDate date = LocalDate.parse(parts[0].trim()); + double amount = Double.parseDouble(parts[1].trim()); + int numberOfPeople = Integer.parseInt(parts[2].trim()); String description = parts[3].trim(); - SplitExpense splitExpense = new SplitExpense(amount, numberOfPeople, description); + SplitExpense splitExpense = new SplitExpense(date, amount, numberOfPeople, description); splitExpenses.add(splitExpense); } scanner.close(); return splitExpenses; } + public void saveSplitExpenses(List splitExpenses) throws IOException { - - ensureDirectoryExists(); - - FileWriter writer = new FileWriter(filePath, false); + ensureDirectoryExists(); + + FileWriter writer = new FileWriter(filePath, false); // Overwrite the file for (SplitExpense splitExpense : splitExpenses) { - writer.write(String.format("%s | %s | %s\n", - splitExpense.getAmount(), splitExpense.getNumberOfPeople(), splitExpense.getDescription())); + writer.write(String.format("%s | %.2f | %d | %s\n", + splitExpense.getDateAdded().toString(), + splitExpense.getAmount(), + splitExpense.getNumberOfPeople(), + splitExpense.getDescription())); } writer.close(); - } - + } /** * Loads currency data from the specified file path and sets the default currency accordingly. diff --git a/src/main/java/seedu/budgetbuddy/commons/SavingList.java b/src/main/java/seedu/budgetbuddy/commons/SavingList.java index 9c1f68acd1..3b81a7efc9 100644 --- a/src/main/java/seedu/budgetbuddy/commons/SavingList.java +++ b/src/main/java/seedu/budgetbuddy/commons/SavingList.java @@ -137,10 +137,10 @@ public void addSaving(String category, String amount) throws BudgetBuddyExceptio assert amount != null : "Amount should not be null"; LOGGER.info("Adding saving..."); - String matchedCategory = categories.stream() - .filter(existingCategory -> existingCategory.equalsIgnoreCase(category)) - .findFirst() - .orElseThrow(() -> new BudgetBuddyException("The category '" + category + "' is not listed.")); + if (categories.stream().noneMatch(existingCategory -> existingCategory.equalsIgnoreCase(category))) { + throw new BudgetBuddyException("The category '" + category + "' is not listed."); + } + if (!amount.matches("^\\d+(\\.\\d{1,2})?$")) { throw new BudgetBuddyException("Invalid amount format. Amount should be a number with up" + diff --git a/src/main/java/seedu/budgetbuddy/commons/SplitExpense.java b/src/main/java/seedu/budgetbuddy/commons/SplitExpense.java index 0e49812a2b..8dba021d86 100644 --- a/src/main/java/seedu/budgetbuddy/commons/SplitExpense.java +++ b/src/main/java/seedu/budgetbuddy/commons/SplitExpense.java @@ -1,18 +1,34 @@ package seedu.budgetbuddy.commons; -public class SplitExpense extends Transaction{ - private final String amount; - private final String description; - private final String numberOfPeople; - - public SplitExpense(String amount, String numberOfPeople, String description) { - super("Split Expense", Double.parseDouble(amount)); - this.amount = amount; +import java.time.LocalDate; +import java.math.BigDecimal; +import java.math.RoundingMode; + +public class SplitExpense extends Transaction { + protected String description; + private int numberOfPeople; + private LocalDate dateAdded; + + public SplitExpense(LocalDate dateAdded, double totalAmount, int numberOfPeople, String description) { + super("Shared Bill", calculateAmountPerPerson(totalAmount, numberOfPeople)); + this.dateAdded = dateAdded; this.numberOfPeople = numberOfPeople; this.description = description; } - public String getNumberOfPeople() { + public SplitExpense(double totalAmount, int numberOfPeople, String description) { + super("Shared Bill", calculateAmountPerPerson(totalAmount, numberOfPeople)); + this.numberOfPeople = numberOfPeople; + this.description = description; + this.dateAdded = LocalDate.now(); + } + + private static double calculateAmountPerPerson(double totalAmount, int numberOfPeople) { + BigDecimal amount = BigDecimal.valueOf(totalAmount); + return amount.divide(BigDecimal.valueOf(numberOfPeople), 2, RoundingMode.HALF_UP).doubleValue(); + } + + public int getNumberOfPeople() { return numberOfPeople; } @@ -20,25 +36,26 @@ public String getDescription() { return description; } - public double calculateAmountPerPerson() { - double amountValue = Double.parseDouble(amount); - double numberOfPeopleValue = Double.parseDouble(numberOfPeople); - - double rawAmountPerPerson = amountValue / numberOfPeopleValue; - - double roundedAmountPerPerson = Math.round(rawAmountPerPerson * 100) / 100.0; - - return roundedAmountPerPerson; + public LocalDate getDateAdded() { + return dateAdded; } public Boolean isExpenseSettled() { return false; } + public double getAmount() { + return amount; + } + @Override public String toString() { - return "Number of People: " + numberOfPeople + " Amount: " + amount + " Description: " + - description + " Amount per person: " + calculateAmountPerPerson(); + return "Number of People: " + numberOfPeople + " Amount per person: " + amount + " Description: " + + description + " Total Amount: " + getTotalAmount(); + } + + public double getTotalAmount() { + return amount * numberOfPeople; } } diff --git a/src/main/java/seedu/budgetbuddy/commons/SplitExpenseList.java b/src/main/java/seedu/budgetbuddy/commons/SplitExpenseList.java index ee1d96dc7e..b35abe8437 100644 --- a/src/main/java/seedu/budgetbuddy/commons/SplitExpenseList.java +++ b/src/main/java/seedu/budgetbuddy/commons/SplitExpenseList.java @@ -37,7 +37,7 @@ public void listSplitExpenses() { LOGGER.info("Listing splitexpenses..."); try { - System.out.println("Split Expenses: "); + System.out.println("Shared Bills: "); for (int i = 0; i < splitexpenses.size(); i++) { SplitExpense splitexpense = splitexpenses.get(i); @@ -46,10 +46,9 @@ public void listSplitExpenses() { continue; } System.out.print(i+1 + " | "); - System.out.print("Amount: " + splitexpense.getAmount()); - System.out.print(" Number of People: " + splitexpense.getNumberOfPeople()); System.out.print(" Description: " + splitexpense.getDescription()); - System.out.println(" Amount per person: " + splitexpense.calculateAmountPerPerson()); + System.out.print(" Number of People: " + splitexpense.getNumberOfPeople()); + System.out.println(" Amount per person: " + splitexpense.getAmount()); } System.out.println("-----------------------------------------------------------------------------"); @@ -64,6 +63,7 @@ public void addSplitExpense(String amount, String numberOfPeople, String descrip LOGGER.info("Adding split expense..."); double amountDouble; + int numberOfPeopleInt; try{ amountDouble = Double.parseDouble(amount); } catch (NumberFormatException e) { @@ -75,7 +75,7 @@ public void addSplitExpense(String amount, String numberOfPeople, String descrip } try { - Integer.parseInt(numberOfPeople); + numberOfPeopleInt = Integer.parseInt(numberOfPeople); if (Integer.parseInt(numberOfPeople) < 0) { throw new BudgetBuddyException("Number of people should be a positive number"); } @@ -83,7 +83,7 @@ public void addSplitExpense(String amount, String numberOfPeople, String descrip throw new BudgetBuddyException("Number of people should be a number"); } - SplitExpense splitexpense = new SplitExpense(amount, numberOfPeople, description); + SplitExpense splitexpense = new SplitExpense(amountDouble, numberOfPeopleInt, description); splitexpenses.add(splitexpense); } From 4c3827ece0e3eb6af2fc3fbd8a3c855d941da56f Mon Sep 17 00:00:00 2001 From: jasraa Date: Sat, 13 Apr 2024 18:23:10 +0800 Subject: [PATCH 34/46] Improve error handling for Edit Expense function --- .../EditExpenseCommandCreator.java | 94 ++++++++++++++++--- .../budgetbuddy/commons/ExpenseList.java | 2 +- 2 files changed, 81 insertions(+), 15 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/commandcreator/EditExpenseCommandCreator.java b/src/main/java/seedu/budgetbuddy/commandcreator/EditExpenseCommandCreator.java index aa47ef43cf..6768573a77 100644 --- a/src/main/java/seedu/budgetbuddy/commandcreator/EditExpenseCommandCreator.java +++ b/src/main/java/seedu/budgetbuddy/commandcreator/EditExpenseCommandCreator.java @@ -3,6 +3,7 @@ import seedu.budgetbuddy.commons.ExpenseList; import seedu.budgetbuddy.command.Command; import seedu.budgetbuddy.command.EditExpenseCommand; +import seedu.budgetbuddy.exception.BudgetBuddyException; public class EditExpenseCommandCreator extends CommandCreator { private ExpenseList expenses; @@ -23,6 +24,15 @@ public EditExpenseCommandCreator(String input, ExpenseList expenses) { * is invalid or incomplete. */ public Command handleEditExpenseCommand(ExpenseList expenses, String input) { + try { + checkForInvalidInputs(input); + checkForValidCategory(input); + checkForInvalidAmount(input); + } catch (IllegalArgumentException | BudgetBuddyException e) { + System.out.println(e.getMessage()); + System.out.println("Command Format : edit expense c/CATEGORY i/INDEX a/AMOUNT d/DESCRIPTION"); + return null; + } String[] parts = input.split(" "); String category = null; int index = -1; @@ -33,34 +43,90 @@ public Command handleEditExpenseCommand(ExpenseList expenses, String input) { if (part.startsWith("c/")) { category = part.substring(2); } else if (part.startsWith("i/")) { - try { - index = Integer.parseInt(part.substring(2)); - } catch (NumberFormatException e) { - // Handle invalid index format - return null; - } + index = Integer.parseInt(part.substring(2)); // Removed the redundant try-catch block } else if (part.startsWith("a/")) { - try { - amount = Double.parseDouble(part.substring(2)); - } catch (NumberFormatException e) { - // Handle invalid amount format - System.out.println("Invalid Amount. Amount should be a numerical value."); - return null; - } + amount = Double.parseDouble(part.substring(2)); } else if (part.startsWith("d/")) { description = part.substring(2); } } - // Validate required fields if (category != null && index != -1 && amount != -1 && description != null) { return new EditExpenseCommand(expenses, category, index, amount, description); } else { // Handle incomplete command + System.out.println("Incomplete command. Please ensure all parameters are included."); return null; } } + + public static void checkForInvalidInputs (String input) throws BudgetBuddyException { + final String CATEGORY_PREFIX = "c/"; + final String INDEX_PREFIX = "i/"; + final String AMOUNT_PREFIX = "a/"; + final String DESCRIPTION_PREFIX = "d/"; + + if (input.contains("!") || input.contains("|")) { + throw new BudgetBuddyException("Please do not include a ! or | in your input"); + } + if (!input.contains("c/") || !input.contains("i/") || !input.contains("a/") || !input.contains("d/")) { + throw new IllegalArgumentException("Please Ensure that you include c/, i/, a/ and d/"); + } + + String [] parameters = {CATEGORY_PREFIX, INDEX_PREFIX, AMOUNT_PREFIX, DESCRIPTION_PREFIX}; + + for (String parameter : parameters) { + if (input.indexOf(parameter) != input.lastIndexOf(parameter)) { + throw new BudgetBuddyException("Please ensure that you do not have duplicate parameters."); + } + } + } + + public static void checkForValidCategory (String input) throws BudgetBuddyException { + String[] parts = input.split(" "); + String category = null; + for (String part : parts) { + if (part.startsWith("c/")) { + category = part.substring(2); + break; + } + } + + if (category == null || !(category.equals("Transport") || category.equals("Housing") || + category.equals("Groceries") || category.equals("Utility") || + category.equals("Entertainment") || category.equals("Others"))) { + throw new BudgetBuddyException("Please enter a valid category: Housing, Groceries, Utility, Transport," + + "Entertainment or Others "); + } + + } + + public static void checkForInvalidAmount(String input) throws BudgetBuddyException { + String[] parts = input.split(" "); + double amount = -1; + + for (String part : parts) { + if (part.startsWith("a/")) { + try { + amount = Double.parseDouble(part.substring(2)); + if (amount <= 0) { // Amount must be greater than 0 + throw new BudgetBuddyException("Invalid Amount. Amount must be greater than 0."); + } + break; // Break after finding the amount to stop checking other parts + } catch (NumberFormatException e) { + throw new BudgetBuddyException("Invalid Amount. Amount should be a numerical value."); + } + } + } + + if (amount == -1) { + // If amount is still -1, it means no amount was entered + throw new BudgetBuddyException("No amount specified. Please enter an amount using a/ prefix."); + } + } + + @Override public Command createCommand() { return handleEditExpenseCommand(expenses, input); diff --git a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java index dedca99ea6..2646a28e5b 100644 --- a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java +++ b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java @@ -234,7 +234,7 @@ public void editExpense(String category, int index, double amount, String descri // Check if the index is within valid bounds if (index <= 0 || index > expenses.size()) { LOGGER.warning("Invalid index: " + index); - System.out.println("Invalid index."); + System.out.println("Invalid index. Enter \"List Expenses\" to view the index."); return; } From b88e8afd395f3ced83faba18d5c576d2051fe35a Mon Sep 17 00:00:00 2001 From: jasraa Date: Sat, 13 Apr 2024 18:56:34 +0800 Subject: [PATCH 35/46] Update PPP --- docs/team/jasraa.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/team/jasraa.md b/docs/team/jasraa.md index 7f57744700..03c3c87b84 100644 --- a/docs/team/jasraa.md +++ b/docs/team/jasraa.md @@ -49,10 +49,19 @@ within the command line interface, eliminating the need for external tools or vi [RepoSense Link](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=jasraa&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2024-02-23&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) #### Enhancements to existing features -(to be updated) +1. Wrote Junit tests for Edit Expenses, Edit Savings, Get Expenses Insight and Get Savings Insights +2. Implemented Bug fixes for "Edit Expenses", "Edit Savings", "Storage", "Get Expenses Insights" and +"Get Savings Insights" #### Contributions to the UG -(to be updated) +Added documentation for the features `edit expense`, `edit savings`, `get expenses insight` +and `get savings insights` #### Contributions to the DG -(to be updated) \ No newline at end of file +Added diagrams and documentation for the features `edit expense`, `edit savings`, `get expenses insight` +and `get savings insights` + +#### Community +1. Communicated with teammates for ideation and enhancement of existing features. +2. Provided DG Peer Review Comments for another team. [CS2113-T15-3 SplitLiang](https://github.com/nus-cs2113-AY2324S2/tp/pull/47) +3. Reported bugs for another team during PE-D. [CS2113-T15-1 LongAh](https://github.com/AY2324S2-CS2113-T15-1/tp/releases) \ No newline at end of file From e2c8dd16377aa091b06f896a98e5c3b1b03edc39 Mon Sep 17 00:00:00 2001 From: Dheekshitha2 Date: Sat, 13 Apr 2024 18:57:56 +0800 Subject: [PATCH 36/46] Refactor code to seperate check for exceeding budget --- .../command/AddExpenseCommand.java | 1 - .../budgetbuddy/commons/ExpenseList.java | 53 ++++++++++--------- .../exception/BudgetExceededException.java | 7 +++ 3 files changed, 35 insertions(+), 26 deletions(-) create mode 100644 src/main/java/seedu/budgetbuddy/exception/BudgetExceededException.java diff --git a/src/main/java/seedu/budgetbuddy/command/AddExpenseCommand.java b/src/main/java/seedu/budgetbuddy/command/AddExpenseCommand.java index b8a19a7954..2f7af5cd16 100644 --- a/src/main/java/seedu/budgetbuddy/command/AddExpenseCommand.java +++ b/src/main/java/seedu/budgetbuddy/command/AddExpenseCommand.java @@ -22,7 +22,6 @@ public AddExpenseCommand (ExpenseList expenses,String category, String amount, S public void execute() { try { expenses.addExpense(this.category,this.amount,this.description); - System.out.println("Expense Added :" + category + " of $" + amount + " description : " + description); } catch (BudgetBuddyException e) { System.out.println(e.getMessage()); } diff --git a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java index dedca99ea6..e91c1feabd 100644 --- a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java +++ b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java @@ -2,6 +2,7 @@ import seedu.budgetbuddy.Ui; import seedu.budgetbuddy.exception.BudgetBuddyException; +import seedu.budgetbuddy.exception.BudgetExceededException; import java.util.Arrays; @@ -29,7 +30,6 @@ public class ExpenseList { public ExpenseList(ArrayList expenses) { this.expenses = expenses; this.budgets = new ArrayList<>(); - } public ExpenseList() { @@ -150,6 +150,24 @@ public double calculateTotalExpenses() { return totalExpenses; } + private boolean checkBudgetBeforeAddingExpense(String category, double amountAsDouble) { + Budget budgetForCategory = budgets.stream() + .filter(budget -> budget.getCategory().equalsIgnoreCase(category)) + .findFirst() + .orElse(null); + + if (budgetForCategory != null) { + double totalSpent = expenses.stream() + .filter(expense -> expense.getCategory().equalsIgnoreCase(category)) + .mapToDouble(Expense::getAmount) + .sum(); + return totalSpent + amountAsDouble > budgetForCategory.getBudget(); + } + return false; + } + + + //@@author Zhang Yangda public void addExpense(String category, String amount, String description) throws BudgetBuddyException { assert category != null : "Category should not be null"; @@ -170,37 +188,22 @@ public void addExpense(String category, String amount, String description) throw throw new BudgetBuddyException("Expenses should not be negative."); } - // Check against the budget before adding the expense - Budget budgetForCategory = budgets.stream() - .filter(budget -> budget.getCategory().equalsIgnoreCase(category)) - .findFirst() - .orElse(null); - - if (budgetForCategory != null) { - double totalSpent = expenses.stream() - .filter(expense -> expense.getCategory().equalsIgnoreCase(category)) - .mapToDouble(Expense::getAmount) - .sum(); - double projectedTotal = totalSpent + amountAsDouble; - - if (projectedTotal > budgetForCategory.getBudget()) { - ui.printDivider(); - System.out.println("Warning: Adding this expense will exceed your budget for " + category); - ui.printDivider(); - - // Replace with actual user confirmation in your application context - if (!ui.getUserConfirmation()) { - System.out.println("Expense not added due to budget constraints."); - return; // Exit without adding the expense - } + boolean budgetExceeded = checkBudgetBeforeAddingExpense(category, amountAsDouble); + if (budgetExceeded) { + System.out.println("Warning: Adding this expense will exceed your budget for " + category); + boolean userConfirmation = ui.getUserConfirmation(); + if (!userConfirmation) { + System.out.println("Expense not added due to budget constraints."); + return; } } Expense expense = new Expense(category, amountAsDouble, description); expenses.add(expense); - + System.out.println("Expense added: " + category + " ->z $" + String.format("%.2f", amountAsDouble)); } + /** * Edits an expense entry in the expenses list at the specified index. Updates the category, * amount, and description of the expense. diff --git a/src/main/java/seedu/budgetbuddy/exception/BudgetExceededException.java b/src/main/java/seedu/budgetbuddy/exception/BudgetExceededException.java new file mode 100644 index 0000000000..21fa1b5c50 --- /dev/null +++ b/src/main/java/seedu/budgetbuddy/exception/BudgetExceededException.java @@ -0,0 +1,7 @@ +package seedu.budgetbuddy.exception; + +public class BudgetExceededException extends Exception { + public BudgetExceededException(String message) { + super(message); + } +} From 904570a73c8b20840182258c22d36d482d62c8f8 Mon Sep 17 00:00:00 2001 From: Dheekshitha2 Date: Sat, 13 Apr 2024 19:02:54 +0800 Subject: [PATCH 37/46] Remove redundant import --- src/main/java/seedu/budgetbuddy/commons/ExpenseList.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java index e91c1feabd..ba07702179 100644 --- a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java +++ b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java @@ -2,8 +2,6 @@ import seedu.budgetbuddy.Ui; import seedu.budgetbuddy.exception.BudgetBuddyException; -import seedu.budgetbuddy.exception.BudgetExceededException; - import java.util.Arrays; import java.util.List; From 3c98ada5efdbb65c4404fb1673e0e4da6bd893d7 Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Sat, 13 Apr 2024 19:07:07 +0800 Subject: [PATCH 38/46] Fix the split expenses with the currencyconverter --- data/DefaultCurrency.txt | 2 +- src/main/java/seedu/budgetbuddy/Parser.java | 2 +- .../command/ChangeCurrencyCommand.java | 6 +- .../ChangeCurrencyCommandCreator.java | 14 ++-- .../commons/CurrencyConverter.java | 66 +++++++++---------- .../budgetbuddy/commons/SplitExpenseList.java | 20 +++++- .../ChangeCurrencyCommandCreatorTest.java | 16 +++-- .../budgetbuddy/SplitExpenseListTest.java | 5 +- 8 files changed, 79 insertions(+), 52 deletions(-) diff --git a/data/DefaultCurrency.txt b/data/DefaultCurrency.txt index 822166bb78..00eacb6acb 100644 --- a/data/DefaultCurrency.txt +++ b/data/DefaultCurrency.txt @@ -1 +1 @@ -Default Currency: SGD \ No newline at end of file +Default Currency: USD \ No newline at end of file diff --git a/src/main/java/seedu/budgetbuddy/Parser.java b/src/main/java/seedu/budgetbuddy/Parser.java index f009f63c06..7c7d051376 100644 --- a/src/main/java/seedu/budgetbuddy/Parser.java +++ b/src/main/java/seedu/budgetbuddy/Parser.java @@ -234,7 +234,7 @@ public Command parseCommand(ExpenseList expenses, SavingList savings, SplitExpen } if (isConvertCurrencyCommand(input.toLowerCase())) { - CommandCreator commandCreator = new ChangeCurrencyCommandCreator(input, savings, expenses, expensesList, + CommandCreator commandCreator = new ChangeCurrencyCommandCreator(input, savings, expenses, splitexpenses, expensesList, new CurrencyConverter()); return commandCreator.createCommand(); } diff --git a/src/main/java/seedu/budgetbuddy/command/ChangeCurrencyCommand.java b/src/main/java/seedu/budgetbuddy/command/ChangeCurrencyCommand.java index d422447360..86c1b79d90 100644 --- a/src/main/java/seedu/budgetbuddy/command/ChangeCurrencyCommand.java +++ b/src/main/java/seedu/budgetbuddy/command/ChangeCurrencyCommand.java @@ -4,6 +4,7 @@ import seedu.budgetbuddy.commons.DefaultCurrency; import seedu.budgetbuddy.commons.ExpenseList; import seedu.budgetbuddy.commons.SavingList; +import seedu.budgetbuddy.commons.SplitExpenseList; import seedu.budgetbuddy.commons.RecurringExpenseLists; import java.util.Currency; @@ -13,14 +14,16 @@ public class ChangeCurrencyCommand extends Command { private Currency newCurrency; private SavingList savings; private ExpenseList expenses; + private SplitExpenseList splitExpenses; private RecurringExpenseLists recurringExpenseLists; private CurrencyConverter currencyConverter; - public ChangeCurrencyCommand(Currency newCurrency, SavingList savings, ExpenseList expenses, + public ChangeCurrencyCommand(Currency newCurrency, SavingList savings, ExpenseList expenses, SplitExpenseList splitExpenses, RecurringExpenseLists recurringExpenseLists, CurrencyConverter currencyConverter) { this.newCurrency = newCurrency; this.savings = savings; this.expenses = expenses; + this.splitExpenses = splitExpenses; this.recurringExpenseLists = recurringExpenseLists; this.currencyConverter = currencyConverter; } @@ -29,6 +32,7 @@ public ChangeCurrencyCommand(Currency newCurrency, SavingList savings, ExpenseLi public void execute() { currencyConverter.convertSavingCurrency(newCurrency, savings); currencyConverter.convertExpenseCurrency(newCurrency, expenses); + currencyConverter.convertSplitExpenseCurrency(newCurrency, splitExpenses); currencyConverter.convertRecurringExpensesCurrency(newCurrency, recurringExpenseLists); currencyConverter.convertBudgetCurrency(newCurrency, expenses); DefaultCurrency.setDefaultCurrency(newCurrency); diff --git a/src/main/java/seedu/budgetbuddy/commandcreator/ChangeCurrencyCommandCreator.java b/src/main/java/seedu/budgetbuddy/commandcreator/ChangeCurrencyCommandCreator.java index 76d8ce7c5f..93f1a2a140 100644 --- a/src/main/java/seedu/budgetbuddy/commandcreator/ChangeCurrencyCommandCreator.java +++ b/src/main/java/seedu/budgetbuddy/commandcreator/ChangeCurrencyCommandCreator.java @@ -4,6 +4,7 @@ import seedu.budgetbuddy.commons.ExpenseList; import seedu.budgetbuddy.commons.RecurringExpenseLists; import seedu.budgetbuddy.commons.SavingList; +import seedu.budgetbuddy.commons.SplitExpenseList; import seedu.budgetbuddy.command.ChangeCurrencyCommand; import seedu.budgetbuddy.command.Command; @@ -16,16 +17,18 @@ public class ChangeCurrencyCommandCreator extends CommandCreator { private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); private ExpenseList expenses; private SavingList savings; + private SplitExpenseList splitExpenses; private RecurringExpenseLists recurringExpenseLists; private String input; private CurrencyConverter newCurrency; - public ChangeCurrencyCommandCreator(String input, SavingList savings, ExpenseList expenses - , RecurringExpenseLists recurringExpenseLists, CurrencyConverter newCurrency) { + public ChangeCurrencyCommandCreator(String input, SavingList savings, ExpenseList expenses, SplitExpenseList splitExpenses, + RecurringExpenseLists recurringExpenseLists, CurrencyConverter newCurrency) { this.input = input; this.savings = savings; this.expenses = expenses; + this.splitExpenses = splitExpenses; this.recurringExpenseLists = recurringExpenseLists; this.newCurrency = newCurrency; @@ -42,6 +45,7 @@ public ChangeCurrencyCommandCreator(String input, SavingList savings, ExpenseLis * @return A ChangeCurrencyCommand if the input is valid; otherwise, null. */ public Command handleChangeCurrencyCommand(String input, SavingList savingList, ExpenseList expenseList, + SplitExpenseList splitExpenses, RecurringExpenseLists recurringExpenseLists, CurrencyConverter currencyConverter) { if (input.toLowerCase().startsWith("change currency")) { @@ -56,8 +60,8 @@ public Command handleChangeCurrencyCommand(String input, SavingList savingList, Currency newCurrency = Currency.getInstance(currencyCode.toUpperCase()); assert newCurrency != null : "Currency code should be valid"; LOGGER.log(Level.INFO, "Default currency changed to " + newCurrency); - return new ChangeCurrencyCommand(newCurrency, savingList, expenseList, recurringExpenseLists, - currencyConverter); + return new ChangeCurrencyCommand(newCurrency, savingList, expenseList, splitExpenses, recurringExpenseLists + , currencyConverter); } catch (IllegalArgumentException e) { LOGGER.log(Level.WARNING, "Invalid currency code: " + currencyCode); System.out.println("Invalid currency code."); @@ -73,6 +77,6 @@ public Command handleChangeCurrencyCommand(String input, SavingList savingList, } @Override public Command createCommand() { - return handleChangeCurrencyCommand(input, savings, expenses, recurringExpenseLists, newCurrency); + return handleChangeCurrencyCommand(input, savings, expenses, splitExpenses, recurringExpenseLists, newCurrency); } } diff --git a/src/main/java/seedu/budgetbuddy/commons/CurrencyConverter.java b/src/main/java/seedu/budgetbuddy/commons/CurrencyConverter.java index 11f2f7c24d..a955b78313 100644 --- a/src/main/java/seedu/budgetbuddy/commons/CurrencyConverter.java +++ b/src/main/java/seedu/budgetbuddy/commons/CurrencyConverter.java @@ -102,6 +102,38 @@ public void convertExpenseCurrency(Currency newCurrency, ExpenseList expenses) { } } + public void convertSplitExpenseCurrency(Currency newCurrency, SplitExpenseList splitExpenses) { + if (splitExpenses == null) { + throw new IllegalArgumentException("SplitExpenseList cannot be null"); + } + + assert splitExpenses != null : "SplitExpenseList cannot be null"; + + if (DefaultCurrency.getDefaultCurrency() == newCurrency) { + System.out.println("Same currency for Split Expenses. No Conversion needed"); + return; + } else { // Convert the currency of each split expense in the SplitExpenseList + for (SplitExpense splitExpense : splitExpenses.getSplitExpenses()) { + if (splitExpense == null) { + LOGGER.warning("Skipping null split expense"); + System.out.println("Skipping null split expense"); + continue; + } + + try { + double convertedAmount = convertAmount(splitExpense.getAmount(), splitExpense.getCurrency(), + newCurrency); + splitExpense.setAmount(convertedAmount); + splitExpense.setCurrency(newCurrency); + } catch (IllegalArgumentException e) { + LOGGER.severe("Error converting amount for split expense: " + e.getMessage()); + System.out.println("Error converting amount for split expense: " + e.getMessage()); + } + } + System.out.println("Default currency for Split Expenses changed to " + newCurrency); + } + } + /** * Converts the currency of savings in the given SavingList to the specified new currency. * No conversion necessary if trying to convert to the same currency. @@ -139,38 +171,6 @@ public void convertSavingCurrency(Currency newCurrency, SavingList savings) { } } - public void convertSplitExpenseCurrency(Currency newCurrency, SplitExpenseList splitExpenses) { - if (splitExpenses == null) { - throw new IllegalArgumentException("SplitExpenseList cannot be null"); - } - - if (DefaultCurrency.getDefaultCurrency() == newCurrency) { - System.out.println("Same currency for Split Expenses. No Conversion needed"); - return; - } - - for (SplitExpense splitExpense : splitExpenses.getSplitExpenses()) { - if (splitExpense == null) { - LOGGER.warning("Skipping null split expense"); - System.out.println("Skipping null split expense"); - continue; - } - - try { - double convertedAmount = convertAmount(splitExpense.getAmount(), splitExpense.getCurrency(), - newCurrency); - splitExpense.setAmount(convertedAmount); - splitExpense.setCurrency(newCurrency); - } catch (IllegalArgumentException e) { - // Handle any IllegalArgumentException thrown during conversion - LOGGER.severe("Error converting amount for split expense: " + e.getMessage()); - System.out.println("Error converting amount for split expense: " + e.getMessage()); - } - } - - System.out.println("Default currency for Split Expenses changed to " + newCurrency); - } - public void convertRecurringExpensesCurrency(Currency newCurrency, RecurringExpenseLists recurringExpenseLists) { if (recurringExpenseLists == null) { @@ -192,7 +192,7 @@ public void convertRecurringExpensesCurrency(Currency newCurrency, RecurringExpe System.out.println("Default currency for Recurring Expenses changed to " + newCurrency); } - + public void convertBudgetCurrency(Currency newCurrency, ExpenseList expenseList) { if (expenseList == null) { throw new IllegalArgumentException("ExpenseList cannot be null"); diff --git a/src/main/java/seedu/budgetbuddy/commons/SplitExpenseList.java b/src/main/java/seedu/budgetbuddy/commons/SplitExpenseList.java index b35abe8437..f2b3f02e68 100644 --- a/src/main/java/seedu/budgetbuddy/commons/SplitExpenseList.java +++ b/src/main/java/seedu/budgetbuddy/commons/SplitExpenseList.java @@ -1,8 +1,10 @@ package seedu.budgetbuddy.commons; + import java.util.ArrayList; import java.util.List; +import seedu.budgetbuddy.Ui; import seedu.budgetbuddy.exception.BudgetBuddyException; import java.util.logging.Level; @@ -10,6 +12,8 @@ public class SplitExpenseList { + Ui ui = new Ui(); + private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); protected ArrayList splitexpenses; public SplitExpenseList(ArrayList splitexpenses){ @@ -33,10 +37,22 @@ public SplitExpense getSplitExpenseListAtListNumber(int listNumber) { return splitexpenses.get(listNumberAsArrayPosition); } + /** + * Lists all the expenses in the list + * @return void + * @throws BudgetBuddyException if there is an error while listing expenses + * @param void + * @return void + * @throws BudgetBuddyException if there is an error while listing expenses + */ + public void listSplitExpenses() { LOGGER.info("Listing splitexpenses..."); try { + ui.printDivider(); + System.out.println(String.format("Current Currency: %s\n", DefaultCurrency.getDefaultCurrency())); + System.out.println("Shared Bills: "); for (int i = 0; i < splitexpenses.size(); i++) { SplitExpense splitexpense = splitexpenses.get(i); @@ -48,9 +64,9 @@ public void listSplitExpenses() { System.out.print(i+1 + " | "); System.out.print(" Description: " + splitexpense.getDescription()); System.out.print(" Number of People: " + splitexpense.getNumberOfPeople()); - System.out.println(" Amount per person: " + splitexpense.getAmount()); + System.out.print(" Amount: $" + String.format("%.2f", splitexpense.getAmount()) + "\n"); } - System.out.println("-----------------------------------------------------------------------------"); + ui.printDivider(); } catch (Exception e) { LOGGER.log(Level.SEVERE, "An error occurred while listing expenses.", e); diff --git a/src/test/java/seedu/budgetbuddy/ChangeCurrencyCommandCreatorTest.java b/src/test/java/seedu/budgetbuddy/ChangeCurrencyCommandCreatorTest.java index 1fd4f7e56a..02efdbe0c5 100644 --- a/src/test/java/seedu/budgetbuddy/ChangeCurrencyCommandCreatorTest.java +++ b/src/test/java/seedu/budgetbuddy/ChangeCurrencyCommandCreatorTest.java @@ -6,6 +6,7 @@ import seedu.budgetbuddy.commandcreator.ChangeCurrencyCommandCreator; import seedu.budgetbuddy.commons.CurrencyConverter; import seedu.budgetbuddy.commons.ExpenseList; +import seedu.budgetbuddy.commons. SplitExpenseList; import seedu.budgetbuddy.commons.RecurringExpenseLists; import seedu.budgetbuddy.commons.SavingList; import seedu.budgetbuddy.exception.BudgetBuddyException; @@ -20,6 +21,7 @@ public class ChangeCurrencyCommandCreatorTest { public void handleChangeCurrencyCommand_changeCurrencyToUSD_success() throws BudgetBuddyException { SavingList savingList = new SavingList(); ExpenseList expenseList = new ExpenseList(); + SplitExpenseList splitExpenseList = new SplitExpenseList(); RecurringExpenseLists recurringExpenseLists = new RecurringExpenseLists(); CurrencyConverter currencyConverter = new CurrencyConverter(); @@ -28,10 +30,10 @@ public void handleChangeCurrencyCommand_changeCurrencyToUSD_success() throws Bud String input = "change currency USD"; ChangeCurrencyCommandCreator changeCurrencyCommandCreator = new ChangeCurrencyCommandCreator(input, savingList, - expenseList, recurringExpenseLists, currencyConverter); + expenseList, splitExpenseList, recurringExpenseLists, currencyConverter); Command command = changeCurrencyCommandCreator.handleChangeCurrencyCommand(input, savingList, - expenseList, recurringExpenseLists, currencyConverter); + expenseList, splitExpenseList, recurringExpenseLists, currencyConverter); assertEquals(ChangeCurrencyCommand.class, command.getClass()); } @@ -40,6 +42,7 @@ public void handleChangeCurrencyCommand_changeCurrencyToUSD_success() throws Bud public void handleChangeCurrencyCommand_changeCurrency_invalidCurrencyCode() throws BudgetBuddyException { SavingList savingList = new SavingList(); ExpenseList expenseList = new ExpenseList(); + SplitExpenseList splitExpenseList = new SplitExpenseList(); RecurringExpenseLists recurringExpenseLists = new RecurringExpenseLists(); CurrencyConverter currencyConverter = new CurrencyConverter(); @@ -47,10 +50,10 @@ public void handleChangeCurrencyCommand_changeCurrency_invalidCurrencyCode() thr String input = "change currency abc"; ChangeCurrencyCommandCreator changeCurrencyCommandCreator = new ChangeCurrencyCommandCreator(input, savingList, - expenseList, recurringExpenseLists, currencyConverter); + expenseList, splitExpenseList, recurringExpenseLists, currencyConverter); Command command = changeCurrencyCommandCreator.handleChangeCurrencyCommand(input, savingList, - expenseList, recurringExpenseLists, currencyConverter); + expenseList, splitExpenseList, recurringExpenseLists, currencyConverter); assertNull(command); } @@ -58,6 +61,7 @@ public void handleChangeCurrencyCommand_changeCurrency_invalidCurrencyCode() thr public void handleChangeCurrencyCommand_changeCurrency_invalidCommandFormat() throws BudgetBuddyException { SavingList savingList = new SavingList(); ExpenseList expenseList = new ExpenseList(); + SplitExpenseList splitExpenseList = new SplitExpenseList(); RecurringExpenseLists recurringExpenseLists = new RecurringExpenseLists(); CurrencyConverter currencyConverter = new CurrencyConverter(); @@ -65,10 +69,10 @@ public void handleChangeCurrencyCommand_changeCurrency_invalidCommandFormat() th String input = "change currency abc asd"; ChangeCurrencyCommandCreator changeCurrencyCommandCreator = new ChangeCurrencyCommandCreator(input, savingList, - expenseList, recurringExpenseLists, currencyConverter); + expenseList, splitExpenseList, recurringExpenseLists, currencyConverter); Command command = changeCurrencyCommandCreator.handleChangeCurrencyCommand(input, savingList, - expenseList, recurringExpenseLists, currencyConverter); + expenseList, splitExpenseList, recurringExpenseLists, currencyConverter); assertNull(command); } } diff --git a/src/test/java/seedu/budgetbuddy/SplitExpenseListTest.java b/src/test/java/seedu/budgetbuddy/SplitExpenseListTest.java index c5cdf872b2..43a8941ce0 100644 --- a/src/test/java/seedu/budgetbuddy/SplitExpenseListTest.java +++ b/src/test/java/seedu/budgetbuddy/SplitExpenseListTest.java @@ -3,7 +3,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import seedu.budgetbuddy.commons.SplitExpenseList; @@ -20,7 +19,7 @@ public void addSplitExpense_addingsplitexpense_success() throws BudgetBuddyExcep splitExpenseList.addSplitExpense("12", "12", "Lunch"); assertEquals(1, splitExpenseList.getSplitExpenses().size()); - assertEquals("12", splitExpenseList.getSplitExpenses().get(0).getNumberOfPeople()); + assertEquals(12, splitExpenseList.getSplitExpenses().get(0).getNumberOfPeople()); assertEquals("Lunch", splitExpenseList.getSplitExpenses().get(0).getDescription()); } @@ -46,7 +45,7 @@ public void addSplitExpense_invalidNumberOfPeople_exceptionThrown() throws Budge } } - @Test @Disabled + @Test public void addSplitExpense_nullDescription_exceptionThrown() throws BudgetBuddyException{ SplitExpenseList splitExpenseList = new SplitExpenseList(); try { From 8ac361be2e06f70695afa05ae5daac40b7adc314 Mon Sep 17 00:00:00 2001 From: Dheekshitha2 Date: Sat, 13 Apr 2024 19:49:29 +0800 Subject: [PATCH 39/46] Update DG based on updated functionalities --- docs/DeveloperGuide.md | 59 +++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 1f76b53c72..64b2439fab 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -135,6 +135,16 @@ brief explanation on their functionality is as follows : * The amounts being shown are dependent on the currency being used. * calculateTotalExpenses() : * The method used to calculate all expenses found in the expense list. +* addExpense(String category, String amount, String description) : + * Adds a new Expense to the list after validating the category and amount. It also checks against the budget limit + for the given category and seeks user confirmation if the budget would be exceeded. +* getBudgetAndListExpensesForCategory(String inputCategory) : + * Retrieves and displays the budget for a given category and lists the expenses under it, sorted by amount and + showing what percentage of the budget each expense constitutes. + +The `ExpenseList` class relies on the `Ui` class to interact with the user for confirmations and to display information. +All exceptions related to invalid operations or data are handled by throwing specific `BudgetBuddyException` instances to +be caught by the caller, ensuring robust error management within the application. ##### 3.6.4 Saving This class holds details regarding a saving a user has. Within this class, it has 3 class-level variables : @@ -186,6 +196,10 @@ brief explanation on their functionality is as follows : * `calculateRemainingSavings(double initialAmount, double totalExpenses)` : * Calculates the remaining savings amount after deducting total expenses from the initial amount. * Provides clarity on how much savings user has left to spend. +* `reduceSavingsByCategory(String category, double amount)` : + * Decreases the savings amount for a specified category by a given amount. + * It iterates through the savings list, finds the specified category, and deducts the specified amount. + * If any of the savings entries do not have sufficient funds to cover the reduction, it outputs a warning. ##### 3.6.6 RecurringExpenseList This class represents a list of recurring expenses for the Recurring Expense feature. Within this class, it has @@ -244,11 +258,18 @@ this method converts the currency of savings in a given `SavingList` to a specif It iterates through the savings in the list, converts each saving amount to the new currency using the `convertAmount` method, and updates the saving amounts and currencies accordingly. +* `convertBudgetCurrency(Currency newCurrency, ExpenseList expenseList)`: +This method is responsible for converting the currency of all budgets within `ExpenseList` to a specified new currency (`newCurrency`). It +accepts the new `Currency` object representing the target currency and the `ExpenseList` containing the budgets, and updates +the budget amounts and currencies accordingly. + + These methods facilitate currency conversion tasks by handling the conversion logic, validating input parameters, and logging relevant messages. They provide essential functionality for managing expenses and savings in different currencies within the budget management application. + ## 4. Implementation ### Edit Expense Feature @@ -294,16 +315,29 @@ amount (`a/40`), and description (`d/GRAB`). category to "Transport," amount to 40.0, and description to "GRAB." 7. A message "Expense edited successfully." is printed to the console. +### 4.6 Reduce Savings Feature +The Reduce Savings feature enables users to decrement a specified amount from their savings at a given index. This +functionality is controlled by the `ReduceSavingCommand` class, which is produced by the `ReduceSavingCommandCreator` +based on user input. The `ReduceSavingCommand` class uses a `SavingList` object to access the relevant saving and performs +the reduction operation using the provided index and amount. Below is the relevance of these attributes: + +| Class Attribute | Variable Type | Relevance | +|----------------|---------------|------------------------------------------------------------------------------| +| savings | SavingList | The `SavingList` object containing the list of savings which can be reduced | +| index | Integer | The `ExpenseList` object containing the list of expenses | +| filterCategory | String | The category to filter the savings by, if provided | + + ### Listing Feature (List Savings) The Listing Savings Feature enables users to view their savings, potentially filtered by a specific category. This functionality is orchestrated by the `ListSavingsCommand` class, which is initialized by the `ListCommandCreator` class. Within the `ListSavingsCommand` object, the `ListCommandCreator` provides it with a `SavingList` object, an `ExpenseList` object, along with an optional `filterCategory`. The relevance of these class attributes in `ListSavingsCommand` is detailed in the following table: -| Class Attribute | Variable Type | Relevance | -|-----------------|---------------|-------------------------------------------------------------------------------------| -| savings | SavingList | The `SavingList` object containing the list of savings to be displayed or filtered | -| expenses | ExpenseList | The `ExpenseList` object containing the list of expenses | -| filterCategory | String | The category to filter the savings by, if provided | +| Class Attribute | Variable Type | Relevance | +|-----------------|---------------|--------------------------------------------------------------------------------------| +| savings | SavingList | The `SavingList` object containing the list of savings to be displayed or filtered | +| expenses | ExpenseList | The `ExpenseList` object containing the list of expenses | +| filterCategory | String | The category to filter the savings by, if provided | When `BudgetBuddy` invokes the `execute()` method via `command.execute()`, the `ListSavingsCommand` object uses several methods from the `SavingList` class to perform its tasks: @@ -367,11 +401,12 @@ The Currency Converter Feature allows users to convert the currency of expenses When `BudgetBuddy` calls `command.execute()`, `ChangeCurrencyCommand` employs the following methods from `CurrencyConverter` to convert the currency of all financial records: -| Method | Return Type | Relevance | -|--------------------------|-------------|---------------------------------------------------------------------------| -| convertExpenseCurrency() | void | Converts the currency of each `Expense` object to `newCurrency` | -| convertSavingCurrency() | void | Converts the currency of each `Saving` object to `newCurrency` | -| convertAmount() | double | Converts an amount from one currency to another using the exchange rates | +| Method | Return Type | Relevance | +|--------------------------|-------------|--------------------------------------------------------------------------| +| convertExpenseCurrency() | void | Converts the currency of each `Expense` object to `newCurrency` | +| convertSavingCurrency() | void | Converts the currency of each `Saving` object to `newCurrency` | +| convertBudgetCurrency() | void | Converts the currency of each `Budget` object to `newCurrency` | +| convertAmount() | double | Converts an amount from one currency to another using the exchange rates | The Currency Converter feature also includes a mechanism for managing a default currency across the application, facilitated by the `DefaultCurrency` class. This enhancement allows for seamless conversion of financial records to a user-specified default currency. @@ -387,10 +422,10 @@ Here's the step-by-step process when the user uses the Currency Converter featur 1. The user inputs `change currency [newCurrencyCode]`. `Parser` processes this input and constructs a `ChangeCurrencyCommand` object with the necessary attributes. 2. The `ChangeCurrencyCommand` object is returned to `BudgetBuddy`, which calls `ChangeCurrencyCommand.execute()`. 3. `execute()` invokes `CurrencyConverter.convertExpenseCurrency(newCurrency, expenseList)` and `CurrencyConverter.convertSavingCurrency(newCurrency, savingList)`. -4. Within the `convertExpenseCurrency` and `convertSavingCurrency` call, the amounts of `Expense` or `Saving` objects are converted to the `newCurrency` using the `convertAmount` method. +4. Within the `convertExpenseCurrency` and `convertSavingCurrency` call, the amounts of `Expense`, `Saving` or `Budget` objects are converted to the `newCurrency` using the `convertAmount` method. 5. The `DefaultCurrency.setDefaultCurrency(newCurrency)` method is called to update the application's default currency setting to `newCurrency`. 6. The `setAmount` and `setCurrency` methods of `ExpenseList` and `SavingList` are used to update the amounts and currency codes. -7. After successful conversion of savings and expenses, the default currency of the application is updated, reflecting the new choice across BudgetBuddy. +7. After successful conversion of savings, expenses and budgets, the default currency of the application is updated, reflecting the new choice across BudgetBuddy. #### Sequence Diagram From e6f9fa0fef48f81c5f4b3947fe923b01a4cd2bde Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Sat, 13 Apr 2024 19:52:09 +0800 Subject: [PATCH 40/46] Update the exception handling for add savings --- src/main/java/seedu/budgetbuddy/Parser.java | 4 +- .../command/ChangeCurrencyCommand.java | 5 ++- .../AddSavingCommandCreator.java | 2 +- .../ChangeCurrencyCommandCreator.java | 9 ++-- .../SplitExpenseCommandCreator.java | 2 +- .../seedu/budgetbuddy/commons/SavingList.java | 2 +- .../budgetbuddy/commons/SplitExpenseList.java | 11 ++--- .../seedu/budgetbuddy/SavingListTest.java | 43 +++++++++++++++++++ .../budgetbuddy/SplitExpenseListTest.java | 11 ----- 9 files changed, 59 insertions(+), 30 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/Parser.java b/src/main/java/seedu/budgetbuddy/Parser.java index 7c7d051376..f3c70a2879 100644 --- a/src/main/java/seedu/budgetbuddy/Parser.java +++ b/src/main/java/seedu/budgetbuddy/Parser.java @@ -234,8 +234,8 @@ public Command parseCommand(ExpenseList expenses, SavingList savings, SplitExpen } if (isConvertCurrencyCommand(input.toLowerCase())) { - CommandCreator commandCreator = new ChangeCurrencyCommandCreator(input, savings, expenses, splitexpenses, expensesList, - new CurrencyConverter()); + CommandCreator commandCreator = new ChangeCurrencyCommandCreator(input, savings, expenses, splitexpenses, + expensesList, new CurrencyConverter()); return commandCreator.createCommand(); } diff --git a/src/main/java/seedu/budgetbuddy/command/ChangeCurrencyCommand.java b/src/main/java/seedu/budgetbuddy/command/ChangeCurrencyCommand.java index 86c1b79d90..3bbc112724 100644 --- a/src/main/java/seedu/budgetbuddy/command/ChangeCurrencyCommand.java +++ b/src/main/java/seedu/budgetbuddy/command/ChangeCurrencyCommand.java @@ -18,8 +18,9 @@ public class ChangeCurrencyCommand extends Command { private RecurringExpenseLists recurringExpenseLists; private CurrencyConverter currencyConverter; - public ChangeCurrencyCommand(Currency newCurrency, SavingList savings, ExpenseList expenses, SplitExpenseList splitExpenses, - RecurringExpenseLists recurringExpenseLists, CurrencyConverter currencyConverter) { + public ChangeCurrencyCommand(Currency newCurrency, SavingList savings, ExpenseList expenses, SplitExpenseList + splitExpenses, RecurringExpenseLists recurringExpenseLists, + CurrencyConverter currencyConverter) { this.newCurrency = newCurrency; this.savings = savings; this.expenses = expenses; diff --git a/src/main/java/seedu/budgetbuddy/commandcreator/AddSavingCommandCreator.java b/src/main/java/seedu/budgetbuddy/commandcreator/AddSavingCommandCreator.java index f3a072ac58..ed65fb17c2 100644 --- a/src/main/java/seedu/budgetbuddy/commandcreator/AddSavingCommandCreator.java +++ b/src/main/java/seedu/budgetbuddy/commandcreator/AddSavingCommandCreator.java @@ -56,7 +56,7 @@ public Command handleAddSavingCommand(SavingList savings, String input) { try { double amountValue = Double.parseDouble(amount); if (amountValue <= 0) { - throw new BudgetBuddyException(amount + " is not a valid amount."); + throw new BudgetBuddyException(amount + " is negative. Please enter a positive amount."); } } catch (NumberFormatException e) { diff --git a/src/main/java/seedu/budgetbuddy/commandcreator/ChangeCurrencyCommandCreator.java b/src/main/java/seedu/budgetbuddy/commandcreator/ChangeCurrencyCommandCreator.java index 93f1a2a140..dcae145f94 100644 --- a/src/main/java/seedu/budgetbuddy/commandcreator/ChangeCurrencyCommandCreator.java +++ b/src/main/java/seedu/budgetbuddy/commandcreator/ChangeCurrencyCommandCreator.java @@ -22,8 +22,9 @@ public class ChangeCurrencyCommandCreator extends CommandCreator { private String input; private CurrencyConverter newCurrency; - public ChangeCurrencyCommandCreator(String input, SavingList savings, ExpenseList expenses, SplitExpenseList splitExpenses, - RecurringExpenseLists recurringExpenseLists, CurrencyConverter newCurrency) { + public ChangeCurrencyCommandCreator(String input, SavingList savings, ExpenseList expenses, + SplitExpenseList splitExpenses, RecurringExpenseLists recurringExpenseLists, + CurrencyConverter newCurrency) { this.input = input; this.savings = savings; @@ -60,8 +61,8 @@ public Command handleChangeCurrencyCommand(String input, SavingList savingList, Currency newCurrency = Currency.getInstance(currencyCode.toUpperCase()); assert newCurrency != null : "Currency code should be valid"; LOGGER.log(Level.INFO, "Default currency changed to " + newCurrency); - return new ChangeCurrencyCommand(newCurrency, savingList, expenseList, splitExpenses, recurringExpenseLists - , currencyConverter); + return new ChangeCurrencyCommand(newCurrency, savingList, expenseList, splitExpenses, + recurringExpenseLists, currencyConverter); } catch (IllegalArgumentException e) { LOGGER.log(Level.WARNING, "Invalid currency code: " + currencyCode); System.out.println("Invalid currency code."); diff --git a/src/main/java/seedu/budgetbuddy/commandcreator/SplitExpenseCommandCreator.java b/src/main/java/seedu/budgetbuddy/commandcreator/SplitExpenseCommandCreator.java index 3a75624925..18ae290a43 100644 --- a/src/main/java/seedu/budgetbuddy/commandcreator/SplitExpenseCommandCreator.java +++ b/src/main/java/seedu/budgetbuddy/commandcreator/SplitExpenseCommandCreator.java @@ -25,7 +25,7 @@ public Command handleSplitExpenseCommand(SplitExpenseList splitexpenses, String String numberOfPeople = extractDetail(input, "n/", "d/"); String description = extractDetail(input, "d/", null); // Description is last, so no nextPrefix - if (amount.isEmpty() || numberOfPeople.isEmpty() || description.isEmpty()) { + if (amount.isEmpty()|| numberOfPeople.isEmpty() || description.isEmpty()) { System.out.println("Missing details."); return null; } diff --git a/src/main/java/seedu/budgetbuddy/commons/SavingList.java b/src/main/java/seedu/budgetbuddy/commons/SavingList.java index 3b81a7efc9..02765b9f7e 100644 --- a/src/main/java/seedu/budgetbuddy/commons/SavingList.java +++ b/src/main/java/seedu/budgetbuddy/commons/SavingList.java @@ -143,7 +143,7 @@ public void addSaving(String category, String amount) throws BudgetBuddyExceptio if (!amount.matches("^\\d+(\\.\\d{1,2})?$")) { - throw new BudgetBuddyException("Invalid amount format. Amount should be a number with up" + + throw new BudgetBuddyException("Invalid amount format. Amount should be a positive number with up" + " to maximum two decimal places."); } diff --git a/src/main/java/seedu/budgetbuddy/commons/SplitExpenseList.java b/src/main/java/seedu/budgetbuddy/commons/SplitExpenseList.java index f2b3f02e68..7c6f523280 100644 --- a/src/main/java/seedu/budgetbuddy/commons/SplitExpenseList.java +++ b/src/main/java/seedu/budgetbuddy/commons/SplitExpenseList.java @@ -11,11 +11,11 @@ import java.util.logging.Logger; public class SplitExpenseList { - - Ui ui = new Ui(); - private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); protected ArrayList splitexpenses; + + Ui ui = new Ui(); + public SplitExpenseList(ArrayList splitexpenses){ this.splitexpenses = splitexpenses; } @@ -39,11 +39,6 @@ public SplitExpense getSplitExpenseListAtListNumber(int listNumber) { /** * Lists all the expenses in the list - * @return void - * @throws BudgetBuddyException if there is an error while listing expenses - * @param void - * @return void - * @throws BudgetBuddyException if there is an error while listing expenses */ public void listSplitExpenses() { diff --git a/src/test/java/seedu/budgetbuddy/SavingListTest.java b/src/test/java/seedu/budgetbuddy/SavingListTest.java index 553bda9943..c2c83dcff6 100644 --- a/src/test/java/seedu/budgetbuddy/SavingListTest.java +++ b/src/test/java/seedu/budgetbuddy/SavingListTest.java @@ -16,6 +16,49 @@ public class SavingListTest { private static final Logger LOGGER = Logger.getLogger(SavingListTest.class.getName()); + + @Test + public void addSaving_validInput_success() throws BudgetBuddyException { + SavingList savingList = new SavingList(); + savingList.addSaving("Salary", "500"); + + assertEquals(1, savingList.getSavings().size()); + assertEquals("Salary", savingList.getSavings().get(0).getCategory()); + assertEquals(500, savingList.getSavings().get(0).getAmount()); + } + + @Test + public void addSaving_invalidAmount_exceptionThrown() { + SavingList savingList = new SavingList(); + try { + savingList.addSaving("Salary", "abc"); + } catch (BudgetBuddyException e) { + assertEquals("Invalid amount format. Amount should be a positive number with up to maximum two decimal " + + "places.", e.getMessage()); + } + } + + @Test + public void addSaving_negativeAmount_exceptionThrown() { + SavingList savingList = new SavingList(); + try { + savingList.addSaving("Salary", "-1.00"); + } catch (BudgetBuddyException e) { + assertEquals("Invalid amount format. Amount should be a positive number with up to maximum "+ + "two decimal places.", e.getMessage()); + } + } + + @Test + public void addSaving_nullCategory_exceptionThrown() { + SavingList savingList = new SavingList(); + try { + savingList.addSaving("abc", "500"); + } catch (BudgetBuddyException e) { + assertEquals("The category 'abc' is not listed.", e.getMessage()); + } + } + @Test public void calculateRemainingSavings_sufficientFunds_success() { SavingList savingList = new SavingList(); diff --git a/src/test/java/seedu/budgetbuddy/SplitExpenseListTest.java b/src/test/java/seedu/budgetbuddy/SplitExpenseListTest.java index 43a8941ce0..8d4063f403 100644 --- a/src/test/java/seedu/budgetbuddy/SplitExpenseListTest.java +++ b/src/test/java/seedu/budgetbuddy/SplitExpenseListTest.java @@ -45,17 +45,6 @@ public void addSplitExpense_invalidNumberOfPeople_exceptionThrown() throws Budge } } - @Test - public void addSplitExpense_nullDescription_exceptionThrown() throws BudgetBuddyException{ - SplitExpenseList splitExpenseList = new SplitExpenseList(); - try { - splitExpenseList.addSplitExpense("12", "12", null); - fail(); - } catch (BudgetBuddyException e) { - assertEquals("Description should not be null", e.getMessage()); - } - } - @Test public void addSplitExpense_negativeAmount_exceptionThrown() throws BudgetBuddyException{ SplitExpenseList splitExpenseList = new SplitExpenseList(); From a25924b2c8dff77bb24a0dab31e9b84142091b05 Mon Sep 17 00:00:00 2001 From: Zhang Yangda Date: Sat, 13 Apr 2024 20:02:14 +0800 Subject: [PATCH 41/46] Add test cases for addsavings --- data/SavingsFile.txt | 1 + .../budgetbuddy/commons/ExpenseList.java | 2 +- .../seedu/budgetbuddy/ExpenseListTest.java | 46 ++++++++++++++++++- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/data/SavingsFile.txt b/data/SavingsFile.txt index e69de29bb2..7a538556d8 100644 --- a/data/SavingsFile.txt +++ b/data/SavingsFile.txt @@ -0,0 +1 @@ +Salary | 200.00 diff --git a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java index 286b8b7988..9d6d507d9a 100644 --- a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java +++ b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java @@ -166,7 +166,7 @@ public void addExpense(String category, String amount, String description) throw .orElseThrow(() -> new BudgetBuddyException("The category '" + category + "' is not listed.")); if (!amount.matches("^\\d+(\\.\\d{1,2})?$")) { - throw new BudgetBuddyException("Invalid amount format. Amount should be a number with up" + + throw new BudgetBuddyException("Invalid amount format. Amount should be a positive number with up" + " to maximum two decimal places."); } diff --git a/src/test/java/seedu/budgetbuddy/ExpenseListTest.java b/src/test/java/seedu/budgetbuddy/ExpenseListTest.java index 9b073d828c..740d9940ef 100644 --- a/src/test/java/seedu/budgetbuddy/ExpenseListTest.java +++ b/src/test/java/seedu/budgetbuddy/ExpenseListTest.java @@ -41,17 +41,59 @@ public void addExpense_addingExpense_success() throws BudgetBuddyException { assertEquals("Bus Fare", expenseList.getExpenses().get(0).getDescription()); } - @Test @Disabled + @Test public void addExpense_addingNegativeExpense_exceptionThrown() { ExpenseList expenseList = new ExpenseList(); try { expenseList.addExpense("Transport", "-50", "Bus Fare"); fail(); } catch (Exception e) { - assertEquals("java.lang.Exception: Expenses should not be negative", e.getMessage()); + assertEquals("Invalid amount format. Amount should be a positive number with up to maximum two decimal " + + "places.", e.getMessage()); + } + } + + @Test + public void addExpense_addingInvalidAmount_exceptionThrown() { + ExpenseList expenseList = new ExpenseList(); + try { + expenseList.addExpense("Transport", "abc", "Bus Fare"); + fail(); + } catch (Exception e) { + assertEquals("Invalid amount format. Amount should be a positive number with up to maximum two decimal " + + "places.", e.getMessage()); } } + @Test + public void addExpense_addingNullCategory_exceptionThrown() { + ExpenseList expenseList = new ExpenseList(); + try { + expenseList.addExpense("abc", "50", "Bus Fare"); + fail(); + } catch (Exception e) { + assertEquals("The category 'abc' is not listed.", e.getMessage()); + } + } + + @Test + public void deleteExpense_validInput_success() throws BudgetBuddyException { + // Create an ExpenseList and add two expenses + ExpenseList expenseList = new ExpenseList(); + expenseList.addExpense("Transport", "50", "Bus Fare"); + expenseList.addExpense("Housing", "30", "Lunch"); + + // Delete the first expense + expenseList.deleteExpense(1); + + // Assert: Check if the first expense is deleted + assertEquals(1, expenseList.getExpenses().size()); + assertEquals("Transport", expenseList.getExpenses().get(0).getCategory()); + assertEquals(50, expenseList.getExpenses().get(0).getAmount(), 0.01); // using delta for double comparison + assertEquals("Bus Fare", expenseList.getExpenses().get(0).getDescription()); + } + + //@@ jasraa @Test public void editExpense_validInput_success() throws BudgetBuddyException { From d6195db9995bc831ba87cd7258841c4195eaed83 Mon Sep 17 00:00:00 2001 From: jasraa Date: Sat, 13 Apr 2024 20:07:28 +0800 Subject: [PATCH 42/46] Made changes --- data/ExpenseFile.txt | 14 ++ data/SavingsFile.txt | 7 + docs/UserGuide.md | 7 +- docs/userguideimages/GetExpenseInsights.png | Bin 0 -> 48933 bytes .../seedu/budgetbuddy/commons/SavingList.java | 195 +++++++++++++----- 5 files changed, 167 insertions(+), 56 deletions(-) create mode 100644 docs/userguideimages/GetExpenseInsights.png diff --git a/data/ExpenseFile.txt b/data/ExpenseFile.txt index 78db31319c..e147d63ccd 100644 --- a/data/ExpenseFile.txt +++ b/data/ExpenseFile.txt @@ -1,2 +1,16 @@ 2024-04-07 | Transport | 100.00 | bus 2024-04-07 | Transport | 60.00 | train +2024-04-13 | Entertainment | 50.00 | Movie tickets +2024-04-13 | Housing | 1200.00 | Monthly rent +2024-04-13 | Groceries | 85.00 | Weekly grocery shopping +2024-04-13 | Transport | 30.00 | Bus pass +2024-04-13 | Entertainment | 75.00 | Concert ticket +2024-04-13 | Housing | 200.00 | Furniture +2024-04-13 | Groceries | 45.00 | Fresh fruits and vegetables +2024-04-13 | Transport | 70.00 | Taxi fare +2024-04-13 | Entertainment | 25.00 | Streaming service +2024-04-13 | Housing | 100.00 | Home repairs +2024-04-13 | Groceries | 110.00 | Meat and seafood +2024-04-13 | Transport | 40.00 | Petrol +2024-04-13 | Entertainment | 60.00 | Art exhibition ticket +2024-04-13 | Housing | 300.00 | Monthly parking space rental diff --git a/data/SavingsFile.txt b/data/SavingsFile.txt index e69de29bb2..e75a79eb50 100644 --- a/data/SavingsFile.txt +++ b/data/SavingsFile.txt @@ -0,0 +1,7 @@ +Salary | 1500.00 +Investments | 500.00 +Gifts | 200.00 +Salary | 1000.00 +Investments | 2000.00 +Gifts | 250.00 +Salary | 400.00 diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 477cfcae20..b1cf5d07bf 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -445,16 +445,19 @@ Format: `print budget` * This feature provides an overview of the expenses distribution across different categories. * A horizontal bar graph showing the percentage of total expenses attributed to each category. * It highlights the category with the highest expenses, the one with the lowest (excluding categories with no expenses), -* and lists any categories where no expenses have been recorded. +and lists any categories where no expenses have been recorded. * Categories are Housing, Groceries, Utility, Transport, Entertainment, and Others. Example of usage: `get expenses insights` +Example of Expected Output: +![GetExpenseInsights.png](userguideimages%2FGetExpenseInsights.png) + ### Get Graphical Insights for savings: `get savings insights` * This feature offers a comprehensive look at how your savings are allocated across various categories. * A horizontal bar graph showing the percentage of total savings attributed to each category. * It highlights the category with the highest savings, the one with the lowest (excluding categories with no savings), -* and lists any categories where no savings have been added. +and lists any categories where no savings have been added. * Categories are Salary, Investments, Gifts, and Others Example of Usage: `get savings insights` diff --git a/docs/userguideimages/GetExpenseInsights.png b/docs/userguideimages/GetExpenseInsights.png new file mode 100644 index 0000000000000000000000000000000000000000..79d2138b7a59cf427f5ece5e06bad6d088b4f31a GIT binary patch literal 48933 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 literal 0 HcmV?d00001 diff --git a/src/main/java/seedu/budgetbuddy/commons/SavingList.java b/src/main/java/seedu/budgetbuddy/commons/SavingList.java index 3a93f37184..4801aa0c48 100644 --- a/src/main/java/seedu/budgetbuddy/commons/SavingList.java +++ b/src/main/java/seedu/budgetbuddy/commons/SavingList.java @@ -222,65 +222,149 @@ public void reduceSavings(int index, double amount) { } } + public double calculateTotalSavings() { + double totalSavings = 0; + try { + for (Saving saving : savings) { + if (saving.getAmount() < 0) { + throw new IllegalArgumentException("Savings should not be negative"); + } + totalSavings += saving.getAmount(); + } + } catch (IllegalArgumentException e) { + LOGGER.log(Level.WARNING, "Negative savings amount detected", e); + } + + assert totalSavings >= 0 : "Total savings should be non-negative"; + + return totalSavings; + } + + /** * Analyzes and displays insights into the saved amounts across different categories. * It prints out the highest and lowest savings categories and lists categories with no savings. * A bar graph representing the distribution of savings is also displayed. */ - public void getSavingsInsights() { - findTotalSavings(); // Make sure total savings are updated +// public void getSavingsInsights() { +// findTotalSavings(); // Make sure total savings are updated +// +// if (initialAmount == 0) { +// System.out.println("No savings to display."); +// return; +// } +// +// // Calculate the highest savings value +// double highestSavings = savings.stream() +// .mapToDouble(Saving::getAmount) +// .max().orElse(0); +// +// // Identify the categories with the highest savings +// List highestCategories = savings.stream() +// .filter(s -> Double.compare(s.getAmount(), highestSavings) == 0) // Use Double.compare for precision +// .map(Saving::getCategory) +// .distinct() // Ensure that there are no duplicates +// .collect(Collectors.toList()); +// +// // Calculate the lowest savings value excluding the highest if it's the only value +// double lowestSavings = savings.stream() +// .filter(s -> !highestCategories.contains(s.getCategory())) +// .mapToDouble(Saving::getAmount) +// .min().orElse(0); +// +// // Identify the categories with the lowest savings, excluding those with no savings +// List lowestCategories = savings.stream() +// .filter(s -> s.getAmount() == lowestSavings && lowestSavings != 0) +// .map(Saving::getCategory) +// .collect(Collectors.toList()); +// +// // If lowestSavings is 0, then this list should be empty +// if (lowestSavings == 0) { +// lowestCategories.clear(); +// } +// +// // Identify categories with no savings +// List noSavingsCategories = categories.stream() +// .filter(c -> savings.stream().noneMatch(s -> s.getCategory().equals(c))) +// .collect(Collectors.toList()); +// +// // Add categories with zero amount saved +// noSavingsCategories.addAll(savings.stream() +// .filter(s -> s.getAmount() == 0) +// .map(Saving::getCategory) +// .collect(Collectors.toList())); +// +// ui.printDivider(); +// printSavingsDistribution(); +// ui.printDivider(); +// System.out.println("Highest Savings Category: " + formatCategoryList(highestCategories)); +// System.out.println("Lowest Savings Category: " + formatCategoryList(lowestCategories)); +// System.out.println("Categories with no savings added: " + formatCategoryList(noSavingsCategories)); +// ui.printDivider(); +// } - if (initialAmount == 0) { + /** + * Analyzes and displays insights into the saved amounts across different categories. + * It prints out the highest and lowest savings categories and lists categories with no savings. + * A bar graph representing the distribution of savings is also displayed. + */ + public void getSavingsInsights() { + double totalSavings = calculateTotalSavings(); + if (totalSavings == 0) { System.out.println("No savings to display."); return; } - printSavingsDistribution(); + Map sumsByCategory = calculateSumsByCategory(); - // Calculate the highest savings value - double highestSavings = savings.stream() - .mapToDouble(Saving::getAmount) - .max().orElse(0); + // Calculate the highest savings + double highestSavings = Collections.max(sumsByCategory.values()); + // Calculate the lowest savings + double lowestSavings = sumsByCategory.values().stream() + .filter(amount -> amount > 0) + .min(Double::compare) + .orElse(0.0); - // Identify the categories with the highest savings - List highestCategories = savings.stream() - .filter(s -> s.getAmount() == highestSavings) - .map(Saving::getCategory) - .collect(Collectors.toList()); + List highestCategories = getSavingsCategoriesByAmount(sumsByCategory, highestSavings); + List lowestCategories = getSavingsCategoriesByAmount(sumsByCategory, lowestSavings); - // Calculate the lowest savings value excluding the highest if it's the only value - double lowestSavings = savings.stream() - .filter(s -> !highestCategories.contains(s.getCategory())) - .mapToDouble(Saving::getAmount) - .min().orElse(0); + // Print the distribution graph + ui.printDivider(); + printSavingsDistribution(sumsByCategory, totalSavings); + ui.printDivider(); - // Identify the categories with the lowest savings, excluding those with no savings - List lowestCategories = savings.stream() - .filter(s -> s.getAmount() == lowestSavings && lowestSavings != 0) - .map(Saving::getCategory) - .collect(Collectors.toList()); + // Print insights + System.out.println("Highest Savings Category: " + formatCategoryList(highestCategories)); + System.out.println("Lowest Savings Category: " + formatCategoryList(lowestCategories)); + System.out.println("Categories with no savings added: " + formatCategoryList(getNoSavingsCategories(sumsByCategory))); + ui.printDivider(); + } - // If lowestSavings is 0, then this list should be empty - if (lowestSavings == 0) { - lowestCategories.clear(); - } + private List getSavingsCategoriesByAmount(Map sumsByCategory, double amount) { + return sumsByCategory.entrySet().stream() + .filter(entry -> entry.getValue() == amount) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + } - // Identify categories with no savings - List noSavingsCategories = categories.stream() - .filter(c -> savings.stream().noneMatch(s -> s.getCategory().equals(c))) + private List getNoSavingsCategories(Map sumsByCategory) { + return categories.stream() + .filter(category -> !sumsByCategory.containsKey(category) || sumsByCategory.get(category) == 0) .collect(Collectors.toList()); + } - // Add categories with zero amount saved - noSavingsCategories.addAll(savings.stream() - .filter(s -> s.getAmount() == 0) - .map(Saving::getCategory) - .collect(Collectors.toList())); + private void printSavingsDistribution(Map sumsByCategory, double totalSavings) { + double maxPercentage = sumsByCategory.values().stream() + .mapToDouble(amount -> (amount / totalSavings) * 100) + .max() + .orElse(100); - ui.printDivider(); - System.out.println("Highest Savings Category: " + formatCategoryList(highestCategories)); - System.out.println("Lowest Savings Category: " + formatCategoryList(lowestCategories)); - System.out.println("Categories with no savings added: " + formatCategoryList(noSavingsCategories)); - ui.printDivider(); + for (String category : categories) { + double percentage = (sumsByCategory.getOrDefault(category, 0.0) / totalSavings) * 100; + int barLength = (int) (percentage / (maxPercentage / 50)); + String bar = "[" + "#".repeat(Math.max(0, barLength)) + "]"; + System.out.println(String.format("%-15s: %6.2f%% %s", category, percentage, bar)); + } } /** @@ -308,27 +392,30 @@ private Map calculateSumsByCategory() { private String formatCategoryList(List categories) { if (categories.isEmpty()) { return "None"; + } else if (categories.size() == 1) { + return categories.get(0); } else { - return String.join(", ", categories.subList(0, categories.size() - 1)) - + (categories.size() > 1 ? " and " : "") + categories.get(categories.size() - 1); + String allButLast = String.join(", ", categories.subList(0, categories.size() - 1)); + return allButLast + " and " + categories.get(categories.size() - 1); } } + /** * Prints a distribution of savings as a horizontal bar graph. * Each category's bar length is proportional to its percentage of the total savings. */ - private void printSavingsDistribution() { - Map sumsByCategory = calculateSumsByCategory(); - double totalSavings = sumsByCategory.values().stream().mapToDouble(Double::doubleValue).sum(); - - for (String category : categories) { - Double sum = sumsByCategory.getOrDefault(category, 0.0); - double percentage = (sum / totalSavings) * 100; - int barLength = (int) (percentage / (100.0 / 50)); // Assuming a bar max length of 50 characters - String bar = "[" + "#".repeat(Math.max(0, barLength)) + "]"; - System.out.println(String.format("%-15s: %6.2f%% %s", category, percentage, bar)); - } - } +// private void printSavingsDistribution() { +// Map sumsByCategory = calculateSumsByCategory(); +// double totalSavings = sumsByCategory.values().stream().mapToDouble(Double::doubleValue).sum(); +// +// for (String category : categories) { +// Double sum = sumsByCategory.getOrDefault(category, 0.0); +// double percentage = (sum / totalSavings) * 100; +// int barLength = (int) (percentage / (100.0 / 50)); // Assuming a bar max length of 50 characters +// String bar = "[" + "#".repeat(Math.max(0, barLength)) + "]"; +// System.out.println(String.format("%-15s: %6.2f%% %s", category, percentage, bar)); +// } +// } } From d1fe66ac058012d5c655449b7cd2f1ee9d8b0ab7 Mon Sep 17 00:00:00 2001 From: jasraa Date: Sat, 13 Apr 2024 20:21:41 +0800 Subject: [PATCH 43/46] Update UG with expected output for graphical insights --- docs/UserGuide.md | 3 + docs/userguideimages/GetSavingsInsights.png | Bin 0 -> 39454 bytes .../seedu/budgetbuddy/commons/SavingList.java | 90 +----------------- 3 files changed, 8 insertions(+), 85 deletions(-) create mode 100644 docs/userguideimages/GetSavingsInsights.png diff --git a/docs/UserGuide.md b/docs/UserGuide.md index b1cf5d07bf..d92db6fae0 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -462,6 +462,9 @@ and lists any categories where no savings have been added. Example of Usage: `get savings insights` +Example of Expected Output: +![GetSavingsInsights.png](userguideimages%2FGetSavingsInsights.png) + ### Saving the data diff --git a/docs/userguideimages/GetSavingsInsights.png b/docs/userguideimages/GetSavingsInsights.png new file mode 100644 index 0000000000000000000000000000000000000000..09b0260f4017c37fae270fe5a0a805a9d3c75ebc GIT binary patch literal 39454 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 E04C>*>Hq)$ literal 0 HcmV?d00001 diff --git a/src/main/java/seedu/budgetbuddy/commons/SavingList.java b/src/main/java/seedu/budgetbuddy/commons/SavingList.java index 4801aa0c48..1e55046e5c 100644 --- a/src/main/java/seedu/budgetbuddy/commons/SavingList.java +++ b/src/main/java/seedu/budgetbuddy/commons/SavingList.java @@ -1,12 +1,9 @@ package seedu.budgetbuddy.commons; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Map; +import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.List; import java.util.stream.Collectors; import seedu.budgetbuddy.Ui; @@ -240,69 +237,6 @@ public double calculateTotalSavings() { return totalSavings; } - - /** - * Analyzes and displays insights into the saved amounts across different categories. - * It prints out the highest and lowest savings categories and lists categories with no savings. - * A bar graph representing the distribution of savings is also displayed. - */ -// public void getSavingsInsights() { -// findTotalSavings(); // Make sure total savings are updated -// -// if (initialAmount == 0) { -// System.out.println("No savings to display."); -// return; -// } -// -// // Calculate the highest savings value -// double highestSavings = savings.stream() -// .mapToDouble(Saving::getAmount) -// .max().orElse(0); -// -// // Identify the categories with the highest savings -// List highestCategories = savings.stream() -// .filter(s -> Double.compare(s.getAmount(), highestSavings) == 0) // Use Double.compare for precision -// .map(Saving::getCategory) -// .distinct() // Ensure that there are no duplicates -// .collect(Collectors.toList()); -// -// // Calculate the lowest savings value excluding the highest if it's the only value -// double lowestSavings = savings.stream() -// .filter(s -> !highestCategories.contains(s.getCategory())) -// .mapToDouble(Saving::getAmount) -// .min().orElse(0); -// -// // Identify the categories with the lowest savings, excluding those with no savings -// List lowestCategories = savings.stream() -// .filter(s -> s.getAmount() == lowestSavings && lowestSavings != 0) -// .map(Saving::getCategory) -// .collect(Collectors.toList()); -// -// // If lowestSavings is 0, then this list should be empty -// if (lowestSavings == 0) { -// lowestCategories.clear(); -// } -// -// // Identify categories with no savings -// List noSavingsCategories = categories.stream() -// .filter(c -> savings.stream().noneMatch(s -> s.getCategory().equals(c))) -// .collect(Collectors.toList()); -// -// // Add categories with zero amount saved -// noSavingsCategories.addAll(savings.stream() -// .filter(s -> s.getAmount() == 0) -// .map(Saving::getCategory) -// .collect(Collectors.toList())); -// -// ui.printDivider(); -// printSavingsDistribution(); -// ui.printDivider(); -// System.out.println("Highest Savings Category: " + formatCategoryList(highestCategories)); -// System.out.println("Lowest Savings Category: " + formatCategoryList(lowestCategories)); -// System.out.println("Categories with no savings added: " + formatCategoryList(noSavingsCategories)); -// ui.printDivider(); -// } - /** * Analyzes and displays insights into the saved amounts across different categories. * It prints out the highest and lowest savings categories and lists categories with no savings. @@ -353,6 +287,10 @@ private List getNoSavingsCategories(Map sumsByCategory) .collect(Collectors.toList()); } + /** + * Prints a distribution of savings as a horizontal bar graph. + * Each category's bar length is proportional to its percentage of the total savings. + */ private void printSavingsDistribution(Map sumsByCategory, double totalSavings) { double maxPercentage = sumsByCategory.values().stream() .mapToDouble(amount -> (amount / totalSavings) * 100) @@ -400,22 +338,4 @@ private String formatCategoryList(List categories) { } } - - /** - * Prints a distribution of savings as a horizontal bar graph. - * Each category's bar length is proportional to its percentage of the total savings. - */ -// private void printSavingsDistribution() { -// Map sumsByCategory = calculateSumsByCategory(); -// double totalSavings = sumsByCategory.values().stream().mapToDouble(Double::doubleValue).sum(); -// -// for (String category : categories) { -// Double sum = sumsByCategory.getOrDefault(category, 0.0); -// double percentage = (sum / totalSavings) * 100; -// int barLength = (int) (percentage / (100.0 / 50)); // Assuming a bar max length of 50 characters -// String bar = "[" + "#".repeat(Math.max(0, barLength)) + "]"; -// System.out.println(String.format("%-15s: %6.2f%% %s", category, percentage, bar)); -// } -// } - } From 98bd85b88780d0270fa4b5caf3e866da6c294a8d Mon Sep 17 00:00:00 2001 From: jasraa Date: Sat, 13 Apr 2024 20:27:30 +0800 Subject: [PATCH 44/46] Fix checkstyle error --- .../java/seedu/budgetbuddy/commons/SavingList.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/commons/SavingList.java b/src/main/java/seedu/budgetbuddy/commons/SavingList.java index 1e55046e5c..b630e11db2 100644 --- a/src/main/java/seedu/budgetbuddy/commons/SavingList.java +++ b/src/main/java/seedu/budgetbuddy/commons/SavingList.java @@ -1,10 +1,13 @@ package seedu.budgetbuddy.commons; -import java.util.*; - +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import java.util.Collections; import seedu.budgetbuddy.Ui; import seedu.budgetbuddy.exception.BudgetBuddyException; @@ -270,7 +273,8 @@ public void getSavingsInsights() { // Print insights System.out.println("Highest Savings Category: " + formatCategoryList(highestCategories)); System.out.println("Lowest Savings Category: " + formatCategoryList(lowestCategories)); - System.out.println("Categories with no savings added: " + formatCategoryList(getNoSavingsCategories(sumsByCategory))); + System.out.println("Categories with no savings added: " + + formatCategoryList(getNoSavingsCategories(sumsByCategory))); ui.printDivider(); } From 63defbe75c3bcf96f5ea37997fab3c03f6ad06bf Mon Sep 17 00:00:00 2001 From: Dheekshitha2 Date: Sat, 13 Apr 2024 20:49:41 +0800 Subject: [PATCH 45/46] Add more updates --- docs/DeveloperGuide.md | 54 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 64b2439fab..9706ef1084 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -322,11 +322,55 @@ based on user input. The `ReduceSavingCommand` class uses a `SavingList` object the reduction operation using the provided index and amount. Below is the relevance of these attributes: | Class Attribute | Variable Type | Relevance | -|----------------|---------------|------------------------------------------------------------------------------| -| savings | SavingList | The `SavingList` object containing the list of savings which can be reduced | -| index | Integer | The `ExpenseList` object containing the list of expenses | -| filterCategory | String | The category to filter the savings by, if provided | - +|-----------------|---------------|------------------------------------------------------------------------------| +| savings | SavingList | The `SavingList` object containing the list of savings which can be reduced | +| category | String | TThe category of savings to reduce | +| amount | double | The amount by which the savings in the specified category should be reduced | + +When `BudgetBuddy` runs the `execute()` method through `command.execute()`, the `ReduceSavingCommand` leverages the reduceSavingsByCategory method from the `SavingList` class: + +| Method | Return Type | Relevance | +|-----------------------------|-------------|------------------------------------------------------------------| +| reduceSavingsByCategory() | void | Decreases the savings by a specified amount in a given category | + +The user interaction for reducing savings follows these steps: + +1. The user commands to reduce savings by inputting `reduce savings c/[category] a/[amount]`. +2. `BudgetBuddy` processes this input with the help of a `Parser`, which identifies the suitable `CommandCreator`. +3. `Parser` constructs a `ReduceSavingCommand` object with the extracted category and amount. +4. `BudgetBuddy` then executes the `ReduceSavingCommand`. +5. The `execute()` method within ReduceSavingCommand calls the SavingList's reduceSavingsByCategory function. +6. The `reduceSavingsByCategory` method performs the deduction and updates the savings amount. + +The following UML Sequence diagram below shows how the Reduce savings Feature Command is executed when a user +inputs a valid reduce savings command: +(will insert diagram soon) + +### 4.7 Delete Expenses Feature +The Delete Expense feature grants users the capability to remove expenses they have previously entered. Managed by the +DeleteExpenseCommand class, this feature is initialized through DeleteExpenseCommandCreator. During the creation process, +the command is provided with an `ExpenseList` object and an `index` indicating the specific expense to be deleted. +The following table outlines the significance of these attributes: + +| Class Attribute | Variable Type | Relevance | +|-----------------|---------------|------------------------------------------------------------------------| +| expenses | ExpenseList | ExpenseList Object containing the list of expenses that can be edited | +| index | Integer | The edited category for the expense in the specified index | + +On invocation of the `execute()` method, as part of the `command.execute() `flow within BudgetBuddy, the DeleteExpenseCommand +object engages the deleteExpense() method from the ExpenseList class. + +| Method | Return Type | Relevance | +|-----------------------------|-------------|-----------------------------------------------------------| +| deleteExpense() | void | Removes the expense at the specified index from the list | + +The user interaction for deleting expenses follows these steps: +1. The user submits a delete command in the format `delete expense i/index`, with `index` specifying the expense to be deleted. +2. `BudgetBuddy` receives the command and employs the Parser to deconstruct it. +3. The `Parser` discerns the delete command, extracting the index value and forming a DeleteExpenseCommand object. +4. `BudgetBuddy` triggers the DeleteExpenseCommand.execute() method. +5. Inside `execute()`, the `deleteExpense()` method is called on `ExpenseList`, with `index` indicating the targeted expense. +6. If the index is valid, the expense is removed, and a confirmation message is printed to the console. ### Listing Feature (List Savings) From bba62b65f9ff7f99d1eecda6b6c3cf44b810c35e Mon Sep 17 00:00:00 2001 From: Dheekshitha2 Date: Sat, 13 Apr 2024 21:21:06 +0800 Subject: [PATCH 46/46] Resolve merge conflict and wrong close bracket --- src/main/java/seedu/budgetbuddy/commons/ExpenseList.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java index b0f794ff8e..351e43e4d9 100644 --- a/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java +++ b/src/main/java/seedu/budgetbuddy/commons/ExpenseList.java @@ -209,11 +209,11 @@ public void addExpense(String category, String amount, String description) throw if (amountAsDouble > MAX_AMOUNT) { throw new BudgetBuddyException("Amount exceeds the maximum allowed limit of " + MAX_AMOUNT); } - - Expense expense = new Expense(matchedCategory, amountAsDouble, description); - expenses.add(expense); - System.out.println("Expense added: " + category + " ->z $" + String.format("%.2f", amountAsDouble)); } + + Expense expense = new Expense(matchedCategory, amountAsDouble, description); + expenses.add(expense); + System.out.println("Expense added: " + category + " ->z $" + String.format("%.2f", amountAsDouble)); }