Skip to content

Commit 5398ef2

Browse files
authored
Merge branch 'master' into master
2 parents 101f3d6 + 5670223 commit 5398ef2

22 files changed

+375
-34
lines changed

docs/UserGuide.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,20 @@ Examples:
7676

7777
Shows a list of all expenses.
7878

79-
Format: `list [c/CATEGORY]`
80-
81-
<div markdown="span" class="alert alert-primary">:bulb: **Tip:**
82-
Category item is optional for showing all expenses in the specific category.
83-
</div>
79+
Format: `list`
8480

8581
Examples:
8682
* `list`: list all the expenses in all the categories.
87-
* `list c/FOODBEVERAGE`: list all the expenses in the food beverage category.
83+
84+
### Listing all expenses in a category : `listbycategory`
85+
86+
Shows a list of all expenses belongs to the category.
87+
88+
Format: `listbycategory CATEGORY`
89+
90+
Examples:
91+
* `listbycategory entertainment`: list all the expenses in entertainment.
92+
8893

8994
### Deleting an expense: `delete`
9095

@@ -116,6 +121,12 @@ The index refers to the index number shown in the displayed expense list.
116121
Examples:
117122
* `view 1` views the `amount, category, date and description` of the 1st expense displayed in the list.
118123

124+
### View Category Labels : `viewCategory`
125+
126+
Show all the category lables used in the UniSave.
127+
128+
Format: `viewCategory`
129+
119130
### Add a description to an expense : `addDes`
120131

121132
Add a description to an existing expense in the finance book.
@@ -187,6 +198,7 @@ Action | Format, Examples
187198
**List** | `list`
188199
**Delete** | `delete INDEX`<br> e.g., `delete 3`
189200
**View** | `view INDEX`<br> e.g., `view 5`
201+
**View existing categori labels** | `viewCategory`
190202
**Add Description** | `addDes INDEX d/DESCRIPTION`<br> e.g., `addDes 2 d/ENTERTAINMENT`
191203
**Delete Description** | `deleteDes INDEX`<br> e.g., `deleteDes 2`
192204
**Set Budget** | `setBudget a/AMOUNT`<br> e.g., `setBudget a/1000`

src/main/java/seedu/address/ExpenseMainApp.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ public void init() throws Exception {
6969
}
7070

7171
/**
72-
* Returns a {@code ExpenseModelManager} with the data from {@code storage}'s expense book and {@code userPrefs}. <br>
72+
* Returns a {@code ExpenseModelManager} with the data from {@code storage}'s expense book
73+
* and {@code userPrefs}. <br>
7374
* The data from the sample expense book will be used instead if {@code storage}'s expense book is not found,
7475
* or an empty expense book will be used instead if errors occur when reading {@code storage}'s expense book.
7576
*/

src/main/java/seedu/address/commons/core/Messages.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
public class Messages {
77
public static final String MESSAGE_INVALID_EXPENSE_DISPLAYED_INDEX = "The expense index provided is invalid";
8-
8+
public static final String MESSAGE_EXPENSES_LISTED_OVERVIEW = "%1$d expenses listed!";
99

1010

1111
public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command";

src/main/java/seedu/address/logic/commands/DeleteDescriptionCommand.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
import seedu.address.commons.core.index.Index;
99
import seedu.address.logic.commands.exceptions.CommandException;
1010
import seedu.address.model.Model;
11-
import seedu.address.model.person.Expense;
1211
import seedu.address.model.person.Description;
12+
import seedu.address.model.person.Expense;
13+
1314

1415

1516
/**
@@ -30,8 +31,8 @@ public class DeleteDescriptionCommand extends Command {
3031
public static final String MESSAGE_ARGUMENTS = "Index: %1$d, Description: %2$s";
3132
public static final String MESSAGE_ADD_DESCRIPTION_SUCCESS = "Added description to Expense: %1$s \n";
3233
public static final String MESSAGE_DELETE_DESCRIPTION_SUCCESS = "Removed description from Expense: %1$s \n";
33-
private final Index index;
3434
private static final Description EMPTY_DESCRIPTION = new Description("");
35+
private final Index index;
3536

3637
/**
3738
* @param index of the expense in the filtered expense list to edit the description
@@ -51,7 +52,8 @@ public CommandResult execute(Model model) throws CommandException {
5152
}
5253

5354
Expense expenseToEdit = lastShownList.get(index.getZeroBased());
54-
Expense editedExpense = new Expense(expenseToEdit.getAmount(), expenseToEdit.getDate(), expenseToEdit.getCategory(),
55+
Expense editedExpense = new Expense(expenseToEdit.getAmount(), expenseToEdit.getDate(),
56+
expenseToEdit.getCategory(),
5557
EMPTY_DESCRIPTION);
5658

5759
model.setExpense(expenseToEdit, editedExpense);
@@ -85,4 +87,4 @@ private String generateSuccessMessage(Expense expenseToEdit) {
8587
String message = MESSAGE_DELETE_DESCRIPTION_SUCCESS;
8688
return String.format(message, expenseToEdit);
8789
}
88-
}
90+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package seedu.address.logic.commands;
2+
3+
import static java.util.Objects.requireNonNull;
4+
5+
import seedu.address.commons.core.Messages;
6+
import seedu.address.model.Model;
7+
import seedu.address.model.person.CategoryContainsKeywordsPredicate;
8+
9+
/**
10+
* Finds and lists all expenses in expense book whose category contains any of the argument keywords.
11+
* Keyword matching is case insensitive.
12+
*/
13+
public class ListExpenseByCategoryCommand extends Command {
14+
15+
public static final String COMMAND_WORD = "listbycategory";
16+
17+
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all expenses whose category contains any of "
18+
+ "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n"
19+
+ "Parameters: KEYWORD [MORE_KEYWORDS]...\n"
20+
+ "Example: " + COMMAND_WORD + "entertainment";
21+
22+
private final CategoryContainsKeywordsPredicate predicate;
23+
24+
public ListExpenseByCategoryCommand(CategoryContainsKeywordsPredicate predicate) {
25+
this.predicate = predicate;
26+
}
27+
28+
@Override
29+
public CommandResult execute(Model model) {
30+
requireNonNull(model);
31+
model.updateFilteredExpenseList(predicate);
32+
return new CommandResult(
33+
String.format(Messages.MESSAGE_EXPENSES_LISTED_OVERVIEW, model.getFilteredExpenseList().size()));
34+
}
35+
36+
@Override
37+
public boolean equals(Object other) {
38+
return other == this // short circuit if same object
39+
|| (other instanceof ListExpenseByCategoryCommand // instanceof handles nulls
40+
&& predicate.equals(((ListExpenseByCategoryCommand) other).predicate)); // state check
41+
}
42+
}

src/main/java/seedu/address/logic/commands/SetBudgetCommand.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
package seedu.address.logic.commands;
22

3-
import seedu.address.logic.commands.exceptions.CommandException;
43
import seedu.address.model.Model;
54

65
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
76

87
public class SetBudgetCommand extends Command {
98
public static final String COMMAND_WORD = "setBudget";
10-
public static final String MESSAGE_SET_BUDGET_SUCCESS = "Successful! Te budget is now S$ %.2f.\n";
9+
public static final String MESSAGE_SET_BUDGET_SUCCESS = "Successful! The budget is now S$ %.2f.\n";
1110
public static final String MESSAGE_SET_BUDGET_FAIL = "Set Budget failed, please enter a valid budget.\n";
1211

1312
private final double budget;
@@ -18,7 +17,7 @@ public SetBudgetCommand(double budget) {
1817
}
1918

2019
@Override
21-
public CommandResult execute(Model model) throws CommandException {
20+
public CommandResult execute(Model model) {
2221
model.setExpenseBookBudget(budget);
2322
String msg = String.format(MESSAGE_SET_BUDGET_SUCCESS, budget);
2423
return new CommandResult(msg);

src/main/java/seedu/address/logic/commands/ShowBudgetCommand.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
package seedu.address.logic.commands;
22

3-
import seedu.address.logic.commands.exceptions.CommandException;
43
import seedu.address.model.Model;
54

65
public class ShowBudgetCommand extends Command {
76

87
public static final String COMMAND_WORD = "showBudget";
98
public static final String MESSAGE_BUDGET = "Current budget is: S$ %.2f\n";
109
public static final String MESSAGE_REMAINING = "Remaining budget is: S$ %.2f\n";
11-
public static final String MESSAGE_SETNEW = "Your current budget is S$0.00, \n"
10+
public static final String MESSAGE_SETNEW = "Your current budget is S$ %.2f, \n"
1211
+ "please set a new budget with command: setBudget AMOUNT\n";
1312

1413
@Override
15-
public CommandResult execute(Model model) throws CommandException {
16-
if (model.getExpenseBookBudget() == 0) {
17-
return new CommandResult(MESSAGE_SETNEW);
14+
public CommandResult execute(Model model) {
15+
double budget = model.getExpenseBookBudget();
16+
if (model.getExpenseBookBudget() <= 0) {
17+
String setNew = String.format(MESSAGE_SETNEW, budget);
18+
return new CommandResult(setNew);
1819
} else {
19-
String budgetMsg = String.format(MESSAGE_BUDGET, model.getExpenseBookBudget());
20+
String budgetMsg = String.format(MESSAGE_BUDGET, budget);
2021
String remainingMsg = String.format(MESSAGE_REMAINING, model.getExpenseBookRemaining());
21-
2222
return new CommandResult(budgetMsg + remainingMsg);
2323
}
2424
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package seedu.address.logic.commands;
2+
3+
import seedu.address.logic.commands.exceptions.CommandException;
4+
import seedu.address.model.Model;
5+
import seedu.address.model.person.Category;
6+
import seedu.address.model.person.Expense;
7+
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
11+
public class ViewCategoryCommand extends Command {
12+
13+
public static final String COMMAND_WORD = "viewCategory";
14+
15+
public static final String MESSAGE_USAGE = COMMAND_WORD
16+
+ ": Finds all the category labels used in the ExpenseBook so far. \n"
17+
+ "Example: " + COMMAND_WORD ;
18+
19+
public static final String MESSAGE_VIEW_CATEGORY_LABELS_SUCCESS =
20+
"View all the existing category labels: \n";
21+
22+
public ViewCategoryCommand() {
23+
}
24+
25+
@Override
26+
public CommandResult execute(Model model) throws CommandException {
27+
String message = "";
28+
List<Category> categories = model.getCategoryLabels();
29+
for (int i = 0; i < categories.size(); i++){
30+
message = message + categories.get(i).categoryName + "\n";
31+
}
32+
return new CommandResult(MESSAGE_VIEW_CATEGORY_LABELS_SUCCESS + message);
33+
}
34+
35+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package seedu.address.logic.commands;
2+
3+
import static java.util.Objects.requireNonNull;
4+
5+
import java.util.List;
6+
7+
import seedu.address.commons.core.Messages;
8+
import seedu.address.commons.core.index.Index;
9+
import seedu.address.logic.commands.exceptions.CommandException;
10+
import seedu.address.model.Model;
11+
import seedu.address.model.person.Expense;
12+
13+
import static java.util.Objects.requireNonNull;
14+
15+
public class ViewCommand extends Command {
16+
public static final String COMMAND_WORD = "view";
17+
18+
public static final String MESSAGE_USAGE = COMMAND_WORD
19+
+ ": Views the expense identified by the index number used in the displayed expense list.\n"
20+
+ "Parameters: INDEX (must be a positive integer)\n"
21+
+ "Example: " + COMMAND_WORD + " 1";
22+
23+
public static final String MESSAGE_VIEW_EXPENSE_SUCCESS = "View Expense: %s";
24+
25+
private final Index targetIndex;
26+
27+
public ViewCommand(Index targetIndex) {
28+
this.targetIndex = targetIndex;
29+
}
30+
31+
@Override
32+
public CommandResult execute(Model model) throws CommandException {
33+
List<Expense> lastShownList = model.getFilteredExpenseList();
34+
35+
if (targetIndex.getZeroBased() >= lastShownList.size()) {
36+
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
37+
}
38+
39+
Expense expenseToView = lastShownList.get(targetIndex.getZeroBased());
40+
String prefix = String.format(MESSAGE_VIEW_EXPENSE_SUCCESS, targetIndex.getOneBased());
41+
String message = prefix + "\n" + expenseToView.toString();
42+
return new CommandResult(message);
43+
}
44+
45+
@Override
46+
public boolean equals(Object other) {
47+
return other == this // short circuit if same object
48+
|| (other instanceof ViewCommand // instanceof handles nulls
49+
&& targetIndex.equals(((ViewCommand) other).targetIndex)); // state check
50+
}
51+
}
52+

src/main/java/seedu/address/logic/parser/ExpenseBookParser.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package seedu.address.logic.parser;
22

3-
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
4-
import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND;
3+
import seedu.address.logic.commands.*;
4+
import seedu.address.logic.parser.exceptions.ParseException;
55

66
import java.util.regex.Matcher;
77
import java.util.regex.Pattern;
@@ -11,12 +11,17 @@
1111
import seedu.address.logic.commands.DeleteDescriptionCommand;
1212
import seedu.address.logic.commands.DeleteExpenseCommand;
1313
import seedu.address.logic.commands.DescriptionCommand;
14-
import seedu.address.logic.commands.HelpCommand;
1514
import seedu.address.logic.commands.ListExpenseCommand;
15+
import seedu.address.logic.commands.ListExpenseByCategoryCommand;
16+
import seedu.address.logic.commands.HelpCommand;
17+
import seedu.address.logic.commands.ViewCommand;
1618
import seedu.address.logic.commands.SetBudgetCommand;
1719
import seedu.address.logic.commands.ShowBudgetCommand;
1820
import seedu.address.logic.parser.exceptions.ParseException;
1921

22+
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
23+
import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND;
24+
2025
/**
2126
* Parses user input.
2227
*/
@@ -44,21 +49,34 @@ public Command parseCommand(String userInput) throws ParseException {
4449
switch (commandWord) {
4550
case DescriptionCommand.COMMAND_WORD:
4651
return new DescriptionCommandParser().parse(arguments);
52+
4753
case AddExpenseCommand.COMMAND_WORD:
4854
return new AddExpenseCommandParser().parse(arguments);
55+
4956
case DeleteExpenseCommand.COMMAND_WORD:
5057
return new DeleteExpenseCommandParser().parse(arguments);
5158

5259
case ListExpenseCommand.COMMAND_WORD:
5360
return new ListExpenseCommand();
61+
62+
case ViewCommand.COMMAND_WORD:
63+
return new ViewCommandParser().parse(arguments);
64+
65+
case ViewCategoryCommand.COMMAND_WORD:
66+
return new ViewCategoryCommandParser().parse(arguments);
67+
5468
case DeleteDescriptionCommand.COMMAND_WORD:
5569
return new DeleteDescriptionCommandParser().parse(arguments);
5670

71+
case ListExpenseByCategoryCommand.COMMAND_WORD:
72+
return new ListExpenseByCategoryCommandParser().parse(arguments);
73+
5774
case ShowBudgetCommand.COMMAND_WORD:
5875
return new ShowBudgetCommandParser().parse(arguments);
5976

6077
case SetBudgetCommand.COMMAND_WORD:
6178
return new SetBudgetCommandParser().parse(arguments);
79+
6280
default:
6381
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
6482
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package seedu.address.logic.parser;
2+
3+
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
4+
5+
import java.util.Arrays;
6+
7+
import seedu.address.logic.commands.ListExpenseByCategoryCommand;
8+
import seedu.address.logic.parser.exceptions.ParseException;
9+
import seedu.address.model.person.CategoryContainsKeywordsPredicate;
10+
11+
/**
12+
* Parses input arguments and creates a new ListExpenseByCategoryCommand object
13+
*/
14+
public class ListExpenseByCategoryCommandParser implements Parser<ListExpenseByCategoryCommand> {
15+
16+
/**
17+
* Parses the given {@code String} of arguments in the context of the ListExpenseByCategoryCommand
18+
* and returns a ListExpenseByCategoryCommand object for execution.
19+
* @throws ParseException if the user input does not conform the expected format
20+
*/
21+
public ListExpenseByCategoryCommand parse(String args) throws ParseException {
22+
String trimmedArgs = args.trim();
23+
if (trimmedArgs.isEmpty()) {
24+
throw new ParseException(
25+
String.format(MESSAGE_INVALID_COMMAND_FORMAT, ListExpenseByCategoryCommand.MESSAGE_USAGE));
26+
}
27+
28+
String[] categoryKeywords = trimmedArgs.split("\\s+");
29+
30+
return new ListExpenseByCategoryCommand(new CategoryContainsKeywordsPredicate(Arrays.asList(categoryKeywords)));
31+
}
32+
33+
}

0 commit comments

Comments
 (0)