PROJECT: ExpenseTracker


Overview

This portfolio aims to document the contributions made by Jonathan Tan Jit Ming to the Expense Tracker.

Expense Tracker is the product of a project done under one of the Software Engineering modules at NUS. The project involved working in a team of 5 people to enhance or morph an existing Address Book application.

Expense Tracker is a desktop application that can be used track one’s expenses and features a Command Line Interface (CLI) as the main mode of interaction. Expense Tracker aims to provide users with the necessary tools to become a better saver. The main features of Expense Tracker are the managing of expenses, budget setting and expense statistics.

Summary of contributions

Refer to this link to see my Code Contributions to Expense Tracker.

Below describes my contributions and enhancements to Expense Tracker and the project team:

Main feature

The main feature that I added was the functionality to display expense statistics, which is a bar chart or pie chart showing the user’s expenditure organised by time or category. This is a core feature of Expense Tracker as it allows the user to be informed about their spending patterns, and therefore helping the user become a better saver.

This feature required an in-depth understanding of the software architecture as it involves multiple components of the application.

Other Contributions

These are other contributions that I made to the project and the team:

  1. Ensured consistency in the language, formatting and structure of the project’s documentation. These changes can be seen in Pull Requests (PRs) #65, #66, #68, #89, #90, #95, #173, #180, #183, #185, and #189.

  2. Reviewed PRs made by teammates by providing meaningful comments, where necessary. The PRs I reviewed include #72, #73, #76, #91, #94, #98, #109, #128, #170, #179, #186, #187 and #188.

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.

Showing expense statistics: stats

Changes the Expense List to show the Statistics Panel if the Expense List is currently showing, then displays a graph of your expenditure over a specified time period, in a given MODE.

You can use this command to analyse your expenses, observe your spending patterns and to identify categories which take up most of your budget.

There are two available modes: Time and Category, which can be indicated by t or c respectively in the MODE parameter.

Choosing Time mode will show a bar chart, similar to the one below, in the statistics panel, where amounts for each day or month will displayed, depending on the specified PERIOD_AMOUNT and PERIOD, starting from the current day or month.

barChart
Figure 1. Statistics Panel showing a bar chart in Time mode

Choosing Category mode will show a pie chart, similar to the one below, in the statistics panel, where amounts for each category will displayed for expenses in the specified PERIOD_AMOUNT and PERIOD.

pieChart
Figure 2. Statistics Panel showing a pie chart in Category mode

The available options for PERIOD are d and m, which represents day and month respectively. E.g. if PERIOD_AMOUNT is 7 and MODE is d, the statistics will include data from the past 7 days.

Format: stats n/PERIOD_AMOUNT p/PERIOD m/MODE

Examples:

  • stats n/14 p/d m/t
    Shows the expense statistics for the past 14 days as a bar chart showing expenses for each day

  • stats n/3 p/m m/t
    Shows the expense statistics for the past 3 months as a bar chart showing expenses for each month

  • stats n/7 p/d m/c
    Shows the expense statistics for the past 7 days as a pie chart showing expenses for each category

  • stats n/3 p/m m/c
    Shows the expense statistics for the past 3 months as a pie chart showing expenses for each category

  • PERIOD_AMOUNT must be a positive integer

  • PERIOD can only be d or m, for day and month respectively

  • MODE can only be t or c, for time and category respectively

  • Leaving all parameters blank, i.e. typing the command stats, defaults in showing expenses for the past 7 days in Time mode.

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.

Statistics

The implementation of the Statistics function can be divided into two phases - preparation and execution. Given below is an explanation of how the statistics mechanism behaves at each phase.

Preparation

In the preparation phase, the program parses the command for statistics, prepares filters used by the model and posts events in EventsCenter. Below is the UML sequence diagram and a step-by-step explanation of the preparation stage.

StatsPreparationSequenceDiagram
Figure 3. Sequence diagram of the preparation stage in the statistics mechanism
  1. User enters command stats command e.g. stats n/7 p/d m/t. The command is received by ExpenseTrackerParser, which calls creates StatsCommand and calls StatsCommandParser#parse() to create StatsCommand.

  2. If no parameters are provided by the user, StatsCommand#StatsCommand() is called to create StatsCommand with the default parameters of periodAmount as 7, period as d and mode as t. Otherwise, StatsCommand#StatsCommand(periodAmount, period, mode) is called to create StatsCommand with the specified parameters.

  3. StatsCommand checks if the parameters are valid. If any parameter is invalid, an exception will be raised and a message will be displayed to the user. Otherwise, the parameters are stored in instance variables and StatsCommand is returned to LogicManager.

  4. LogicManager then calls StatsCommand#execute(), which updates expensePredicate, statsMode, statsPeriod and periodAmount in ModelManager, which are variables in ModelManager relevant for statistics. StatsCommand#execute() also posts ShowStatsRequestEvent and SwapLeftPanelEvent events to EventsCenter.

Execution

In the execution phase, the program handles ShowStatsRequestEvent posted by StatsCommand by processing and retrieving the data to be displayed and finally displaying it. Below is the UML sequence diagram and a step-by-step explanation of the execution stage.

StatsExecutionSequenceDiagram
Figure 4. Sequence diagram of the execution stage in the statistics mechanism
  1. The ShowStatsRequestEvent event is handled by MainWindow#handleShowStatsEvent(), which calls 'StatisticsPanel#setData()' and passes the data as parameters by calling Logic#getExpenseStats(), Logic#getStatsPeriod(), Logic#getStatsMode() and Logic#getPeriodAmount().

  2. Logic#getExpenseStats() gets the filtered expense list by calling Model#getExpenseStats(), which returns an unmodifiable ObservableList, only containing only expenses in the last 7 days, as per ModelManager#expensePredicate, and sorted by date.

  3. Logic#getExpenseStats() then organises the data into a LinkedHashMap<String, Double>, where the key value pair represents the data series of the chart. If StatsMode is set to TIME, the key and value pair represents date and cost. If StatsMode is set to CATEGORY, the key value pair represents category and cost. Regardless of mode, the values are cumulative and is implemented using the algorithm in the following code snippet, using the example of category mode:

    LinkedHashMap<String, Double> stats = new LinkedHashMap<>();
    for (Expense e : expenseList) {
        String category;
        category = e.getCategory().categoryName;
    
        if (stats.containsKey(category)) {
            stats.put(
                    category,
                    stats.get(category) + e.getCost().getCostValue()
            );
        } else {
            stats.put(category, e.getCost().getCostValue());
        }
    }
  4. Logic#getStatsPeriod(), Logic#getStatsMode() and Logic#getPeriodAmount() gets their respective data by calling the method of the same name in Model.

  5. Once the parameters are passed into StatisticsPanel#setData(), StackPane#getChildren()#clear() is called to clear any display elements in StackPane. JavaFX’s BarChart and PieChart are used to render the charts. There are three scenarios which could happen:

    1. If the data received is empty, a Text object is generated and StackPane#getChildren()#add() is called, which informs the user that there are no expenditures

    2. If StatsMode is set to TIME, StatisticsPanel#setTimeBasedData() will be called, which generates a Bar Chart and calls StackPane#getChildren()#add(), which adds it to StackPane.

    3. If StatsMode is set to CATEGORY, StatisticsPanel#setCategoryBasedData() will be called, which generates a Pie Chart and calls StackPane#getChildren()#add(), which adds it to StackPane.

Design Considerations

Aspect: How to handle statistics data and parameters
  • Alternative 1 (current choice): Data and each parameter is handled as separate objects

    • Pros: Easy to implement.

    • Cons: Need to call multiple methods to get parameters

  • Alternative 2 (planned for future releases): Create Statistics object which contains data and all the parameters.

    • Pros: More scalable. Less method calls to get parameters.

    • Cons: None

Aspect: How to pass statistics data and parameters from Command to UI
  • Alternative 1 (current choice): UI gets all data and parameters from Logic, which gets data from Model.

    • Pros: Easy to implement. Aligned with architecture.

    • Cons: A lot of method calls

  • Alternative 2: Pass data and parameters through event

    • Pros: Less method calls. Easier to read.

    • Cons: Not in alignment with architecture. Need to consider application startup when there are no events posted.