PROJECT: Savee

What Savee is about:

Savee is an application my team has created for the NUS module CS2113T on Software Engineering Principles and Object Oriented Programming. Savee’s main target audience are students who need help managing their finances and likes typing. In Savee, there is a command box for inputting commands and graphic user interface(GUI) created using JavaFX was also used to display the output of the system to create a more intuitive and engaging user experience.

Summary of contributions

Throughout this development cycle, I have made much contributions to the team and below shows a summary of my contributions.

  • Major Enhancements: Facilitated the morph from AddressBook Level 4 to Savee

    • Reason for the enhancement Savee is mainly targeted at users who wants to store and keep track of their daily financial activity, which is not the same as AB4.

    • My contributions I adapted all model and storage components. I also fixed all the tests that broke as a result of the morph.

  • Major Enhancements: Added a feature that allows users to display a summary of their expenses and income by day, month and categories in a table

    • Reason for the enhancement Users want to have a way to track daily or monthly financial activities without having to go through the list.

    • Brief Description To see the summary within any date range, the user needs to enter 2 dates or 2 months and the corresponding parameters and the system would generate a summary table.

    • My contributions I created the framework for this feature. It covers many components comprising of parsing, data manipulation, logic and graphic user interface as output. The report was generated on a table panel which can be switched around with other user interface panels as necessary. I created all java logic components and the Java fxml layout files.

  • Major Enhancements: Added a feature that shows the breakdown of financial activity into categories

    • Reason for the enhancement Savee also allows users to tag each financial activity with a tag that they can define. These tags can be used for analysing financial activity.

    • Overview To further empower users to make informed choices, the statistics feature was designed to provide a detailed breakdown of all financial activity within a given period.

    • My contributions For this feature, there were 3 main parts, logic for the command, model to support statistics and the GUI. I created all the components necessary for this feature, with the most noteworthy implementation being user interface. Similar to summary, the Ui panel in this feature can be switched out for other panels. The pie charts used were generated using JavaFX pie chart library. However, I overwrote some parts of the in to allow for greater functionality using Java’s overriding feature.

  • Minor Enhancements: Added a welcome panel that displays breakdown for current month

    • Reason for the enhancement Users may want to get a sense of their current financial status without having to type a single command.

    • My contributions I created a system to track the current date and refresh the UI panel whenever it detects changes to the underlying list.

  • Minor Enhancements: Added an extension to list command

    • My contributions ListCommandParser of the original implementation was tweaked slightly to allow additional functionality.

  • Code contributed can be found here: https://nuscs2113-ay1819s1.github.io/dashboard/#=undefined&search=tenvinc

  • Project management

    • Managed releases for 4 milestones(v1.0 - v1.3)

    • Set up a workflow where pull requests are automatically blocked unless there is one other person who approved the request

  • Tools

    • Set up Continuous Integration, coverage tools and github website deployment

    • PRs reviewed(with non trivial comments)

  • Testing

    • Wrote extensive tests to increase coverage of the project

  • Documentation

    • Did a few cosmetic tweaks to the User Guide

    • Organised and ensured that documentation is coherent

Contributions to the User Guide

Below are some of my contributions to the User Guide. These show that I am able to write comprehensive User Guides.

Data Analysis Features

This section describe features for the user to analyse his/her financial status in greater detail.

Showing a summary table of all financial activity in a time period: summary

Shows a summary table listing by day, month or categories within a given time specified by the user.
A summary is an item that contains information on the date or month that is represented, the total expense calculated, the total income calculated and the net money flow calculated. A category refers to any set of tags that are assigned to any records in the application.

The summary command supports both listing by date, by month and by categories.
Format:

  • By Date: summary date d/START_DATE END_DATE

  • By Month: summary month d/START_MONTH END_MONTH

  • By Category: summary category d/START_DATE END_DATE

  • Note that there are specific formats required for the dates and months entered.

  • For the commands "summary date" and "summary category", START_DATE/END_DATE must be in the format of dd-mm-yyyy where dd represents day, mm represents month, yyyy represents year.

  • For command "summary month", START_MONTH/END_MONTH must in the format of mmm-yyyy, mmm represents the month with its three letter representations, and yyyy represents the year in its numerical form.

  • Refer to [constraints] for the more information on the parameters.

  • Note that for mmm, it is case-insensitive, meaning both "APR" and "apr" are accepted.

Examples:

  • summary date d/1-1-2018 12-12-2018

  • summary month d/apr-2018 sep-2018

  • summary month d/APR-2018 SeP-2018

  • summary category d/1-1-2018 12-12-2018

Showing a breakdown of total expenses and income into categories: stats

Shows a breakdown of total expenses and income into categories and displays these information in a pie chart.
Format:`stats d/START_DATE END_DATE`

  • START_DATE/END_DATE follow the same configurations as date parameters required when adding records. It is in the form of dd-mm-yyyy where dd represents day, mm represents month and yyyy represents the year. dd and mm both require 1 to 2 digits while yyyy requires exactly 4 digits.

  • Refer to [constraints] for the more information on the parameters.

Once the command has been executed, 2 tabs will appear showing a pie chart containing data that is relevant in the range.
At the same time, currently selected record will be unselected to reduce confusion for the user. If there are many categories shown and the box is not large enough, you can use the scroll bar at the side of each legend to view the other categories which are not in view.

Due to label constraints, some labels may not be displaying correctly if they are overlapping with other labels. This happens when the pie slice is too small. To improve readability, we have decided to hide some labels in such scenarios. Also, when the label is too long, since the pie charts need to fit the labels, the pie chart may become small as a result. To prevent such situations, please keep your labels short. This will be improved in later versions of the product to remove the labels completely and use a mouse over input instead.

Contributions to the Developer Guide

Below are some of my contributions to the Developer Guide. These show that I am able to utilise modelling tools such as UML diagrams, sequence diagrams, activity flow which are crucial to Software Engineering Principles to illustrate to potential developers the architecture of my product.

View summary feature

This feature allows the user to view a summary table of all their financial activity within a period of time. There are 3 different ways the user can view the summary, one is summary by date which means the summary of each day in the period will be provided, summary by month or summary by category.

The corresponding command required for this feature is summary and the user will have to supply 2 dates and a compulsory parameter mode which determines whether they are viewing summary by date, by month or by category. This feature involves most components of FinancialPlanner with the exception of Storage. It can also be broadly split into 2 phases, the logic phase which generates the summary and the UI phase which allows users to view the summary in a table.

As shown below, SummaryByDateCommand, SummaryByCategoryCommand, SummaryByMonthCommand is a type of SummaryCommand and thus inherits from SummaryCommand. The rationale behind this design choice is that code shared by these classes can be placed in SummaryCommand for code reuse. This makes it easier for future developers to easily extend this functionality.

SummaryCommandClassDiagram
Figure 1. Class diagram showing the inheritance from SummaryCommand

Also, these commands utilise their own version of summary lists which is also inherited from the parent class SummaryList as shown below. Below details the logic phase.

  1. When the user types in the command "summary date d/1-1-2018 12-12-2018", the command is passed from LogicManager to FinancialPlannerParser. In here, the system chooses which parser to use and calls its parse method which is polymorphic, meaning that every parser has the same function but use different implementation.

  2. In this class, based on the mode parameter given, the system chooses a SummaryCommand to instantiate and pass the reference back to the Logic Manager. The various checks for the validity of the parameters also occur during this stage.

  3. After the SummaryCommandObject is created, SummaryByDateCommand#execute is called. The responsibility of SummaryByDateCommand is a manager that has retrieves information from model and passes it to other components. SummaryByDateCommand gets the filtered list from Model using Model#getFilteredRecordList and passes it to the constructor of SummaryByDateList. The creates SummaryList object which is then passed into a ShowSummaryTableEvent before triggering the event.

  4. The entire logic process is the same for SummaryByMonthCommand and SummaryByCategoryCommand but uses different lists.

The sequence diagram below details the sequence of program executions for the logic phase.

SummarySequenceDiagram
Figure 2. Sequence diagram for high level interactions in logic phase

The next phase of the program execution is performed in the UI components.

  1. MainWindow will listen for the ShowSummaryTableEvent and render all Main UI panels invisible before rendering StatsDisplayPanel visible.

  2. It then calls the handler function in StatsDisplayPanel which will create tabs and call the constructor of SummaryDisplay.

  3. Within the constructor of SummaryDisplay, the table is created and the SummaryList is converted into a Ui friendly list.

Design Considerations

Aspect: Method of generating the summary
  • Alternative 1 (current choice): Generate the summary list whenever the summary command is called.

    • Pros: Easier to implement and maintain. Sufficient for the intended target audience of FinancialPlanner.

    • Cons: This requires looping through each record in the filtered record list obtained from the Model. To aid in the time complexity, the internal implementation of SummaryList was done using hash maps instead which allowed for constant time random access.. However, the initial filtering is close to linear time complexity which could slow down the app if many records are inside. Also, the list had to be created every time summary is called which could be slow if the command is called multiple times.

  • Alternative 2: Morph the record list into a record hash map of record lists instead

    • Pros: A hash map allows for constant random access to a record list of a particular date assuming the key for the hash map is using dates. Thus, the filtering function does not need to loop through as many records and the time taken would be lower especially when the database in the application is large.

    • Cons: Might be too specific to only 1 type of category like categorising by date. If any other types are required, another map may have to be added. This implementation may make the system rigid and hard to modify in the future.

  • Alternative 3: Cache the summary list in financial planner

    • Pros: By caching the summary list in the financial planner and assigning a boolean variable along with information on the filter predicate to it to determine if it is modified, we can reduce the number of times summary list is recreated every time the summary command is called. When the summary command is called, it checks the boolean variable to see if summary list needs to be modified. If it doesn’t need to be regenerated, the system will simply read directly from ModelManager.

    • Cons: This implementation involves tracking of the state of the summary list. If it is not done systematically, it may have some hidden bugs which can be hard to test. Also, if the sequence of commands is as follows, summary, add, summary, the time required is still long.

View category breakdown feature

Current Implementation

This feature allows the user to view a pie chart breakdown o f all expenses and all income within a date range which the user can specify.

The corresponding command required for this feature is stats.For this feature, users have to enter 2 dates, one starting date and one ending date. This feature is facilitated by a few key components of FinancialPlanner, Logic, Model, UI and function executions can be split into 2 phases, the Logic phase and the UI phase. The detailed execution sequence of functions used for Logic phase are as shown below.

StatisticLogicSequenceDiagram
Figure 3. Sequence diagram for high level interactions in logic phase

Consider the situation where the user enters "stats d/1-1-2018 12-12-2018":

  • When user enters the command, the LogicManager recognises the command and calls the FinancialPlannerParser to process the new command as shown above.

  • The FinancialPlannerParser will then search for the stats keyword required and once it is found, the rest of the command minus the keyword is passed in as a parameter to StatisticCommandParser.

  • The StatisticCommandParser will then parse the arguments and create a new StatisticCommand object before returning its reference. The activity diagram below details the mechanism within the StatisticCommandParser#parse method.

StatisticParserActivityDiagram
Figure 4. Activity diagram for details in StatisticCommandParser
  • Once StatisticCommand#execute is called, it will then search through the in-memory data of FinancialPlanner and return a list containing all records within the date range and including both the start dates and end dates. This functionality is facilitated by the ModelManager which is the class that manages all interactions between Logic and Model component, by`ModelManager#updateFilteredRecords`. The command then retrieves the filteredList from ModelManager and passes it into the constructor of CategoryStatisticsList.

  • In this constructor, it will loop through all the records in the list and add them into an internal map. The internal data structure in CategoryStatisticsList is a hash map, to aid in the adding process, however it only outputs lists and not the map. This functionality is facilitated by CategoryStatisticsList#addToCategoryStatistics which checks whether the record is in the map.

  • If the record is not present, it creates a new CategoryStatistic object and adds that to the map. If the record is present, the record is then added to the existing CategoryStatistic object.

  • The flow of control returns to StatisticCommand and StatisticCommand calls the read function of CategoryStatisticsList to obtain a read-only list and passes it into an event constructor before posting the event ShowPieChartStatsEvent.

After the event is posted, the execution proceeds to the UI phase where there is a listener in MainWindow listening to this event. This is facilitated by the event system in FinancialPlanner. The sequence diagram below details the program flow of the functions executed in UI phase for creating the pie chart for total expense.

StatisticUiSequenceDiagram
Figure 5. Sequence diagram for high level interactions in UI phase
  • When the event is caught by the listener in MainWindow, MainWindow looks through all children of the MainWindow#mainUiPanelPlaceholder and executes the hide function in them. This will make all children hidden from view in the UI which ensures that the UI is displayed correctly.

  • As shown above, the function StatsDisplayPanel#handleShowPieChartDataEvent is called which will call the constructor of MixedPieChartData. The detailed execution details within this class is as shown in the activity diagram below.

StatisticUiActivityDiagram
Figure 6. Activity diagram for details in MixedPieChartDataList

The program flow is then as shown above where the CategoryBreakdown is created and instantiated with 2 lists, one being expenseLabelData and other being expenseLegendData. In the current implementation, whenever stats is called, 2 tabs will be created, one for total income and one for total expense. Thus, the same program sequence after construction for CategoryBreakdown is also repeated for total income.

The sequence diagram below details the program flow after the constructor of CategoryBreakdown class is called.

StatisticUiDetailedSequenceDiagram
Figure 7. Sequence diagram for creation of pie charts
Note that the CustomLegend class is located within the CustomPieChart class which inherits from the JavaFX PieChart class. This legend class can only be accessed within CustomPieChart for security purposes.

Design Considerations

Aspect: Data structure to support statistic command
  • Alternative 1 (current choice): The pie chart breakdown is regenerated from the filtered list every time this command is called.

    • Pros: Reduce overhead during normal operations like adding, deleting and editing if we do not have to update the statistics in real time.

    • Cons: If the command is called multiple times, this process could be repeated many times which may make the app sluggish when there are many records.

  • Alternative 2: Use a data structure to store the statistic information when there is mutation of data

    • Pros: Since the statistics are constantly updated, whenever the command is called, system can read directly and not have to recompute.

    • Cons: Adds overhead to usual operations. Benefits may not be visible if the command is not called frequently.