Overview

$aveNUS is a command line interface (CLI) financial planning application that my team and I designed for CS2103T (Software Engineering) module in School of Computing, National University of Singapore (NUS).

In this project, we morphed the sample address book application into $aveNUS, an application that allows NUS students to track their financial spending with regards to food purchases. Additionally, the application provides them with the best food recommendations within their current budget as well as a savings feature to track their savings.

My main role was to implement the Wallet-Tracking Feature as well as the Purchase-Tracking Feature. The following sections illustrate these enhancements in more detail, as well as the relevant documentation I have added to the user and developer guides in relation to these enhancements.

The table below provides a quick summary of the symbols and formatting used in this portfolio.

code

Command that can be typed into the command box

Success execution of command

Tips that might be useful

Additional information that is good to know

Important pointers to take note

Summary of contributions

This section provides a summary of the contributions that I have made to the team project.

Major enhancement: Budget-Tracking Feature

I have implemented a Budget-Tracking feature to $aveNUS.

What it does

The Budget-Tracking feature allows users to manage their budget for food expenditure.

Firstly, users are able to set their budget using the budget command by specifying their budget amount and budget duration. Following which, users can use the buy command to purchase food items which would deduct the corresponding price amount from the wallet. Lastly, users are able to use the topup command to update the budget amount, if for example, they got an allowance from their parents and wishes to add that to their food budget

The user is updated with regards to the amount as well as the duration left for their current budget through the graphical user interface(GUI). Budget-related information is also used in the application’s recommendation system to suggest appropriate food items within a user’s budget.

Justification

Our application’s main target audience are NUS students, who often may have a limited budget when it comes to food expenditure.

Highlights

While implementing this feature, I had to implement new models such as Wallet, RemainingBudget, DaysToExpire, which serves to store the user’s budget-related information in a structured manner. An additional Money class was also added to allow for the changes to budget amount to be made without a loss of precision. Commands such as budget, topup have also been implemented to update the aforementioned models.

Storage functionality for the user’s budget was also implemented. This means that the user’s budget-related information are conveniently saved into their hard disk and persist even after the application is closed and restarted.

Furthermore, using JavaFX’s Properties and Binding application programming interface (API), a user’s budget-related information is accurately and updated on a timely basis on the GUI.

Major enhancement: Purchase-Tracking Feature

I have added a Purchase-Tracking feature to $aveNUS.

What it does

The Purchase-Tracking feature stores a user’s purchase history, thereby allowing users to keep track of the food purchases they have made.

Whenever a user uses the buy command to purchase a food item, an entry with the purchased food item and time of purchase is added to the purchase history. The GUI is then re-rendered to show the most updated purchase history.

Information of a user’s purchase history is also used in the application’s recommendation system to avoid suggesting food items bought recently to encourage user’s to try different types of food.

Justification

Users may which to check their purchase history in order to remind themselves of their past food expenditure. Using this information, users will be able to plan their future food expenditure better.

Highlights

While implementing this feature, I had to implement new models such as Purchase, TimeOfPurchase which serves to store a user’s purchase in a structured manner. The buy command have also been implemented to allow users to add purchases.

Storage functionality for the user’s purchase history was also implemented. This means that the user’s purchase history is conveniently saved into their hard disk and persist even after the application is closed and restarted.

Furthermore, additional user interface(UI) classes such as ReadOnlyPurchaseHistory and PurchaseHistoryList ensure that a user’s purchase history is accurately and updated on a timely basis on the GUI.

Minor Enhancement: Command History Tracking and Retrieval

What it does

Stores user’s previously entered commands in a CommandHistory model, thereby allowing users to use arrow keys to scroll through their command history.

With focus on the Command Line, pressing the Up Arrow will recall the previous command. Correspondingly, the Down Arrow would recall the next command you typed.

Justification

As our application is a predominantly Command-Line application, I realised that this would be an extremely useful feature both to users and developers alike.

As a user, having this feature would allow them to be able to redo a command multiple times without re-entering the entire command again. For example, if a user wishes buy more than one of the first food item in the displayed list, they would be able to enter buy 1 once and repeat the command again using the Up Arrow.

As a developer, this feature allows for more convenient debugging as developers would not have to re-enter entire commands in order to test changes.

Highlights

CommandHistory is implemented as a Singleton class despite decreasing its testability. This is to prevent additional instantiation since every application should only have one command history.

Also, the list of commands in CommandHistory is implemented similar to a queue. It has a maximum length of 10 and when commands that are added when the list is full, the new command would replace the oldest command in the command history list.

Other contributions

  • Project Management:

    • Added user stories as issues on GitHub

    • Reviewed pull requests by team members [PR #105, #82]

    • Opened issues when bugs were found [Issue #101, #166]

    • Fixed bugs after they were found [PR #167]

  • Documentation:

    • Updated About Us page

      • Improved the styling for developer’s portfolio avatar [PR #73]

    • Updated the User Guide and Developer Guide

      • Replace references to the main repository with references to our team’s fork [PR #170]

    • Community:

      • Reviewed the Developer Guide of other teams [Examples: #1, #2]

Contributions to the User Guide

This section shows the contributions that I have made to the Budget-Tracking and Purchase-Tracking feature of the User Guide.

Budgeting

wallet
Figure 1. Example User’s Wallet
Maximum budget amount is $1,000,000.
Maximum budget duration is 365 days (1 year).

Sets budget for a number of days: budget

Allows the user to set a budget for food expenses.

Format: budget AMOUNT [DURATION]
Example: budget 100.00 10

Note:
AMOUNT must be a non-negative integer or non-negative double with 2 decimal places.
DURATION is in days, and must be a non-negative integer.

Top up money into wallet: topup

Allows users to top up the money into their wallet.

Format: topup AMOUNT
Example: topup 10

Note:
AMOUNT must be a non-negative integer or a non-negative double with 2 decimal places.

If the top up was successful, you should be able to see the update to your wallet immediately.

Purchasing

PurchaseHistory
Figure 2. Example User’s PurchaseHistory

Buy a food item: buy

Allows users to log a food expense into the application.

Format: buy FOOD_INDEX
Example: buy 1

Note: FOOD_INDEX is with reference to the currently displayed food list

Make sure you have enough money in your wallet for the purchase.
If the purchase was successful, you should be able to see the update to your purchase history immediately.

Contributions to the Developer Guide

I have made documentation contributions to the Developer Guide regarding the 2 main features I implemented, i.e. Budget-Tracking and Purchase-Tracking features.
This section will only show the contribution that I have made regarding the Budget-Tracking feature and a part of the the Purchase-Tracking feature of the Developer Guide to adhere to the PPP word limit.
The rest of the documentation regarding the Purchase-Tracking feature can be found in our Developer Guide.

Budget Tracking feature

The Budget Tracking feature allows users to manage their budget for food expenditure. It keeps the user updated with regards to the amount as well as the duration left for their current budget. Budget information is also used in the application’s recommendation system to suggest appropriate food items within a user’s budget.

Classes for Budget Tracking feature in Model

The Budget Tracking feature was implemented with the following classes.

WalletClassDiagram
Figure 3. Wallet-related class diagram in Model component.
Wallet

Wallet is a class containing the user’s current budget, i.e., storing the user’s budget amount and budget duration.

RemainingBudget

RemainingBudget stores a user’s remaining budget amount. It contains an ObservableValue which allows the UI to track of the amount of money left in the current budget after changes are made to it. The maximum budget amount has been set to 1 million dollars.

Also, in order to avoid possible loss of precision errors, a Money class is used. This design decision is discussed below.
DaysToExpire

DaysToExpire stores a user’s remaining budget duration. It contains an ObservableValue which allows the UI to track of the number of days before the current budget expires after changes are made to it. The maximum budget duration has been set to 1 year (365 days).

When a DaysToExpire object is instantiated, it stores the system time as a field. The budget duration is correspondingly updated based on the difference between this saved time and the actual system time.

Due to development constraints, we have decided to only update the budget duration every time the application is started up instead of constantly monitoring the actual time to update this property.
Design considerations

Below are some design considerations when implementing Budget-related models.

Table 1. Design considerations of the for RemainingBudget model
Alternative 1 (Chosen Implementation) Alternative 2

Creating a Money class which makes use of Java’s BigDecimal class to store budget amount

  • Pros:

    • Avoid precision loss when adding or subtracting from the budget amount

    • Money class serves as a reusable class to store money amounts and can be used in other parts of the application such as in the Savings feature

  • Cons:

    • Increased coupling due to the additional classes used.

Making use of Java’s primitive double to store budget amount

  • Pros:

    • Easier implementation

    • Decreases the number of dependencies of RemainingBudget

    • Can make use of inbuild DoubleProperty to display to GUI

  • Cons:

    • Loss of precision when adding or subtracting from the budget amount

We chose alternative 1 mainly due to the fact that the loss of precision is extremely apparent to the user. From our testing, after the user buys 3 or 4 items, the precision error adds up resulting in a difference of 1 cent between the expected and actual budget amount. This may confuse the user and is a bug that we wish to avoid.

Setting a Budget

A budget can be set using the budget command which takes a budget amount, and an optional budget duration.

For example, budget 100 10 will set the user’s budget, with $100.00 for 10 days.

The sequence diagram for interactions between the Logic, Model and Storage components when a user executes the buy 1 command is shown below.

BudgetSequenceDiagram
Figure 4. Sequence diagram for budget 100 10 command

The following activity diagram below summarizes how budget commands works

BudgetActivityDiagram
Figure 5. Activity diagram for a budget command

Purchase Tracking feature

The Purchase Tracking feature allows users to monitor their food expenditure by keeping track of their purchase history. Whenever a user’s executes the buy command, the corresponding food will be added as a purchase to the purchase history. A user’s purchase history is displayed in the UI, similar to the food menu, and is updated every time a change is made to it.

Classes for Purchase Tracking feature in Model

PurchaseHistoryClassDiagram
Figure 6. Purchase-related class diagram in Model component.

The Purchase Tracking feature was implemented with the following classes.

ReadOnlyPurchaseHistory

ReadOnlyPurchaseHistory is an interface implemented by PurchaseHistory to allow the other components to retrieve the purchase history data of the user while maintaining data integrity.

PurchaseHistory

PurchaseHistory contains a PurchaseHistoryList and serves as an encapsulation for Purchase-related methods and fields.

PurchaseHistoryList

PurchaseHistoryList contains an ObservableList of Purchase made by the user.

Purchase

Purchase contains a Food object representing the purchased food item, and a TimeOfPurchase representing the time of purchase.

TimeOfPurchase

TimeOfPurchase stores the time the Purchase was made by the user.

Design considerations

Below are some design considerations when implementing Purchase-related models.

Table 2. Design considerations of the for Purchase model
Alternative 1 (Chosen Implementation) Alternative 2

Storing the purchased food item as a Food object in the Purchase object

  • Pros:

    • Easier to implement

    • No need to do additional input validation to ensure validity of Purchase and can instead rely on the input validation provided by Food.

    • Allow for future functionality extension by storing all the information of the purchased Food to be accessed when needed.

  • Cons:

    • Increased coupling due to the dependency created between Purchase model and Food model.

Creating an additional immutable PurchasedFood class to store information regarding the purchased Food object.

  • Pros:

    • Can choose to only include relevant information such as the food name and price while cutting out other irrelevant parts.

    • Remove the dependency between Purchase model and Food model

  • Cons:

    • Creates another dependency between Purchase and PurchasedFood

    • Harder to implement, additional classes would have to be written to allow for serialisation as well.

We chose alternative 1 due to the fact that Food is implemented as a immutable class. Therefore, we are able to get the required from the Food object the user selected to construct the new purchased Food object. And at the same time, ensure the data integrity of that information. Also, by encapsulating the Food object within the Purchase object and making it a private field, we are able to ensure that the purchased Food is not modified in an unintended manner.