PROJECT: ExpenseTracker

Overview

This portfolio aims to document my role and contribution to the ExpenseTracker.

ExpenseTracker is a desktop application used for tracking user’s expenses. The user interacts with it using a Command Line Interface (CLI), and it has a Graphical User Interface (GUI) created with JavaFX. It is written in Java, and has about 28 kLoC. It is the product of CS2103T team project.

The main purpose of this project is to morph AddressBook - Level 4, a given desktop application, into any new application. We work as a team of 5.

Some of the main features of ExpenseTracker are:

  1. Setting a budget for expenses.

  2. Multiple user accounts.

  3. Categorization of expenses.

  4. Statistics for expenses.

Summary of contributions

This section summarizes my contribution to the project.

  • Major enhancement:

    • Added the ability to find and edit multiple expenses by specific keywords

      • What it does: Allow user to filter out the particular expenses by entering relevant keywords. Allow user to edit all targeted expenses at the same time.

      • Justification: This feature improves the product significantly because now it is more convenient for user to find and edit particular expenses. Now users can easily view the list of expenses with desired details, for example,specific name, category, cost and date. With mass edit, users can easily correct the wrongly recorded expenses.

      • Highlights: This feature enhances the original filtering function. This makes the application more user-friendly as filtering is one of the most frequently used commands in this application.

  • Minor enhancement:

    • Refactored original AddressBook and Person class into ExpenseTracker and Expense class.

    • Updated sample entries.

    • Modified the original UniquePersonList into ExpenseList to allow for duplicate Expense.

  • Code contributed: [code]

  • Other contributions:

    • Community:

      • Reported bugs for other teams(examples: 1, 2)

    • Documentation:

      • Updated Architecture and Dev Op sections of Developer Guide: #91

Contributions to the User Guide

Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users.

Locating expenses by keywords: find

Finds expense which contains all the given keywords.

Format: find [n/NAME] [c/CATEGORY] [$/COST:COST] [d/DATE:DATE] [t/TAG…​]

To use find command, simply enter the command in correct format and the desired expenses will be shown on the expense list panel. The diagram below illustrates the effect of find command.

FindCommandExampleDiagram
Figure 1. Diagram to show the effect of find command

Examples:

  • find c/School
    Find all the expenses under the School category.

  • find d/1-10-2018:7-10-2018
    Find all the expenses which have dates between 1-10-2018 and 7-10-2018(inclusive).

  • find d/1-10-2018
    Find all the expenses with dates on 1-10-2018

  • find $/10.00:20.00
    Find all the expenses with costs between 10 and 20(inclusive).

  • find $/10.00
    Find all the expenses with costs of 10.00.

  • find c/School t/lunch d/1-10-2018
    Find all the expenses under the "School" category, with "lunch" tags and dates on 1-10-2018.

  • At least one keyword should be provided

  • Keywords are case insensitive, i.e. the KEYWORD have is equivalent to the KEYWORD Have

  • The order of the keywords does not matter, i.e. the KEYWORD Have lunch is equivalent to the KEYWORD lunch have

  • Partial words will be matched, i.e. using the KEYWORD Hav for expense name will give an expense with the name Have

  • Only Tag keywords can have multiple keywords. Name,Category,Cost,Date can only have one keyword, i.e. find t/lunch t/family is permitted but find n/school n/book is not permitted.

Editing multiple expenses : massedit

Edits the all expenses which match the keywords specified. Existing values of the expense will be edited according to the value of the parameters

Format: massedit [n/EXPENSE_NAME] [$/COST] [c/CATEGORY] [d/DATE] [t/TAG…​] -> [n/EXPENSE_NAME] [$/COST] [c/CATEGORY] [d/DATE] [t/TAG…​]

To use massedit command, simply enter the command in correct format. The edited command will be shown on the expense list panel. The diagram below illustrate the effect of massedit command.

MassEditCommandExampleDiagram
Figure 2. Diagram to show the effect of massedit command

Examples:

  • massedit c/school -> c/food
    Edits all the expenses in the "school" category to have their categories changed to "food".

  • massedit n/School fee d/01-10-2018:03-10-2018 -> t/books
    Edits all the expenses which have names containing "School", with dates between "01-10-2018" and "03-10-2018", to have their tags changed to "book".

  • massedit $/1.00:2.00 -> c/waste n/saving
    Edits all the expenses which have costs between "1.00" and "2.00" to have their categories changed to "waste" and names changed to "saving".

  • massedit c/shopping $/100.00 -> n/waste $/200.00
    Edits all the expenses in the "shopping" category, which have a cost of "100.00", to have their names changed to "waste" and costs changed to "200.00".

  • At least one keyword before -> and one keyword after -> must be provided.

  • The order of the keywords does not matter.

  • Keywords are case insensitive, i.e. the KEYWORD have is equivalent to the KEYWORD Have

  • COST should be a non-zero positive number with two decimal places

  • DATE should be in the format of "dd-mm-yyyy".

  • DATE can be a date in the future

  • Only Tag keywords can have multiple keywords. Name,Category,Cost,Date can only have one keyword, i.e. find t/lunch t/family is permitted but find n/school n/book is not permitted.

Contributions to the Developer Guide

Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project.

Find

This feature allows users to filter out specific expenses by entering multiple keywords. Only the expenses which contain all the keywords will be shown on the expense list panel.

This implementation is under Logic and Model Components.

Current Implementation

Below is the UML sequence diagram and a step-by-step explanation of an example usage scenario.

FindCommandSequenceDiagram
Figure 3. Sequence diagram of find mechanism
  1. User enters command find n/Have Lunch f/Food d/01-01-2018:03-01-2018. The command is received by ExpenseTrackerParser, which then creates a FindCommandParser Object and calls FindCommandParser#parse() method.

  2. FindCommandParser#parse() method calls ArgumentTokenizer#tokenize() to tokenize the input String into keywords and store them in an ArgumentMultimap Object.

  3. FindCommandParser#parse() method then calls ParserUtil#ensureKeywordsAreValid() method. If any of the keywords doesn’t conform to the correct format, ParseException will be thrown. If no exception is thrown, a ExpenseContainsKeywordsPredicate Object is created. It implements Predicate<Expense> interface and is used to filter out all the expenses which matches the keywords entered by the user.

  4. A FindCommand Object with the ExpenseContainsKeywordsPredicate Object as parameter is created and returned to LogicManager.

  5. LogicManager then calls FindCommand#execute(),which calls Model#updateFilteredExpenseList() method to update the predicate of FilterList<Expense>. FilterList now contains new set of expenses which filtered by the new predicate.

  6. Then the expense list panel will show a new set of expenses according to the keywords. A CommandResult is then created and returned to LogicManager.

Design Consideration

This feature can be implemented in different ways in terms of how the target expenses are found. The alternative ways of implementation are shown below.

Aspect: How to filter out targeted expenses
  • Alternative 1 (current choice): Check through all expenses and select those with all the keywords

    • Pros: Easy to implement. No need to change original architecture.

    • Cons: Time-consuming. Tend to take longer time when there is a large number of expenses.

  • Alternative 2: Store expenses in separate files and only check the relevant files while filtering.

    • Pros: More efficient. No need to check every expense.

    • Cons: Need to change the original architecture of storage.

Mass Edit

This feature allows users to edit multiple expenses at the same time. Users need to enter the keywords to identify the targeted expenses as well as the fields they would like to edit.

This implementation is under Logic and Model components.

Current implementation

Below is the UML sequence diagram and a step-by-step explanation of an example usage scenario.

MassEditCommandSequenceDiagram
Figure 4. Sequence diagram of mass edit mechanism
  1. User enters command massedit c/school -> c/work d/01-01-2018. The command is received by ExpenseTrackerParser, which then creates a MassEditCommandParser Object and calls MassEditCommandParser#parse() method.

  2. MassEditCommandParser#parse() method calls ArgumentTokenizer#tokenize() to tokenize the input String into keywords and store them in two ArgumentMultimap Objects.

  3. MassEditCommandParser#parse() method then create a ExpenseContainsKeywordsPredicate Object. Then it calls EditExpenseDescriptor#createEditExpenseDescriptor() method to create an EditExpenseDescriptor Object which stores the fields of expenses which are going to be edited.

  4. A MassEditCommand Object with the ExpenseContainsKeywordsPredicate and EditExpenseDescriptor Object as parameters is created and returned to LogicManager.

  5. LogicManager then calls MassEditCommand#execute(),which calls Model#updateFilteredExpenseList() method to update the predicate of FilterList<Expense>. Model#getFilteredExpenseList() is called to return the FilterList<Expense>.

  6. All the Expense in the FilterList<Expense> are then added to a new list. A loop starts and for each Expense in the list, EditExpenseDescriptor#createEditedExpense() is called to create an edited Expense object. Then Model#updateExpense is called to replace the original Expense with edited Expense.

  7. When loop ends, Model#updateFilteredExpenseList() is called to show the edit Expense to the user. A CommandResult is then created and returned to LogicManager.

Design Consideration

This feature can be implemented in different ways in terms of how the target expenses are edited. The alternative ways of implementation are shown below.

Aspect: How to Edit the targeted expenses
  • Alternative 1(current choice): Filter out the targeted expenses and replace them with edited expenses.

    • Pros: Easy to implement. Align with current architecture.

    • Cons: Time-consuming. Tend to take longer time when there is a large number of expenses.

  • Alternative 2: Store expenses in separate files. When the expenses are edited, move them to another file according to the edited fields.

    • Pros: Easy to identify the targeted expenses by checking relevant files. No need to check every expense.

    • Cons: Need to change original architecture of storage. May need to create new files during edition.