Skip to content

Commit

Permalink
Merge pull request #70 from yyangdaa/yangda
Browse files Browse the repository at this point in the history
Implement Splitter
  • Loading branch information
yyangdaa authored Mar 26, 2024
2 parents dcbab36 + 1dfcfcb commit 7188669
Show file tree
Hide file tree
Showing 12 changed files with 326 additions and 31 deletions.
10 changes: 10 additions & 0 deletions docs/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ Format: `add savings c/CATEGORY a/AMOUNT`
* The `AMOUNT` must be a positive integer.
* The `DESCRIPTION` can be any string.

### Add Split Expenses
Add expenses that are meant for splitting among friends or colleague

Format: `split expenses a/AMOUNT n/NUMBER_OF_PEOPLE d/DESCRIPTION`

* Increments split expenses
* The `AMOUNT` must be a positive number
* The `NUMER_OF_PEOPLE` must be a positive integer.
* The `DESCRIPTION` can be any string

Example of usage:

`add savings c/Salary a/10000`
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/seedu/budgetbuddy/BudgetBuddy.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class BudgetBuddy {
private Parser parser;
private ExpenseList expenses;
private SavingList savings;
private SplitExpenseList splitexpenses;

private Storage expensesStorage;
private Storage savingsStorage;
Expand All @@ -20,12 +21,13 @@ public BudgetBuddy() {
parser = new Parser();
expenses = new ExpenseList();
savings = new SavingList();
splitexpenses = new SplitExpenseList();
expensesStorage = new Storage("src/main/java/seedu/budgetbuddy/data/ExpenseFile.txt");
savingsStorage = new Storage("src/main/java/seedu/budgetbuddy/data/SavingsFile.txt");
}

public void handleCommands(String input) {
Command command = parser.parseCommand(expenses, savings, input);
Command command = parser.parseCommand(expenses, savings, splitexpenses, input);

if (command != null) {
command.execute();
Expand Down
108 changes: 97 additions & 11 deletions src/main/java/seedu/budgetbuddy/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import seedu.budgetbuddy.command.ListBudgetCommand;
import seedu.budgetbuddy.command.ListExpenseCommand;
import seedu.budgetbuddy.command.ListSavingsCommand;
import seedu.budgetbuddy.command.SplitExpenseCommand;
import seedu.budgetbuddy.command.ListSplitExpenseCommand;
import seedu.budgetbuddy.command.MenuCommand;
import seedu.budgetbuddy.command.ReduceSavingCommand;
import seedu.budgetbuddy.command.SetBudgetCommand;
Expand Down Expand Up @@ -63,6 +65,7 @@ private String extractDetailsForAdd(String details, String prefix) {
public Boolean isFindExpensesCommand(String input) {
return input.startsWith("find expenses");
}

public Boolean isListCommand(String input) {
return input.startsWith("list");
}
Expand All @@ -78,10 +81,22 @@ public Boolean isMenuCommand(String input) {
return input.startsWith("menu");
}

/**
* Checks if the provided input starts with the word "bye" .
*
* @param input The user input string
* @return true if user input starts with "bye", else returns false
*/
public Boolean isExitCommand(String input) {
return input.startsWith("bye");
}

/**
* Checks if the provided input starts with the word "add expense" .
*
* @param input The user input string
* @return true if user input starts with "add expense", else returns false
*/
public Boolean isAddExpenseCommand(String input) {
return input.startsWith("add expense");
}
Expand All @@ -106,6 +121,9 @@ public Boolean isReduceSavingCommand(String input) {
return input.startsWith("reduce");
}

public Boolean isSplitExpenseCommand(String input) {
return input.startsWith("split expenses");
}
public Boolean isSetBudgetCommand(String input){
return input.startsWith("set budget");
}
Expand All @@ -114,11 +132,11 @@ public boolean isListBudgetCommand(String input){
return input.startsWith("budget print");
}


/**
* Parses the "find expenses" command, allowing for optional and combinable parameters.
* Parses the "find expenses" command, allowing for optional and combinable
* parameters.
*
* @param input The full user input string.
* @param input The full user input string.
* @param expenses The ExpenseList to search within.
* @return A Command for executing the search, or null if the input is invalid.
*/
Expand All @@ -133,7 +151,7 @@ public Command handleFindExpensesCommand(String input, ExpenseList expenses) {

LOGGER.log(Level.INFO, "Begin parsing parameters in find expenses command");

if(!input.contains("d/") && !input.contains("morethan/") && !input.contains("lessthan/")) {
if (!input.contains("d/") && !input.contains("morethan/") && !input.contains("lessthan/")) {
LOGGER.log(Level.WARNING, "Input does not contain any parameters");

System.out.println("Please Ensure that you include d/, morethan/ or lessthan/");
Expand Down Expand Up @@ -178,7 +196,17 @@ public Command handleFindExpensesCommand(String input, ExpenseList expenses) {
return new FindExpensesCommand(expenses, description, minAmount, maxAmount);
}

public Command handleListCommand(String input, ExpenseList expenseList, SavingList savingList) {
/**
* Parses the "list" command, allowing for optional category filtering.
*
* @param input The full user input string.
* @param expenseList The ExpenseList to list from.
* @param savingList The SavingList to list from.
* @return A Command for executing the list, or null if the input is invalid.
*/

public Command handleListCommand(String input, ExpenseList expenseList, SavingList savingList,
SplitExpenseList splitexpenseList) {
assert input != null : "Input should not be null";
assert !input.isEmpty() : "Input should not be empty";

Expand Down Expand Up @@ -216,6 +244,9 @@ public Command handleListCommand(String input, ExpenseList expenseList, SavingLi
LOGGER.log(Level.WARNING, "Invalid category inputted: " + filterCategory, e);
}
return new ListExpenseCommand(expenseList, filterCategory);
} else if (parts.length == 3 && parts[1].equalsIgnoreCase("splitted")
&& parts[2].equalsIgnoreCase("expenses")) {
return new ListSplitExpenseCommand(splitexpenseList);
} else if (parts.length == 3 && parts[1].equalsIgnoreCase("savings")) {
String filterCategory = parts[2];
try {
Expand All @@ -238,8 +269,8 @@ public Command handleListCommand(String input, ExpenseList expenseList, SavingLi
break;
default:
return null;
}
return null;
}return null;

}


Expand Down Expand Up @@ -535,6 +566,57 @@ public Command handleReduceSavingCommand(SavingList savings, String input) {
}
}

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/");

// Validation for each part
if (amount.isEmpty() || numberOfPeople.isEmpty() || description.isEmpty()) {
System.out.println("Missing details.");
return null;
}

try {
double amountValue = Double.parseDouble(amount);
if (amountValue <= 0) {
throw new BudgetBuddyException(amount + " is not a valid amount.");
}
} catch (NumberFormatException | BudgetBuddyException e) {
System.out.println("Invalid amount format.");
return null;
}

try {
int 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.");
return null;
}

return new SplitExpenseCommand(splitexpenses, amount, numberOfPeople, description);
}

private String extractDetail(String input, String prefix) {
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);
} catch (Exception e) {
return ""; // Return empty string if any error occurs
}
}

private Command handleSetBudgetCommand(ExpenseList expenses, String input) {
LOGGER.log(Level.INFO, "Entering handleSetBudgetCommand with input: " + input);
String[] parts = input.split(" ");
Expand Down Expand Up @@ -580,7 +662,6 @@ public Command handleListBudgetCommand(ExpenseList expenseList) {
return new ListBudgetCommand(expenseList);
}


/**
* Parses a string input into a Command object and returns the associated
* command to handle the user input
Expand All @@ -589,8 +670,9 @@ public Command handleListBudgetCommand(ExpenseList expenseList) {
* @return A Command object corresponding to the user input, or null if the
* input is invalid.
*/
public Command parseCommand(ExpenseList expenses, SavingList savings, String input) {

public Command parseCommand(ExpenseList expenses, SavingList savings, SplitExpenseList
splitexpenses, String input) {

if(isMenuCommand(input)) {
LOGGER.log(Level.INFO, "Confirmed that input is a menu command");
return handleMenuCommand(input);
Expand Down Expand Up @@ -621,13 +703,17 @@ public Command parseCommand(ExpenseList expenses, SavingList savings, String inp
}

if (isListCommand(input)) {
return handleListCommand(input, expenses, savings);
return handleListCommand(input, expenses, savings, splitexpenses);
}

if (isFindExpensesCommand(input)) {
return handleFindExpensesCommand(input, expenses);
}

if (isSplitExpenseCommand(input)) {
return handleSplitExpenseCommand(splitexpenses, input);
}

if (isSetBudgetCommand(input)) {
return handleSetBudgetCommand(expenses, input);
}
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/seedu/budgetbuddy/SplitExpense.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package seedu.budgetbuddy;

public class SplitExpense {
private final String amount;
private final String description;
private final String numberOfPeople;

public SplitExpense(String amount, String numberOfPeople, String description) {
this.amount = amount;
this.numberOfPeople = numberOfPeople;
this.description = description;
}

public String getNumberOfPeople() {
return numberOfPeople;
}

public String getAmount() {
return amount;
}

public String getDescription() {
return description;
}

public double calculateAmountPerPerson() {
double amountValue = Double.parseDouble(amount);
double numberOfPeopleValue = Double.parseDouble(numberOfPeople);
return amountValue / numberOfPeopleValue;
}

public Boolean isExpenseSettled() {
return false;
}

@Override
public String toString() {
return "Number of People: " + numberOfPeople + " Amount: " + amount + " Description: " +
description + " Amount per person: " + calculateAmountPerPerson();
}
}
74 changes: 74 additions & 0 deletions src/main/java/seedu/budgetbuddy/SplitExpenseList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package seedu.budgetbuddy;

import java.util.ArrayList;
import java.util.List;

import seedu.budgetbuddy.exception.BudgetBuddyException;

import java.util.logging.Level;
import java.util.logging.Logger;

public class SplitExpenseList {
private static final Logger LOGGER = Logger.getLogger(SplitExpenseList.class.getName());
protected ArrayList <SplitExpense> splitexpenses;
public SplitExpenseList(ArrayList<SplitExpense> splitexpenses){
this.splitexpenses = splitexpenses;
}

public SplitExpenseList() {
this.splitexpenses = new ArrayList<>();
}

public int size() {
return splitexpenses.size();
}

public List<SplitExpense> getSplitExpenses() {
return splitexpenses;
}

public void listSplitExpenses() {
LOGGER.info("Listing splitexpenses...");

try {
System.out.println("Split Expenses: ");
for (int i = 0; i < splitexpenses.size(); i++) {
SplitExpense splitexpense = splitexpenses.get(i);

if (splitexpense == null) {
LOGGER.warning("Expense object at index " + i + " is null");
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.println("-----------------------------------------------------------------------------");

} catch (Exception e) {
LOGGER.log(Level.SEVERE, "An error occurred while listing expenses.", e);
}
}

public void addSplitExpense(String amount, String numberOfPeople, String description ) throws BudgetBuddyException {
assert amount != null : "Amount should not be null";
assert description != null : "Description should not be null";
LOGGER.info("Adding split expense...");

double amountDouble;
try{
amountDouble = Double.parseDouble(amount);
} catch (NumberFormatException e) {
throw new BudgetBuddyException("Invalid amount format. Amount should be a number.");
}

if (amountDouble < 0){
throw new BudgetBuddyException("Expenses should not be negative.");
}

SplitExpense splitexpense = new SplitExpense(amount, numberOfPeople, description);
splitexpenses.add(splitexpense);
}
}
Loading

0 comments on commit 7188669

Please sign in to comment.