PROJECT: Modulo


Overview

{Overview written by Tuan Ding Wei}

Modulo is a NUS student life application specially designed for busy and motivated NUS students.

As busy students in NUS, we understand that it can be daunting to keep track of various tasks and concurrently do well for exams. Modulo features a one-stop application to keep track of one’s timetable, finances and academic progress. It also includes a quiz feature that facilitates students with actively recalling their study concepts to improve their study outcomes.

The user interacts with Modulo using a CLI, and it features an outstanding user-friendly GUI created with JavaFX. It is written in Java, and has about 35 kLoC.

Summary of contributions

  • Major enhancement: added finance feature

    1. Allow 4 different types of entries (spend, income, borrow, lend)

    2. Added budget component

      • What it does: allows the user to set budgets (with option of making it more specific to a type of spending). Budgets can be set retrospectively, or in the future, in addition to those that are ongoing in present time.

      • Justification: This feature adds an additional dimension to the feature aside from the passive recording of financial activities. User can now set goals (in the form of budgets) and the application will tabulate the total amount spent so far for the user.

      • Highlights: The portion of budget spent is depicted through a progress bar. When the user’s spending is close to exceeding or has exceeded a budget, the feature will notify the user instantaneously. To provide usual feedback to the user, the colour of text, numbers and progress bar will change accordingly, reflecting the status of the budget.

    3. Added stats component

      • What it does: Display pie and bar charts summarising the numbers in the finance log. Pie charts depict the total amount associated with various groups. Entries can be grouped by their entry type (spend, income, borrow, lend), their transaction method, their place of spending or the categories they were tagged with. Bar charts show the total number of entries in the various groups.

      • Justification: With the addition of more entries over time, it can be overwhelming for the user to look through those entries to determine his pattern of spending. A graph that summarises these numbers will make it easier to judge what kind of expenses should be reduced.

      • Highlights: This command has 8 possible combination of inputs possible, which is all supported. The number of log entries and total amounts are sorted in descending order, with the largest value first.

  • Minor enhancement: find command that allows the filtering of entries by their type, in addition to searching by keywords (partial keyword match is also enabled for item descriptions).

  • Code contributed: [Functional code]

  • Other contributions:

    • Project management:

      • Set deadlines for milestones v1.0 - v1.4 on GitHub

    • Documentation:

    • Community:

      • PRs reviewed (with non-trivial review comments): #146, #46

      • Reported bugs and suggestions for other teams in the class (example: PE Dry Run)

Contributions to the User Guide

This is a subset of the Finance section, for the full version, please refer to the User Guide.

Finances

To enter the Finances section, please enter the command: switch finance

All amounts are taken to be in SGD and recorded as if with dollar signs and numerals. For example, 110 cents should be written as 1.10 or 1.1.

If dates are to be specified, only dates of format DD-MM-YYYY will be recognised. If dates are not specified, the default day will be set to the current day when the entry was entered. Dates should not be in the future.

Note that category names should be without whitespaces (e.g. catFood, not cat food).

Add an entry of expenditure: spend

Record down an entry of spending with relevant information associated with it. If place of spending is not specified, it will default to -.

Format: spend <amt>AMOUNT <item>DESCRIPTION <met>TRANSACTION_METHOD [<place>PLACE] [<day>TRANSACTION_DATE] [<cat>CATEGORY]…​
e.g. spend <amt>2.80 <day>15-10-2019 <item>Yong Tau Foo <met>Cash <place>Frontier ==== Edit an entry: edit

Edit an entry previously entered by index of entry in listed listed out by list. Index provided should be valid, within range of the list and positive. There is not need to re-enter all details of the log entry to edit it - just specify the field to be edited. Any irrelevant fields to the log entry (e.g. 'Borrow' entries do not have a <place> field) will be ignored.

Note that the newly-entered information will overwrite the details at the attribute. For example, if there were categories food and hobby linked to the entry at index 5 of the list, command edit 5 <cat>pet will delete the previous two categories and replace them with a single category pet.

Repaid 'Borrow' and 'Lend' entries cannot be edited.

Format: edit INDEX [<amt>AMOUNT] [<day>DAY] [<item>DESCRIPTION] [<met>TRANSACTION_METHOD] [<cat>CATEGORY ]
* Additional field available for 'Spend' entries: [<place>PLACE]
* Additional field available for 'Income' and 'Borrow' entries: [<from>SOURCE/PERSON_BORROWED_FROM]
* Additonal field available for 'Lend' entries: [<to>PERSON_LENT_TO]
e.g. edit 1 <day>12-02-2019 <cat>Gift

Delete entry/entries: delete

Delete an entry by its index in the list.

Format: delete INDEX
e.g. delete 5

Search and filter list of log entries: find

Search through the list of log entries by keyword. This will search through every entry’s item description, place (for 'Spend' entries), transaction method, source of income (for 'Income' entries), person borrowed from (for 'Borrow' entries) and person lent to (for 'Lend' entries). Note that only item description will allow for partial word matching (i.e. cook in cookie is valid), the rest will search for a full word match. This search is case-insensitive.

Filter the list of log entries by their log entry type (i.e. spend, income, borrow, lend).

At least one field has to be specified.

To return to the default full list of log entries, use the list command.

Format: find [<type> spend/income/borrow/lend] [<keyword> KEYWORD [MORE_KEYWORDS]…​] [<cat> CATEGORY_NAME [MORE_CATEGORY_NAMES]…​]
E.g. find <type>spend

Show statistical summaries of finances: stats

Shows an overview of the state of expenses and incomes. Log entries can be grouped by (<gb>) a specified attribute with either the frequency or total amount of each group summarised (<sum>) in a graphical display. These attributes include log entries of the same month, type, transaction method, category or place.

Both <gb> and <sum> have to be present, with combination of ATTRIBUTE and STAT specified.

Format: stats <gb>ATTRIBUTE <sum>STAT
* Possible ATTRIBUTE values for <gb> are: month, entrytype, met, cat, place (only shows Spend entries)
* Possible STAT values for <sum> are: freq and amt
E.g. stats <gb> met <sum> freq

Add a budget: budget

Specify a budget. Budgets will only take into account the amount spent (i.e. Spend entries) and are generally characterised by a starting date, an ending date and a limit (maximum threshold). When total amount associated with spending crosses this limit, the budget is considered to be exceeded.

Budgets for a specific place, category or transaction method can also be set (optional). Only at most one field out of these 3 optional fields - <met>, <cat>, <place> - can be included to make the budget more specific. If a spend entry matches the specified field and also falls within the budget duration, it will be included in the budget tabulation. If none of these fields are indicated, the budget will sum up the amounts of all Spend entries which fall between the budget duration.

In essence, there are 3 optional fields (only at most one can be used at any time):

  1. [<met>TRANSACTION_METHOD]

  2. [<cat>CATEGORY_NAME]

  3. [<place>PLACE_OF_SPENDING]

Note that these fields are case-sensitive (e.g. Spend entries with category food will not match if budget field is specified as <cat> FOOD).

There are 3 ways to specify the duration (start, end) of a budget:

  1. <start>START_DATE <end>END_DATE

  2. <start>START_DATE <dur>DURATION_IN_DAYS

  3. <month>MM-YYYY

Example Format 1: budget <amt>AMOUNT <start>START_DATE <end>END_DATE [<met>TRANSACTION_METHOD]
Example Format 2: budget <amt>AMOUNT <start>START_DATE <dur>DURATION_IN_DAYS [<cat>CATEGORY_NAME]
Example Format 3: budget <amt>AMOUNT <month>MM-YYYY [<place>PLACE_OF_SPENDING]
e.g. budget <amt> 300 <month>11-2019 <met>cash

Contributions to the Developer Guide

Class diagrams

FinanceModelClassDiagram
Figure 1. Structure of the Model Component for the feature Finance
FinanceStorageClassDiagram
Figure 2. Structure of the Storage Component for the feature Finance

Budgets in finances

Implementation

A budget is an estimate or threshold of spending set for a specified period of time. In Modulo, a budget can be set to only include spendings of a particular characteristic (i.e. transaction method, place of spending or category). For example, budgets of spendings at a particular place can be set. Modulo will only take into account spendings recorded to be associated with this place and falling within the specified period of time.

To compute the current total amount spent so far and see whether this total amount still falls within the budget, amounts associated with entries are summed together.

These entries have to fulfill the following requirements set by the budget to be considered in the tabulation:

  • Has to be a log entry of type Spend

  • Transaction date has to fall within budget period (i.e. between the start and end dates)

  • (If addition field of transaction method, place of spending or categorys specified) Has to either have the same transaction method, place of spending or be tagged with the same category

There are some classes in the Model component necessary for the computation of budgets:

  • Budget - Contains the basic information about a budget (amount, start and end dates, additional characteristic Spend entry has to fall under (if any))

  • BudgetData - The Budget object associated to it, the limit set by the budget and the current total amount tabulated from the Spend entries matching the budget requirements

In ModelFinanceManager which implements the Model interface, Model#getFilteredBudgetDataList() will return the list of BudgetData objects mapped from the list of Budget objects stored in the Modulo. These BudgetData are instantiated using information from the list of entries stored in Modulo. They filter out entries which do not match the requirements of the budget they are associated with, and then add up all the amounts of the entries to obtain the current total amount spent.

If the total amount of spending is close to exceeding the budget (more than or equals to 80% of budget spent), an orange label at the menu bar will be shown to notify the user that a budget is near to reaching its limit.

And if the total amount of spending has exceeding the limit set by the budget, the menu bar will have a red label indicating that the budget has been exceeded. The amount of money spend has gone over the estimate set and is now in deficit.

Given below is an example usage scenario for what happens when a budget is set, and how Modulo behaves at each step.

This assumes that the user has not set any budget in the application before but has some entries recorded in the finance log. These entries are:

  1. (Income) Amount: 800, Item: Internship Pay, From: ABCompany, Transaction Method: Bank Transfer, Day: 7-11-2019

  2. (Spend) Amount: 50, Item: EzLink TopUp, Transaction Method: NETS, Place: Caldecott MRT, Day: 4-11-2019

  3. (Spend) Amount: 107.70, Item: Bicycle, Transaction Method: Cash, Day: 5-11-2019, Place: Toa Payoh Lor 4, Categories: bike

  4. (Spend) Amount: 1.10, Item: KopiO, Transaction Method: Cash, Day: 2-11-2019, Categories: drink, kopitiam

Step 1. The user launches the application and switch to the finance mode by executing switch finance.

Step 2. The user wants to set a budget of 300 dollars for November for spendings done using cash. He executes the budget <amt> 300 <month> 11-2019 <met> Cash command to set this budget. The budget command calls Model#addBudget(b), where upon the finance log will add Budget object b to budgetList, the list of budgets.

The interactions inside the Logic Component for budget <amt> 300 <month> 11-2019 <met> cash Command are shown in the sequence diagram below.

{Please refer to sequence diagram here.}

The interactions in the Model Component for the same command are shown in the sequence diagram below.

BudgetModelSequenceDiagram

The budget is added to the list of budgets (this being the first budget in the list). The list of budgets will update with the status of each budget.

Modulo will change the view after a budget command to show the list of budgets stored in Modulo.

If the exact same budget already exists in the budget list, it will not call Model#addBudget(b), and this budget will not be added to the list of budgets. Modulo will show an error message that this budget already exists.

Step 3. The user now decides to add another entry of spending. This time the user has recently spent 400 dollars on a Nintendo Switch and paid for it using cash. He enters this record with the spend <amt> 400 <item> Nintendo Switch <met> Cash <day> 7-11-2019 command. This entry is added to the list of entries.

Since this entry is paid using cash, transaction date was in November 2019 it is included in the tabulation of the budget. It causes the total amount spent to exceed the budget of 300 dollars, and a red label in the menu bar appears to notify the user that a budget has exceeded.

Step 4. The user views the list of budgets (in this example, there is only one budget) using the listb command.

The window changes to a view of the budget, with information about its status shown.

These information include:

  • Type of budget (for all Spend entries, for entries done using a specific transaction method, conducted at a specific place or tagged with a specific category)

  • Start and end date of budget

  • Progress bar of how much money has been spent (for entries fulfilling budget requirements)

  • Whether the budget is active (current date falls between start and end dates) or not (end date of budget has passed or start date has yet to come)

  • Total amount spend so far

  • Limit set by budget

  • Amount of money left to limit or how much has the budget been exceeded by

The flow on how what happens when the user enters a new entry is shown in the activity diagram below.

{Please refer to activity diagram here.}

Design Considerations

Aspect: Data structure to support tabulation of spendings
  • Alternative 1 (current choice): Save just the basic details related to the budget - amount (limit to amount to be spent), start and end date, optional requirements Spend entries should fufill (transaction method, place of spending or category).

    • Pros: Less information to store, flexible to changes such as updates to entries during edits (e.g. changes in amounts etc). Budgets can be retrospective (even if dates have past, budgets can still be set to see spending was kept within limits).

    • Cons: Additional step of filtering to obtain entries matching budget requirements before tabulating the total amount - may have performance issues when number of entries is large in terms of time complexity.

  • Alternative 2: Budget stores the same information as above, and also the list of entries that fulfill the budget requirements.

    • Pros: Removes the need for filtering entries before tabulation, simply calculate total amount from list of entries stored under the budget.

    • Cons: Will use more memory (now storing the list of entries). Difficult when an entry is delete or modified, have to delete and modify entry accordingly in the list of entries stored under the budget.

User Stories

For more user stories related to financial management, please refer to the Developer Guide.

Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *

Priority As a …​ I want to …​ So that I can…​

* * *

student with basic finance literacy

keep a record of my finances

understand my spending habits

* * *

cash-strapped student

set a budget for the month

limit my spending

Use Cases

For more use cases, please refer to the Developer Guide.

Use case: Record down an entry of borrowing to finance log

Preconditions: User has switched to the finance feature

MSS

  1. User enters details of money borrowed.

  2. User requests to add a Borrow entry.

  3. Modulo adds Borrow entry and displays it in list of log entries.

    Use case ends.

Extensions

  • 2a. Modulo detects an error in command/details entered.

    • 2a1. Modulo shows an error message.

    • 2a2. Modulo requests for command to be entered in the correct format.

    • 2a3. User enters new line of command with new details.

  • Steps 2a1-2a3 are repeated until the command and details entered are in the correct format.

  • Use case resumes from step 3.

Use case: Record down an entry of borrowing to finance log

Preconditions: User has switched to the finance feature, a budget exists in finance log

MSS

  1. User enters details of money spend.

  2. User requests to add a Spend entry.

  3. Modulo adds Spend entry and displays it in list of log entries.

    Use case ends.

Extensions

  • 2a. Modulo detects an error in command/details entered.

    • 2a1. Modulo shows an error message.

    • 2a2. Modulo requests for command to be entered in the correct format.

    • 2a3. User enters new line of command with new details.

  • Steps 2a1-2a3 are repeated until the command and details entered are in the correct format.

  • Use case resumes from step 3.

  • 3a. Spend entry is included under budget and budget is exceeded (i.e. limit set by budget is crossed).

    • 3a1. Modulo notifies that budget has been exceeded.

    • 3a2. Exceeded budget is marked as so.

  • Use case ends.

  • 3b. Spend entry is included under budget and budget is close to being exceeded.

    • 3b1. Modulo notifies that budget is close to exceeding.

  • Use case ends.