Skip to content

Commit

Permalink
Merge 1085fc8 into b92c5c3
Browse files Browse the repository at this point in the history
  • Loading branch information
choonx99 committed Oct 23, 2019
2 parents b92c5c3 + 1085fc8 commit c36172b
Show file tree
Hide file tree
Showing 43 changed files with 1,505 additions and 45 deletions.
26 changes: 24 additions & 2 deletions src/main/java/seedu/address/MainApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,13 @@
import seedu.address.model.ReadOnlyExpenseList;
import seedu.address.model.ReadOnlyUserPrefs;
import seedu.address.model.UserPrefs;
import seedu.address.model.budget.BudgetList;
import seedu.address.model.budget.ReadOnlyBudgetList;
import seedu.address.model.util.SampleDataUtil;

import seedu.address.storage.BudgetListStorage;
import seedu.address.storage.ExpenseListStorage;
import seedu.address.storage.JsonBudgetListStorage;
import seedu.address.storage.JsonExpenseListStorage;
import seedu.address.storage.JsonUserPrefsStorage;
import seedu.address.storage.Storage;
Expand Down Expand Up @@ -57,7 +62,8 @@ public void init() throws Exception {
UserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(config.getUserPrefsFilePath());
UserPrefs userPrefs = initPrefs(userPrefsStorage);
ExpenseListStorage expenseListStorage = new JsonExpenseListStorage(userPrefs.getExpenseListFilePath());
storage = new StorageManager(expenseListStorage, userPrefsStorage);
BudgetListStorage budgetListStorage = new JsonBudgetListStorage(userPrefs.getBudgetListFilePath());
storage = new StorageManager(expenseListStorage, budgetListStorage, userPrefsStorage);

initLogging(config);

Expand All @@ -75,7 +81,9 @@ public void init() throws Exception {
*/
private Model initModelManager(Storage storage, ReadOnlyUserPrefs userPrefs) {
Optional<ReadOnlyExpenseList> expenseListOptional;
Optional<ReadOnlyBudgetList> budgetListOptional;
ReadOnlyExpenseList initialData;
ReadOnlyBudgetList initialBudgets;
try {
expenseListOptional = storage.readExpenseList();
if (!expenseListOptional.isPresent()) {
Expand All @@ -90,7 +98,21 @@ private Model initModelManager(Storage storage, ReadOnlyUserPrefs userPrefs) {
initialData = new ExpenseList();
}

return new ModelManager(initialData, userPrefs);
try {
budgetListOptional = storage.readBudgetList();
if (!budgetListOptional.isPresent()) {
logger.info("Data file not found. Will be starting with a sample BudgetList");
}
initialBudgets = budgetListOptional.orElseGet(SampleDataUtil::getSampleBudgetList);
} catch (DataConversionException e) {
logger.warning("Data file not in the correct format. Will be starting with an empty BudgetList");
initialBudgets = new BudgetList();
} catch (IOException e) {
logger.warning("Problem while reading from the file. Will be starting with an empty BudgetList");
initialBudgets = new BudgetList();
}

return new ModelManager(initialData, initialBudgets, userPrefs);
}

private void initLogging(Config config) {
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/seedu/address/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ public CommandResult execute(String commandText) throws CommandException, ParseE
throw new CommandException(FILE_OPS_ERROR_MESSAGE + ioe, ioe);
}

try {
storage.saveBudgetList(model.getBudgetList());
} catch (IOException ioe) {
throw new CommandException(FILE_OPS_ERROR_MESSAGE + ioe, ioe);
}

return commandResult;
}

Expand Down
67 changes: 67 additions & 0 deletions src/main/java/seedu/address/logic/commands/AddBudgetCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.parser.CliSyntax.PREFIX_AMOUNT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_DATE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_END_DATE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;

import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.budget.Budget;

/**
* Adds a budget into the budget list.
*/
public class AddBudgetCommand extends Command {

public static final String COMMAND_WORD = "budget";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a budget to the budget list.\n"
+ "Parameters: "
+ PREFIX_NAME + "NAME "
+ PREFIX_AMOUNT + "AMOUNT "
+ PREFIX_DATE + "START-DATE "
+ PREFIX_END_DATE + "END-DATE...\n"
+ "Example: " + COMMAND_WORD + " "
+ PREFIX_NAME + "Japan Travel "
+ PREFIX_AMOUNT + "$2000.00 "
+ PREFIX_DATE + "12/12/2019 "
+ PREFIX_END_DATE + "18/12/2019\n";


public static final String MESSAGE_SUCCESS = "New budget added: %1$s";
public static final String MESSAGE_DUPLICATE_BUDGET = "This budget already exists in the budget list";
public static final String MESSAGE_BUDGET_CLASH = "This budget period clashes with another budget";
public static final String MESSAGE_START_BEFORE_END = "The budget end date has to be after its start date";

private final Budget toAdd;

/**
* Creates an AddBudgetCommand to add the specified {@code Budget}
*/
public AddBudgetCommand(Budget budget) {
requireNonNull(budget);
toAdd = budget;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);

if (toAdd.getEndDate().localDate.isBefore(toAdd.getStartDate().localDate)) {
throw new CommandException(MESSAGE_START_BEFORE_END);
}

if (model.hasBudgetPeriodClash(toAdd)) {
throw new CommandException(MESSAGE_BUDGET_CLASH);
}

if (model.hasBudget(toAdd)) {
throw new CommandException(MESSAGE_DUPLICATE_BUDGET);
}

model.addBudget(toAdd);
return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd));
}
}
1 change: 1 addition & 0 deletions src/main/java/seedu/address/logic/commands/AddCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import seedu.address.model.Model;
import seedu.address.model.expense.Expense;


/**
* Adds an expense to the expense list.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package seedu.address.logic.parser;

import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_AMOUNT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_DATE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_END_DATE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;

import java.util.stream.Stream;

import seedu.address.logic.commands.AddBudgetCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.ExpenseList;
import seedu.address.model.budget.Budget;
import seedu.address.model.expense.Amount;
import seedu.address.model.expense.Date;
import seedu.address.model.expense.Name;

/**
* Parses input arguments and creates a new AddBudgetCommand object
*/
public class AddBudgetCommandParser implements Parser<AddBudgetCommand> {

/**
* Parses the given {@code String} of arguments in the context of the AddBudgetCommand
* and returns an AddBudgetCommand object for execution.
*
* @throws ParseException if the user input does not conform the expected format
*/
public AddBudgetCommand parse(String args) throws ParseException {
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_AMOUNT, PREFIX_DATE, PREFIX_END_DATE);

if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_AMOUNT, PREFIX_DATE, PREFIX_END_DATE)
|| !argMultimap.getPreamble().isEmpty()) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddBudgetCommand.MESSAGE_USAGE));
}

Name name = ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get());
Amount amount = ParserUtil.parseAmount(argMultimap.getValue(PREFIX_AMOUNT).get());
Date startDate = ParserUtil.parseDate(argMultimap.getValue(PREFIX_DATE).get());
Date endDate = ParserUtil.parseDate(argMultimap.getValue(PREFIX_END_DATE).get());

Budget budget = new Budget(name, amount, amount, startDate, endDate, new ExpenseList());

return new AddBudgetCommand(budget);
}

private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
}
}
1 change: 1 addition & 0 deletions src/main/java/seedu/address/logic/parser/CliSyntax.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public class CliSyntax {
public static final Prefix PREFIX_AMOUNT = new Prefix("a/");
public static final Prefix PREFIX_CURRENCY = new Prefix("c/");
public static final Prefix PREFIX_DATE = new Prefix("d/");
public static final Prefix PREFIX_END_DATE = new Prefix("ed/");
public static final Prefix PREFIX_TAG = new Prefix("t/");

}
4 changes: 4 additions & 0 deletions src/main/java/seedu/address/logic/parser/MymParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import seedu.address.logic.commands.AddBudgetCommand;
import seedu.address.logic.commands.AddCommand;
import seedu.address.logic.commands.ClearCommand;
import seedu.address.logic.commands.Command;
Expand Down Expand Up @@ -68,6 +69,9 @@ public Command parseCommand(String userInput) throws ParseException {
case HelpCommand.COMMAND_WORD:
return new HelpCommand();

case AddBudgetCommand.COMMAND_WORD:
return new AddBudgetCommandParser().parse(arguments);

default:
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
}
Expand Down
62 changes: 62 additions & 0 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package seedu.address.model;

import java.nio.file.Path;
import java.util.Optional;
import java.util.function.Predicate;

import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.model.budget.Budget;
import seedu.address.model.budget.ReadOnlyBudgetList;
import seedu.address.model.expense.Expense;

/**
Expand All @@ -13,6 +16,7 @@
public interface Model {
/** {@code Predicate} that always evaluate to true */
Predicate<Expense> PREDICATE_SHOW_ALL_EXPENSES = unused -> true;
Predicate<Budget> PREDICATE_SHOW_ALL_BUDGETS = unused -> true;

/**
* Replaces user prefs data with the data in {@code userPrefs}.
Expand Down Expand Up @@ -85,4 +89,62 @@ public interface Model {
* @throws NullPointerException if {@code predicate} is null.
*/
void updateFilteredExpenseList(Predicate<Expense> predicate);

/**
* Returns the user prefs' budget list file path.
*/
Path getBudgetListFilePath();

/**
* Sets the user prefs' budget list file path.
*/
void setBudgetListFilePath(Path expenseListFilePath);

/**
* Replaces budget list data with the data in {@code budgetList}.
*/
void setBudgetList(ReadOnlyBudgetList budgetList);

/** Returns the BudgetList */
ReadOnlyBudgetList getBudgetList();

/**
* Returns true if a budget with the same identity as {@code budget} exists in the budget list.
*/
boolean hasBudget(Budget budget);

/**
* Deletes the given budget.
* The budget must exist in the budget list.
*/
void deleteBudget(Budget target);

/**
* Adds the given budget.
* {@code budget} must not already exist in the budget list.
*/
void addBudget(Budget budget);

/**
* Replaces the given budget {@code target} with {@code editedBudget}.
* {@code target} must exist in the budget list.
* The budget identity of {@code editedBudget} must not be the same as
* another existing budget in the budget list.
*/
void setBudget(Budget target, Budget editedBudget);

/** Returns an unmodifiable view of the filtered budget list */
ObservableList<Budget> getFilteredBudgetList();

/**
* Updates the filter of the filtered budget list to filter by the given {@code predicate}.
* @throws NullPointerException if {@code predicate} is null.
*/
void updateFilteredBudgetList(Predicate<Budget> predicate);

boolean hasBudgetPeriodClash(Budget newBudget);

Optional<Budget> getBudgetExpenseFallsInto(Expense expense);

boolean expenseFallsIntoABudget(Expense expense);
}
Loading

0 comments on commit c36172b

Please sign in to comment.