1. Introduction
2. Setting up
2.1 Prerequisites
3. Design
3.1 Architecture
3.2 Parser Class
3.3 Ui Class
3.4 CommandCreator
3.5 CommandClass
3.6 Storage Class
3.7 Commons
3.7.1 Transaction
3.7.2 Expense
3.7.3 ExpenseList
3.7.4 Saving
3.7.5 SavingList
3.7.6 RecurringExpenseList
3.7.7 RecurringExpensesList
3.7.8 DefaultCurrency
3.7.9 CurrencyConverter
4. Implementation
4.1 Menu Feature
4.2 Add Expenses Feature
4.3 Add Savings Feature
4.4 Add Split Expenses Feature
4.5 Edit Savings Feature
4.6 Edit Expenses Feature
4.7 Reduce Savings Feature
4.8 Delete Expenses Feature
4.9 List Savings Feature
4.10 List Expenses Feature
4.11 Check Splitted Expenses Feature
4.12 Settle Splitted Expenses Feature
4.13 Find Expenses Feature
4.14 Recurring Expenses Feature
4.15 Currency Converter Feature
4.16 Setting Budget Feature
4.17 Get Graphical Insights for expenses
4.18 Get Graphical Insights for savings
5. Documentation
6. Testing
Appendix A: Product Scope
Appendix B: User Stories
Appendix C: Use Cases
Appendix D: Non-Functional Requirements
Appendix E: Glossary
Appendix F: Instructions for Manual Testing
Diagrams have been created on Draw.io.
Welcome to the Developer Guide for BudgetBuddy! This guide has been created to help you current and future developers of BudgetBuddy understand how BudgetBuddy works and aid you in easily adding new features and fixing bugs. In this guide, it will go over the main parts of the app, how they work together, and why we made them that way.
This section describes how to set up the coding environment, along with the tools needed to work on BudgetBuddy
The following diagram provides a rough overview of how BudgetBuddy is built
BudgetBuddy
is the main class of the application and directly interacts with the user. BudgetBuddy
passes along the input into the Parser
. The Parser
creates a CommandCreator
object depending on the user’s input
. The CommandCreator
object then creates the Command
object.
This Command
object will be executed in BudgetBuddy
. The Command
object
utilizes methods and the classes present in Commons
, which will be explained in more
detail in the following sections.
The main functionality of the Parser Class is to determine the type of CommandCreator
object to create. Using
Boolean Functions, the Parser Class determines this by what the user input starts with.
After determining the type of CommandCreator
object, the Parser initializes the CommandCreator
object
with all its required parameters.
Here are some examples :
Boolean Method | Checks if input starts with | Feature Requires | Creates |
---|---|---|---|
isAddExpenseCommand() | add expense | input, ExpenseList | AddExpenseCommandCreator(input, expenses) |
isEditSavingCommand() | edit expense | input, SavingList | EditSavingsCommandCreator(input, savings) |
The Ui Class is used to print certain elements to the CLI. In particular, it consists of the Welcome Message, Goodbye Message, Divider Lines and all the corresponding commands’ command format.
The CommandCreator class has multiple subclasses, which corresponds to a specific function of the application.
Within the CommandCreator classes, it handles making sense of the user input, obtaining the relevant parameters, and finally
creating the Command
class to be executed.
The superclass CommandCreator
is an abstract class which is never instantiated. Where its createCommand()
method is overridden by its subclasses.
The association between the Command
and CommandCreator
can be seen in their names. E.g. MenuCommandCreator
, would
create a MenuCommand
class when its createCommand() method is called. Similarly, FindExpensesCommandCreator
would
create a FindCommand
class when its createCommand() method is called.
For clarity, unlike the BudgetBuddy
and Parser
class, where only one instance of them is used for the entire
application, a new CommandCreator
subclass is instantiated every time a user provides an input. Hence,
a created CommandCreator
will always be specific to, and only handle one
user input. This will be further illustrated in the
UML Sequence Diagram provided in section 3.4 Command Class
The Command class, similar to the CommandCreator class, contains multiple subclasses, all corresponding to a specific
function/feature of the application. Stated in section3.4 CommandCreator Class
, each subclass of the Command
Object is created by its associated CommandCreator
subclass.
The superclass Command
is an abstract class which is never instantiated. Where its execute()
method is overridden
by its subclasses. What each Command subclass does when its execute()
method is called would be discussed in
more detail in the Implementation section.
For clarity, similar to the CommandCreator
class, a new Command
subclass is instantiated every time a
user provides an input. As such, a created Command
will always be specific to, and only handle one
user input.
The following UML Sequence Diagram depicts the process of what happens when a user input is passed through the application, up till the point when the command gets executed :
Note : BudgetBuddy instantiates other classes such as the Storage and Ui class, however, these steps have been left out as they have no relevance to the process of creating and executing a Command.
The Storage Class handles the loading and saving of the features in BudgetBuddy. Different features are saved in different files corresponding to their data type.
The Storing methods are always called after every user input
, ensuring that the saved files
are always up-to-date.
Similarly, the Loading methods present in the Storage Class is always called before the application is fully initialized.
The classes present in this group of Commons
refers to a collection of classes used by multiple other components
. They represent data of the user’s financial transactions, including expenses and savings, along with methods
for organizing and managing this data.
This is an abstract class, which is the superclass for both the Expense and Saving Classes. It contains common variables such as Currency, Category and Amount.
This class holds details regarding an expense a user has. Within this class, it has 4 class-level variables :
String category
, LocalDate dateAdded
, String description
and Double amount
.
String category
: This variable holds the category of the expense. It represents the type or classification
of the expense as per the pre-defined categories (“Housing”, “Groceries”, “Utility”, “Transport”, “Entertainment”).
LocalDate dateAdded
: This variable holds the date when the expense was added or recorded.
It is of type LocalDate, representing a date without a time zone.
Storing the date of the expense allows users to track when each expense occurred,
facilitating budget management and analysis over time.
String description
: This variable holds a description of the expense.
It provides additional details or information about the expense,
such as what the expense was for or any relevant notes.
Descriptions help users understand the context or purpose of each expense entry.
Double amount
: This variable holds the monetary amount of the expense.
It represents the cost or value of the expense, typically in the currency used by the user.
Storing the amount allows users to track how much money was spent on each expense,
aiding in budgeting and financial planning.
This class represents a list of expenses. Within this class, it has 2 class-level variables :
ArrayList<Expense> expenses
and ArrayList<String> categories
, The variables and there relevance are as follows :
ArrayList<Expense> expenses
: This variable holds a list of Expense
objects.
Each Expense
object represents an expense incurred by the user. The list stores all the expenses entered by the user.
Managing expenses in a list allows for easy retrieval, modification, and deletion of individual expenses.
Additionally, it enables functionalities such as filtering, listing, and calculating total expenses.
ArrayList<String> categories
: This variable holds a list of predefined expense categories.
Each category represents a classification or grouping for expenses, such as “Housing,” “Groceries,” “Utility,” etc.
The list provides predefined options for users to select when adding or editing expenses.
It helps organize expenses into meaningful groups,
allowing users to track and analyze their spending habits across different expense categories.
This class also contains the methods to handle any user interactions with the list of expenses. These methods would
be further explained in their corresponding Implementation
sections.
This class holds details regarding a saving a user has. Within this class, it has 3 class-level variables :
String category
, LocalDate dateAdded
, Double amount
. The variables and their relevance
are as follows :
String Category
: This variable holds the category of the saving.
Similar to expenses, savings can also be categorized based on their purpose or intended use.
Pre-defined categories include (“Salary”, “Investments”, “Gifts”, or “Others”).
Categorizing savings helps users allocate funds for different financial goals and track progress towards those goals.
LocalDate dateAdded
: This variable holds the date when the saving was added or recorded.
As with expenses, tracking the date of each saving allows users to monitor their saving habits over time.
It provides a historical record of when savings were initiated,
helping users understand their saving patterns and behaviors.
Double amount
: This variable holds the monetary amount of the saving.
It represents the value or sum of money saved by the user.
The amount indicates how much money has been set aside or accumulated towards achieving a particular financial goal.
Users can track their progress towards savings targets and
monitor their overall financial health based on the amount saved.
This class represents a list of savings. Within this class, it has 2 class-level variables :
ArrayList<Saving> savings
and ArrayList<String> categories
, The variables and there relevance are as follows :
ArrayList<Saving> savings
: This variable holds a list of Saving
objects,
where each object represents a saving made by the user. The list stores all the savings entered by the user.
Managing savings in a list allows for easy retrieval, modification, and reduction of individual savings.
Additionally, it enables functionalities such as listing savings, calculating remaining savings after
deducting expenses, and adding new savings.
ArrayList<String> categories
: This variable holds a list of predefined saving categories.
Each category represents a classification or grouping for savings, such as “Salary,” “Investments,” “Gifts,” etc.
The list provides predefined options for users to select when adding or editing savings.
It helps organize savings into meaningful groups, allowing users to track and
manage their savings across different categories.
This class also contains the methods to handle any user interactions with the list of savings. These methods would
be further explained in their corresponding Implementation
sections.
This class represents a list of recurring expenses for the Recurring Expense feature. Within this class, it has
1 class-level variable : String name
. Which is used to store the name of the list. Given that its overall
functionality is similar to ExpenseList class, it inherits the ExpenseList class.
This class represents the list of all lists of recurring expenses for the Recurring Expense feature. Within this class,
it has only 1 class-level variable : ArrayList<ExpenseList> recurringExpenses
. Which is used to store a list of
ExpenseList objects. This class contains all methods required for the overall Recurring Expense feature to work.
The implementation of these methods would be discussed in further detail in the Implementation section.
For clarity, the following Class Diagram depicts the associations between RecurringExpenseLists, RecurringExpenseList and ExpenseList.
The DefaultCurrency
class manages the application’s default currency setting. It contains a static variable:
Currency defaultCurrency
: Holds the current default currency setting, initialized to the Singapore Dollar (SGD) using the Currency.getInstance("SGD")
method.This class provides two static methods that are further explained in detail in the Implementation section.
This class ensures a consistent default currency is used throughout the application, essential for functions like displaying amounts and performing currency conversions.
The CurrencyConverter
class provides functionality for converting amounts between different currencies. It includes two class-level variables:
Map<Currency, Double> exchangeRates
: This variable represents a map where the keys are instances of
the Currency
class, and the values are conversion rates as Double
values.
The map stores exchange rates for various currencies relative to a base currency (in this case, Singapore Dollar, SGD).
The exchange rates are initialized with default values for common currencies such as
USD, EUR, JPY, KRW, MYR, CNY, and HKD.
The class includes several methods to handle currency conversion tasks, with its relevance explained in the Implementation section.
These methods facilitate currency conversion tasks by handling the conversion logic, validating input parameters, and logging relevant messages. They provide essential functionality for managing expenses and savings in different currencies within the budget management application.
The menu feature is designed to allow users to view the relevant command formats by inputting the relevant menu
indexes. This feature is orchestrated by the MenuCommand
class, which is initialized by the MenuCommandCreator
class. Which is in turn, created by the Parser
class. Within the MenuCommand
object, the
MenuCommandCreator
would initialize one class-level variable index
of type String
. The relevance of
this class-level variable in MenuCommand
is as follows
Variable Name | Variable Type | Relevance |
---|---|---|
index | int | Refers to the corresponding item in the displayed menu |
For Clarity, the menu items and their corresponding indexes are as follows :
index | Menu Item |
---|---|
Empty/0 | Displays all Menu Items |
1 | Manage Expenses |
2 | Manage Savings |
3 | View Expenses |
4 | View Savings |
5 | Find Expenses |
6 | Split Expenses |
7 | Manage Recurring Bills |
8 | Change Currency |
9 | Manage Budget |
10 | Get Graphical Insights |
Upon the call of the execute()
method in BudgetBuddy using command.execute()
, the MenuCommand
object
utilizes methods from the UI
class to display the relevant menu items. The utilized methods are as follows :
methodName | Return Type | Relevance |
---|---|---|
showMenuTitles() | void | Prints all Menu Items |
showMenuItem(INDEX) | void | Prints commands associated at INDEX |
Important Note : As the process of how the CommandCreator is created upon the receipt of a user input has already been
discussed in 3.4 CommandClass
, the following Sequence Diagrams would omit the initial methods prior to the
MenuCommandCreator being created.
The following UML Sequence Diagram shows how the MenuCommandCreator for Menu Commands work and what
will be returned to the Parser, which will ultimately be returned to BudgetBuddy. Note that this diagram assumes that Parser
has already detected that the user input is a menu command and has initialized a MenuCommandCreator object:
The following UML Sequence Diagram shows the processes of the MenuCommand upon the call of its execute() command:
Given below is an example usage scenario and how the full Menu feature works :
menu 1
. This input passed from BudgetBuddy
into Parser#parseCommands()
.Parser
, it determines that the input is a menu command from isMenuCommand()
, and creates a new
MenuCommandCreator
object.Parser
then calls MenuCommandCreator#createCommand()
index
is done in MenuCommandCreator#handleMenuCommand()
MenuCommandCreator
creates a constructor for MenuCommand
with the parameter 1
, which in turn
also constructs a new Ui
objectMenuCommandCreator
returns this created MenuCommand
to Parser
, which is then returned to BudgetBuddy
BudgetBuddy
then calls MenuCommand#execute()
execute()
then calls Ui#showMenuItem(1)
showMenuItem()
in Ui
then prints all commands for case 1
which is for Manage Expenses
The Add Expense Feature allows users to add expenses to different categories. AddExpenseCommand
class enables this feature,
after initialized by the Parser
class. Within the AddExpense
object, the Parser
would have initialized it with
4 variables, an ExpenseList
object, along with a category
, amount
, description
.
The relevance of these Class Attributes in AddExpenseCommand
is as follows :
Class Attribute | Variable Type | Relevance |
---|---|---|
expenses | ExpenseList | ExpenseList Object containing the list of expenses |
category | String | The category that the expense belongs to |
amount | String | The amount spent |
description | String | The description of the expense |
Upon the call of the execute()
method in BudgetBuddy
using command.execute()
,
the AddExpenseCommand
Object utilizes the following method from the ExpenseList
class to add it to the existing
list of expenses
matching against the corresponding category
.
Method | Return Type | Relevance |
---|---|---|
addExpense() | void | Add expense to the existing list of expenses |
The following UML Sequence diagram shows how the Parser works to obtain the relevant inputs for the Add Expense Feature :
The following is a step-by-step explanation for the Parser for the Find Feature :
BudgetBuddy
calls Parser#parseCommand(input)
with input
being the entire user input.
E.g add expense c/Transport a/20 d/EZ-Link Top Up
Parser
, it will have determined that the input
is a Find Command from the isAddExpenseCommand(input)
function.Parser
then self calls the method handleAddExpenseCommand(input)
with the input
still being the entire
user input.AddExpenseCommand(input)
, the first check would be the check for the existence of any combination of
c/ , a/ and d/
. If none of these combinations were found, it immediately returns null
.If the checks in 4.
is passed, Three variables would be initialized.
Variable Name | Variable Type |
---|---|
category | String |
amount | String |
description | String |
Parser#extractDetailsForAdd(input, "parameter")
Parser#handleAddExpenseCommand()
returns a AddExpensesCommand
to Parser#parseCommand()
, which is
then returned to BudgetBuddy
The Add Savings Feature allows users to add savings to different categories. AddSavingCommandCreator
class intialises the AddSavingCommand
, after initialised by the Parser
class. Within the AddSavings
object, the Parser
would have initialized it with
4 variables, a SavingList
object, along with a category
, amount
.
The relevance of these Class Attributes in AddExpenseCommand
is as follows :
Class Attribute | Variable Type | Relevance |
---|---|---|
savings | SavingList | SavingList Object containing the list of savings |
category | String | The category that the expense belongs to |
amount | String | The amount spent |
Upon the call of the execute()
method in BudgetBuddy
using command.execute()
,
the AddSavingCommand
Object utilizes the following method from the SavingList
class to add it to the existing
list of savings
matching against the corresponding category
.
Method | Return Type | Relevance |
---|---|---|
addSaving() | void | Add savings to the existing list of savings |
The following UML Sequence diagram shows how the Parser works to obtain the relevant inputs for the Add Expense Feature :
The following is a step-by-step explanation for the Parser for the Find Feature :
BudgetBuddy
calls Parser#parseCommand(input)
with input
being the entire user input.
E.g add savings c/Allowance a/20
Parser
, it will have determined that the input
is a Find Command from the isAddSavingsCommand(input)
function.Parser
then self calls the method handleAddExpenseCommand(input)
with the input
still being the entire
user input.AddExpenseCommand(input)
, the first check would be the check for the existence of any combination of
c/ , and a/
. If none of these combinations were found, it immediately returns null
.If the checks in 4.
is passed, two variables would be initialized.
Variable Name | Variable Type |
---|---|
category | String |
amount | String |
Parser#extractDetailsForAdd(input, "parameter")
Parser#handleAddExpenseCommand()
intialises a AddExpensesCommandCreator
which then returns AddSavingCommand
to Parser#parseCommand()
, which is then returned to BudgetBuddy
.The Add Shared Bill Feature allows users to enter expenses that are shared among multiple parties, facilitating easy splitting and tracking of such expenses. The feature is managed by the SplitExpenseCommand
class, which is initialized by the SplitExpenseCommandCreator
as a result of the Parser class interpretation.
Class Attributes for SplitExpenseCommand:
Class Attribute | Variable Type | Relevance |
---|---|---|
splitExpenseList | SplitExpenseList | SplitExpenseList O bject where the shared bill will be added |
amount | double | The total amount of the shared bill |
numerOfPeople | int | The number of people that are meant for splitting the bill |
description | String | Description of the shared bill |
Upon the call of the execute() method via command.execute(), SplitExpenseCommand performs the following key actions:
Key Methods used from SplitExpenseList
Method | Return Type | Relevance |
---|---|---|
addSplitExpense() | void | Adds the splitexpense to the list of splitexpenses |
The SplitExpenseCommand also provides an output summarizing the shared expense, each participant’s share.
Sequence Diagram for Adding a Shared Bill The sequence diagram illustrates the flow from when a user inputs a command to add a shared bill to its execution:
User Input: The user inputs a command in the format add shared bill a/<Amount> n/<NumberOfPeople> d/<Description>
Parsing: The Parser
class identifies the input as a shared bill command and extracts the necessary parameters (amount
, number of people
, description
).
Command Initialization: The Parser
initializes a SplitExpenseCommand
with the extracted parameters.
Execution: The SplitExpenseCommand
is executed, which calls addSplitExpense()
on the SplitExpenseList
to add the shared bill.
Calculation: The command calculates each participant’s share of the bill and records it.
The Edit Savings feature allows users to update their previously saved financial contributions, specifically adjusting
the category
and amount
. This feature is facilitated by the EditSavingCommand
class, which is prepared and issued
by the Parser
class. An EditSavingCommand
object encapsulates several variables that are instantiated within the
Parser
: a SavingList
object, category
, and amount
. The significance of these Class Attributes within
EditSavingCommand
is detailed below:
Class Attribute | Variable Type | Relevance |
---|---|---|
savings | SavingList | SavingList Object containing the list of savings that can be modified |
category | String | The updated category for the saving entry at the specified index |
amount | Double | The updated monetary value for the saving entry at the specified index |
Upon invoking the execute()
method in BudgetBuddy
through command.execute()
, the EditSavingCommand
object
leverages the following method from the SavingList
class to carry out the modification:
Method | Return Type | Relevance |
---|---|---|
editSaving() | void | Adjusts the amount for the saving entry at the provided category |
The following UML Sequence diagram illustrates the execution process of the Edit Savings Feature Command when a user enters a valid edit savings command:
Here is a step-by-step narrative of the actions taken for a sample input:
edit savings c/Salary a/3000
edit savings c/Salary a/3000
and passes it to the Parser
for interpretation.Parser
splits the command into components and constructs an EditSavingCommand
object with the category (c/Salary
) and amount (a/3000
).Parser
returns the constructed EditSavingCommand
object to BudgetBuddy.execute()
method on the EditSavingCommand
object.execute()
method, EditSavingCommand
calls the editSaving
method of SavingList
, supplying the relevant parameters.SavingList
updates the entry’s amount to 3000 for the category Salary.The Edit Expense feature allows users to edit their previously added expenses, specifically the category
, amount
,
and description
. This feature is managed by the EditExpenseCommand
class, which is initialized by the
Parser
class. Within the EditExpenseCommand
object, 5 variables would have been initialized in the Parser
class:
an ExpenseList
object, category
, index
, amount
and description
. The relevance of these Class Attributes in
EditExpenseCommand
is as follows:
Class Attribute | Variable Type | Relevance |
---|---|---|
expenses | ExpenseList | ExpenseList Object containing the list of expenses that can be edited |
category | String | The edited category for the expense in the specified index |
index | Integer | The index of the expense to be edited from ExpenseList |
amount | Double | The edited amount the expense in the specified index should be |
description | String | The edited description for the expense in the specified index |
When the execute()
method in BudgetBuddy
is called via command.execute()
, the EditExpenseCommand
Object,
utilizes the following method from the ExpenseList
class to edit the expense.
Method | Return Type | Relevance |
---|---|---|
editExpense() | void | Edits the category , amount and description for the expense in the specified index |
The following UML Sequence diagram below shows how the Edit Expense Feature Command is executed when a user inputs a valid edit expense command:
The following is a step by step explanation of the processes that occur for an example input:
edit expense c/Transport i/2 a/40 d/GRAB
edit expense c/Transport i/2 a/40 d/GRAB
and uses
the Parser
to interpret it.Parser
splits the input into parts and constructs a EditExpenseCommand
Object with the category
(c/Transport
), index (i/2
),
amount (a/40
), and description (d/GRAB
).Parser
returns this called EditExpenseCommand
Object to BudgetBuddy
.BudgetBuddy
application calls execute()
on the EditExpenseCommand
object.EditExpenseCommand
object calls editExpense
on the ExpenseList
with the provided parameters.ExpenseList
looks up the second expense in its list
(as lists are zero-indexed, it uses index - 1 to access the correct item), and updates this expense’s
category to “Transport,” amount to 40.0, and description to “GRAB.”The Reduce Savings feature enables users to decrement a specified amount from their savings at a given index. This
functionality is controlled by the ReduceSavingCommand
class, which is produced by the ReduceSavingCommandCreator
based on user input. The ReduceSavingCommand
class uses a SavingList
object to access the relevant saving and performs
the reduction operation using the provided index and amount. Below is the relevance of these attributes:
Class Attribute | Variable Type | Relevance |
---|---|---|
savings | SavingList | The SavingList object containing the list of savings which can be reduced |
category | String | TThe category of savings to reduce |
amount | double | The amount by which the savings in the specified category should be reduced |
When BudgetBuddy
runs the execute()
method through command.execute()
, the ReduceSavingCommand
leverages the reduceSavingsByCategory method from the SavingList
class:
Method | Return Type | Relevance |
---|---|---|
reduceSavingsByCategory() | void | Decreases the savings by a specified amount in a given category |
The user interaction for reducing savings follows these steps:
reduce savings c/[category] a/[amount]
.BudgetBuddy
processes this input with the help of a Parser
, which identifies the suitable CommandCreator
.Parser
constructs a ReduceSavingCommand
object with the extracted category and amount.BudgetBuddy
then executes the ReduceSavingCommand
.execute()
method within ReduceSavingCommand calls the SavingList’s reduceSavingsByCategory function.reduceSavingsByCategory
method performs the deduction and updates the savings amount.The following UML Sequence diagram below shows how the Reduce savings Feature Command is executed when a user inputs a valid reduce savings command:
The Delete Expense feature grants users the capability to remove expenses they have previously entered. Managed by the
DeleteExpenseCommand class, this feature is initialized through DeleteExpenseCommandCreator. During the creation process,
the command is provided with an ExpenseList
object and an index
indicating the specific expense to be deleted.
The following table outlines the significance of these attributes:
Class Attribute | Variable Type | Relevance |
---|---|---|
expenses | ExpenseList | ExpenseList Object containing the list of expenses that can be edited |
index | Integer | The edited category for the expense in the specified index |
On invocation of the execute()
method, as part of the command.execute()
flow within BudgetBuddy, the DeleteExpenseCommand
object engages the deleteExpense() method from the ExpenseList class.
Method | Return Type | Relevance |
---|---|---|
deleteExpense() | void | Removes the expense at the specified index from the list |
The user interaction for deleting expenses follows these steps:
delete expense i/index
, with index
specifying the expense to be deleted.BudgetBuddy
receives the command and employs the Parser to deconstruct it.Parser
discerns the delete command, extracting the index value and forming a DeleteExpenseCommand object.BudgetBuddy
triggers the DeleteExpenseCommand.execute() method.execute()
, the deleteExpense()
method is called on ExpenseList
, with index
indicating the targeted expense.The Listing Savings Feature enables users to view their savings, potentially filtered by a specific category. This functionality is orchestrated by the ListSavingsCommand
class, which is initialized by the ListCommandCreator
class. Within the ListSavingsCommand
object, the ListCommandCreator
provides it with a SavingList
object, an ExpenseList
object, along with an optional filterCategory
. The relevance of these class attributes in ListSavingsCommand
is detailed in the following table:
Class Attribute | Variable Type | Relevance |
---|---|---|
savings | SavingList | The SavingList object containing the list of savings to be displayed or filtered |
expenses | ExpenseList | The ExpenseList object containing the list of expenses |
filterCategory | String | The category to filter the savings by, if provided |
When BudgetBuddy
invokes the execute()
method via command.execute()
, the ListSavingsCommand
object uses several methods from the SavingList
class to perform its tasks:
Method | Return Type | Relevance |
---|---|---|
getSavings() | ArrayList |
Retrieves the list of all savings from the SavingList |
findTotalSavings() | void | Calculates the total amount of savings stored in SavingList |
listSavings() | void | Prints the savings, filtered by filterCategory , to the CLI |
calculateRemainingSavings() | double | Calculates the remaining amount after deducting total expenses |
The Listing Savings feature follows these steps when a user inputs a command to list savings:
list savings [optional: filterCategory]
. This input is processed by the Parser
class in BudgetBuddy
, which creates a ListSavingsCommand
object with savings
set to the current SavingList
and filterCategory
to the user-specified category, if any.Parser
returns this ListSavingsCommand
object to BudgetBuddy
, which calls ListSavingsCommand.execute()
.execute()
calls SavingList.listSavings(filterCategory, expenses)
, where the filterCategory
is applied if provided.listSavings()
, the findTotalSavings()
method is called first to calculate the initial total savings amount.listSavings()
method continues by iterating through each Saving
and printing those that match the filterCategory
criteria.calculateRemainingSavings(initialAmount, totalExpenses)
, accounting for any expenses deducted.filterCategory
is not provided, all savings are printed, and the total initial amount and remaining savings after expenses are displayed.The UML Sequence diagram for the Listing Savings feature would illustrate the interactions between the User
, BudgetBuddy
, Parser
, ListSavingsCommand
, and SavingList
classes, showing the method calls and returns between these objects to complete the operation.
The Listing Expenses Feature provides users with the ability to view their expenses, which can be filtered by category. The ListExpenseCommand
class, generated by the ListCommandCreator
, is responsible for this feature. The class utilizes the ExpenseList
object to access and manipulate expense records, optionally applying a filter based on the category. The significance of the ListExpenseCommand
class’s attributes is outlined below:
Class Attribute | Variable Type | Relevance |
---|---|---|
expenses | ExpenseList | Holds the list of expenses to be filtered and listed |
filterCategory | String | The category to filter the expenses by (null if no filtering is needed) |
Upon invoking the execute()
method by BudgetBuddy
through command.execute()
, the ListExpenseCommand
object calls upon several methods from the ExpenseList
class to carry out its responsibilities:
Method | Return Type | Relevance |
---|---|---|
listExpenses() | void | Prints the expenses, filtered by filterCategory , to the command line |
calculateTotalExpenses() | double | Calculates the total expenses from the list of expenses |
Here’s an overview of the process flow when a user employs the Listing Expenses feature:
list expenses [optional: filterCategory]
. This command is parsed by the Parser
class within BudgetBuddy
, which then creates a ListExpenseCommand
with expenses
set to the current ExpenseList
and filterCategory
set to any specified by the user.Parser
returns the ListExpenseCommand
object to BudgetBuddy
, which calls ListExpenseCommand.execute()
.execute()
method invokes ExpenseList.listExpenses(filterCategory)
. If a filterCategory
is provided, it will filter the expenses accordingly.listExpenses()
method in ExpenseList
iterates over the list of expenses and prints each one that matches the filter category criteria or all expenses if no filter is provided.calculateTotalExpenses()
.The sequence diagram for the Listing Expenses feature would illustrate the above steps, showing the interactions between the User
, BudgetBuddy
, Parser
, ListExpensesCommand
, and ExpenseList
classes.
The Check Split Bills Feature allows users to view a list of all bills that have been marked as split among multiple parties. This is particularly useful for tracking shared expenses in scenarios like shared accommodations, group trips, or joint projects.
Class Attributes for CheckSplitExpensesCommand:
Class Attribute | Variable Type | Relevance |
---|---|---|
splitExpenseList | splitExpenseList | Object containing the list of split bills to display |
When BudgetBuddy executes the ListSplitExpenseCommand
via command.execute()
, the ListSplitExpenseCommand
uses the following method from the SplitExpenseList
class to retrieve and display all split expenses:
Method | Return Type | Relevance |
---|---|---|
listSplitExpense | ArrayList |
Retrieves and displays a detailed list of all recoreded split expenses |
Process Overview:
check split bills
.
1 BudgetBuddy
processes this input with the help of a Parser
, which then initialises the ListSplitExpenseCommandCreator
.Parser
constructs a ListSplitExpenseCommand
with the split expenses list as a parameter.BudgetBuddy
then executes the ListSplitExpenseCommand
.execute()
method within the ListExpenseCommand
calls the listSplitExpenses()
method on the SplitExpenseList
.listSplitExpenses()
method retrieves all split expenses and formats them for display.Sequence Diagram: The sequence diagram for the Check Split Expenses feature would illustrate the interactions between the User, BudgetBuddy, Parser, CheckSplitExpensesCommand, and SplitExpenseList classes, showing how the method calls and returns between these objects complete the operation to display all split expenses.
The Settle Bill Feature allows users to mark shared bills as settled, which is crucial for tracking repayments in scenarios such as shared accommodations or group outings.
Class Attributes for SettleBillCommand
:
Class Attribute | Variable Type | Relevance |
---|---|---|
splitExpenseList | SplitExpenseList | Object containing the list of shared bills to be settled |
When BudgetBuddy
executes the SettleSplitExpenseCommand
via command.execute()
, the SettleSplitExpensesCommand
uses the following method from the SplitExpenseList
class to delete the bill:
Method | Return Tyoe | Relevance |
---|---|---|
settleSplitExpense(index) | void | Marks the split expense at the given index as settled |
Process Overview:
settle bill 3
.BudgetBuddy
processes this input with the help of a Parser
, which initialises the SettleSplitExpenseCommandCreator
.Parser
constructs a SettleSplitExpenseCommand
with the split expense list and index as parameters.BudgetBuddy
then executes the SettleSplitExpenseCommand
.execute()
method within SettleSplitExpenseommand
calls the settleSplitExpense(index)
method on the SplitExpenseList
.settleSplitExpense(index)
method deletes the shared bill at the specified index.Sequence Diagram:
The sequence diagram for the Settle Bill feature would illustrate the interactions between the User
, BudgetBuddy
, Parser
, SettleSplitExpenseCommand
, and SplitExpenseList
classes, showing how the method calls and returns between these objects complete the operation to mark a shared bill as settled.
The Find Feature allows users to search for expenses based on a specific criteria such as description, minimum amount
and maximum amount. This feature is orchestrated by the FindExpensesCommand
class, which is created by the FindExpensesCommandCreator
, which is in turn created by the Parser
. Within the FindExpensesCommand
object, the FindExpensesCommandCreator
would have initialized it with 4 variables, an ExpenseList
object, along with a description
, minAmount
,
maxAmount
. The relevance of these Class Attributes in FindExpensesCommand
is as follows :
Variable Name | Variable Type | Relevance |
---|---|---|
expenses | ExpenseList | ExpenseList Object containing the list of expenses which will be filtered |
description | String | The description to match against expenses in expenses |
minAmount | Double | The minimum amount matched expenses should be |
maxAmount | Double | The maximum amount matched expenses should be |
Upon the call of the execute()
method in BudgetBuddy
using command.execute()
,
the FindExpensesCommand
Object, utilizes the following methods from the ExpenseList
class in order to both
obtain a new ExpenseList
object containing the filtered expenses, along with printing them.
Method | Return Type | Relevance |
---|---|---|
filterExpenses() | ArrayList |
Returns an ArrayList |
listExpenses() | void | Prints the filtered expenses obtained from filterExpenses() |
Important Note : As the process of how the CommandCreator is created upon the receipt of a user input has already been
discussed in 3.4 CommandClass
, the following Sequence Diagrams would omit the initial methods prior to the
FindCommandCreator being created.
The following UML Sequence diagram below shows how FindExpensesCommandCreator works to obtain the relevant inputs for the FindExpensesCommand, NOTING that the Parser has already determined the input to be a find expenses command, and has also created the FindExpensesCommandCreator.
Given that multiple methods are called in FindExpensesCommandCreator
. The following is a step-by-step explanation for the processes that occur before the FindExpensesCommand is created :
BudgetBuddy
calls Parser#parseCommand(input)
with input
being the entire user input.
E.g find expenses d/bruno morethan/ lessthan/
Parser
, it will have determined that the input
is a Find Command from the isFindCommand(input)
.Parser
then creates a FindExpensesCommandCreator
object, initializing it with the overall Expense List and
the provided user inputParser
then calls FindExpensesCommandCreator#createCommand()
.FindExpensesCommandCreator#createCommand()
then calls FindExpensesCommandCreator#handleFindExpensesCommand()
handleFindExpensesCommand(input)
, the first check would be the check for the existence of any combination of
d/ , morethan/ and lessthan/
using the method checkForInvalidParameters()
. If none of these combinations were found, it immediately returns null
checkForOutOfOrderParameters()
, which checks whether d/
, morethan/
and lessthan/
is in the right order.checkForDuplicateParameters()
, which checks for duplicates of parameters
in the user input. It duplicates are found, similarly, it immediately returns null
.If the checks in 6.
7.
and 8.
is passed, or in this case No Exceptions are thrown.
Three variables would be initialized.
Variable Name | Variable Type |
---|---|
description | String |
minAmount | Double |
maxAmount | Double |
FindExpensesCommandCreator#parse*()
, where *
represents the variable name we wish to obtain.minAmount
and maxAmount
not be empty, a check is done to ensure minAmount
is less than
or equals to maxAmount
. If this check does not pass, the function immediately returns null
FindExpensesCommandCreator#handleFindExpensesCommand()
creates and returns a
FindExpensesCommand
containing the extracted description, minAmount and maxAmountFindExpensesCommandCreator#createCommand()
, which is returned to, Parser#parseCommand()
, which is then returned to BudgetBuddy
The following UML Sequence diagram below shows how the Find Feature command works when a user provides a valid find expenses command upon the call of its execute() method:
Important Note : Although d/ , morethan/ and lessthan/ are optional parameters, the optional component would mean
user has left that option empty if not in use, e.t.c find expenses d/ morethan/ lessthan/200
. Hence,
unused parameters are treated as null variables instead.
Important Note 2 : Although the UI class is also initialized, the details of its use is omitted as its functionality in the Find Feature is trivial. In this case, the UI class is only used to print dividers.
The following is an example of the processes that occur when the user uses the find expenses feature:
find expenses d/bruno morethan/30 lessthan/200
. This input is passed through the Parser
class from BudgetBuddy
, which constructs a FindExpenseCommandCreator
Object. The FindExpenseCommandCreator
then
creates a FindExpenseCommand
object with its variables initialized to expenses : current overall ExpenseList
,
description : bruno
, minAmount : 30
, maxAmount : 200
, by calling FindExpenseCommandCreator#createCommand()
.Parser
returns this created FindExpenseCommand
Object to BudgetBuddy
and BudgetBuddy
calls
FindExpenseCommand#execute()
execute()
is called, which initializes a variable filteredExpenses
of type ArrayList<Expense>
.execute()
then calls ExpenseList#filterexpenses()
, which returns the filtered expenses based on the description
,
minAmount
and maxAmount
, into the filteredExpenses
variable.filteredExpenses
is empty, “No Matching Expenses Found” is printed and execute
ends here.filteredExpenses
is not empty, execute()
then initializes a new variable filteredExpenseList
of type ExpenseList
with filteredExpenses
initialized as the expenses
Class attribute.execute()
calls filteredExpenseList#listexpenses()
to print filtered expenses into the CLI.The Recurring Expenses feature allows users to create list(s) of expenses, where each list can be added to
the overall expenses in a single command. This feature includes the creation of a list of expenses, the viewing of
all/each list of expenses and the removal of each list of expenses. All functions are orchestrated by the
RecurringExpenseCommand
class, which would have been created by the RecurringExpenseCommandCreator
, which is in turn
created by the Parser
class. When RecurringExpenseCommand#execute()
is called by BudgetBuddy
, it utilizes methods
present in ExpenseList
, RecurringExpenseList
and RecurringExpenseLists
to facilitate the relevant features.
Within the RecurringExpenseCommand, the following variables would be initialized :
Variable | Variable Type | Relevance |
---|---|---|
overallExpenses | ExpenseList | Refer to the overall Expense List storing all of User’s Expenses |
initialListName | String | Used as the name of the new list that will be created |
commandType | String | Type of RecurringExpenseCommand. E.g. newlist , viewlists , … |
listNumber | int | Refers to the List Number of a recurring expense list shown during viewlists |
category | String | Category of the Expense to be added when using newexpense |
amount | Double | Amount of Expense to be added when using newexpense |
description | String | Description of Expense to be added when using newexpense |
When viewing the code, you would notice that there are 5 different constructors in RecurringExpensesCommand
. These
constructors correspond to the different commandTypes
present. Each constructor would initialize only the required
parameters for the specified commandTypes
.
A switch statement in RecurringExpensesCommand
is used, where it runs the corresponding function according to the
commandType
. The following is the commandType
, class-level methods used and methods utilized from other classes
when RecurringExpensesCommand#execute()
is called
commandType | Calls Method | Uses Methods From | |
---|---|---|---|
newlist | addNewList() | RecurringExpenseLists#addNewRecurringList() |
|
viewlists | printList() | RecurringExpenseLists#printAllRecurringLists() |
|
removelist | removeList() | RecurringExpenseLists#removeList() |
|
newexpense | addExpenseToList() | RecurringExpenseLists#getExpenseListAtListNumber() , ExpenseList#addExpense() |
|
addrec | addRecurringExpensesToExpenses() | RecurringExpenseLists#getExpenseListAtListNumber() , ExpenseList#getExpenses() , AddExpenseCommand#execute() |
|
viewexpenses | printExpensesAtIndex | RecurringExpenseLists#getExpenseListAtListNumber() , ExpenseList#listExpenses() |
From the table above, most commandTypes have a fairly straight forward process of calling a single method from the relevant classes, and follows
a similar process to many of the previous features too. Hence, the explanation of these trivial methods would be left out to avoid repetition. For details regarding these methods, you may also view the JavaDoc comments found in the code.
However, the addrec
commandType would be the most complicated to follow, given that it utilizes 3 methods from three different classes. The following
is a UML sequence diagram to illustrate the implementation of the addRecurringExpensesToExpenses() method in RecurringExpenseCommand
, upon the call of the execute()
from BudgetBuddy
The following is an example of the processes that occur when the user uses the rec addrec command :
rec addrec 1
. This input is passed through the Parser
class from BudgetBuddy
, which constructs a RecurringExpenseCommandCreator
RecurringExpenseCommandCreator
identifies that the command type is addrec
, obtains all the relevant parameters,
and uses the constructor RecurringExpenseCommand(1, recurringExpenseLists, overallExpenses, addrec)
. Note that
recurringExpenseLists
here is the overall list containing all lists of recurring expenses and overallExpenses
is the user’s
overall expenses.RecurringExpenseCommand
is returned to the Parser
, which is then returned to BudgetBuddy
.BudgetBuddy
calls RecurringExpenseCommand#execute()
execute()
, RecurringExpenseCommand
identifies it needs to perform a addrec
operation from its
commandType
and calls its own addRecurringExpensesToExpenses()
recurringExpenseList
we wish to add into the overallExpenses
is obtained utilizing RecurringExpensesList#getExpenseListAtListNumber(listNumber)
where listNumber
is 1
.ArrayList<Expense> expenses
is extracted by utilizing ExpenseList#getExpenses()
from our extracted recurringExpenseList
category
, amount
and description
of all the expenses present in expenses
and adding them one by one into the overallExpenses
. This is done so by creating a new AddExpenseCommand
with the relevant parameters and executing it. FOr more details regarding
this AddExpenseCommand
, do refer to the Implementation
section for AddExpenseCommand
.The Currency Converter Feature allows users to convert the currency of expenses and savings. This feature is facilitated by the ChangeCurrencyCommand
class, initialized by the Parser
class with CurrencyConverter
, ExpenseList
, and SavingList
objects, alongside the newCurrency
to convert to. The importance of these class attributes is as follows:
Class Attribute | Variable Type | Relevance |
---|---|---|
currencyConverter | CurrencyConverter | The object responsible for currency conversion calculations |
expenseList | ExpenseList | Contains the expenses whose currency will be converted |
savingList | SavingList | Contains the savings whose currency will be converted |
newCurrency | Currency | The new currency to which the amounts will be converted |
exchangeRates | Map<Currency, Double> | Stores exchange rates with currencies as keys |
When BudgetBuddy
calls command.execute()
, ChangeCurrencyCommand
employs the following methods from CurrencyConverter
to convert the currency of all financial records:
Method | Return Type | Relevance |
---|---|---|
convertExpenseCurrency() | void | Converts the currency of each Expense object to newCurrency |
convertSavingCurrency() | void | Converts the currency of each Saving object to newCurrency |
convertBudgetCurrency() | void | Converts the currency of each Budget object to newCurrency |
convertRecurringExpensesCurrency() | void | Converts the currency of each Expense object in each ExpenseList object of the RecurringExpenseLists object to newCurrency |
convertAmount() | double | Converts an amount from one currency to another using the exchange rates |
The Currency Converter feature also includes a mechanism for managing a default currency across the application, facilitated by the DefaultCurrency
class. This enhancement allows for seamless conversion of financial records to a user-specified default currency.
convertAmount(double amount, Currency fromCurrency, Currency toCurrency)
:
This method converts an amount from one currency to another using exchange rates stored in the exchangeRates
map.
It takes the original amount, the currency of the original amount (fromCurrency
),
and the target currency (toCurrency
) as parameters and returns the converted amount.
The method ensures that exchange rates are available for both currencies and that they are positive numbers.
convertExpenseCurrency(Currency newCurrency, ExpenseList expenses)
:
This method converts the currency of expenses in a given ExpenseList
to a specified new currency (newCurrency
).
It iterates through the expenses in the list, converts each expense amount to the new currency
using the convertAmount
method, and updates the expense amounts and currencies accordingly.
convertSavingCurrency(Currency newCurrency, SavingList savings)
: Similar to convertExpenseCurrency
,
this method converts the currency of savings in a given SavingList
to a specified new currency (newCurrency
).
It iterates through the savings in the list, converts each saving amount to the new currency using the convertAmount
method, and updates the saving amounts and currencies accordingly.
convertBudgetCurrency(Currency newCurrency, ExpenseList expenseList)
:
This method is responsible for converting the currency of all budgets within ExpenseList
to a specified new currency (newCurrency
). It
accepts the new Currency
object representing the target currency and the ExpenseList
containing the budgets, and updates
the budget amounts and currencies accordingly.convertRecurringExpensesCurrency(Currency newCurrency, RecurringExpenseLists recurringExpenseLists)
This Method converts the currency of expenses of each ExpenseList
within recurringExpenseLists
by continuously calling the method convertExpenseCurrency
for each ExpenseList
.
The DefaultCurrency
class is designed to maintain and update the application-wide default currency setting. It provides static methods to get and set the default currency:
Method | Return Type | Relevance |
---|---|---|
getDefaultCurrency | Currency | Retrieves the current default currency for the application |
setDefaultCurrency | void | Updates the default currency to a new value |
Here’s the step-by-step process when the user uses the Currency Converter feature:
change currency [newCurrencyCode]
. Parser
processes this input and constructs a ChangeCurrencyCommand
object with the necessary attributes.ChangeCurrencyCommand
object is returned to BudgetBuddy
, which calls ChangeCurrencyCommand.execute()
.execute()
invokes CurrencyConverter.convertExpenseCurrency(newCurrency, expenseList)
and CurrencyConverter.convertSavingCurrency(newCurrency, savingList)
.convertExpenseCurrency
and convertSavingCurrency
call, the amounts of Expense
, Saving
or Budget
objects are converted to the newCurrency
using the convertAmount
method.DefaultCurrency.setDefaultCurrency(newCurrency)
method is called to update the application’s default currency setting to newCurrency
.setAmount
and setCurrency
methods of ExpenseList
and SavingList
are used to update the amounts and currency codes.The sequence diagram would be segmented into the different features that utilises the CurrencyConverter class.
Main Sequence Diagram before Execution:
Upon execution, the following respective conversion functions will run:
Sequence Diagram for convertExpenseCurrency():
Sequence Diagram for convertSavingCurrency():
Sequence Diagram for convertRecurringExpensesCurrency():
Sequence Diagram for convertSplittedExpenseCurrency():
Sequence Diagram for convertBudgetCurrency():
The Budget Management feature allows users to set financial limits for the various categories and monitor their spending. This feature’s objective is to give users the ability to stay within their financial goals and avoid overspending.
This feature is orchestrated by ListBudgetCommand
and SetBudgetCommand
, which are initialised by the Parser
class. Below is a description of the key class attributes and methods involved in the budget setting and listing
process:
SetBudgetCommand
:Class Attribute | Variable Type | Relevance |
---|---|---|
expenseList | ExpenseList | Object containing the list of expenses to check against set budgets |
category | String | The category for which the budget is being set |
budget | double | The budget amount to be set for the category |
The UML Sequence diagram below illustrates the execution flow of the Set Budget Feature when a user inputs a valid command to set a budget:
The sequence of operations for an example input, set budget c/Transport b/500
, is as follows:
ListBudgetCommand
:Class Attribute | Variable Type | Relevance |
---|---|---|
expenseList | ExpenseList | Object containing the list of expenses to check against set budgets |
The UML Sequence diagram below illustrates the execution flow of the Set Budget Feature when a user inputs a valid command to list budgets:
Upon the call of the execute()
method in BudgetBuddy
using command.execute()
, SetBudgetCommand
will update the
budget in ExpenseList
using setBudget
. Similarly, ListBudgetCommand
will fetch and display all categories with
their budgets using getBudgets
, and highlight those that are above the set budget.
ExpenseList
Method | Return Type | Relevance |
---|---|---|
setBudget(category, budget) | void | Sets or updates the budget for a given category in the ExpenseList |
getBudgets() | List |
Retrieves the list of all budgets set |
The ListBudgetCommand
’s updated execution function now features an improved display that not only shows the budget,
spent amount, and remaining balance but also clearly indicates when the budget has been exceeded. If the expenses
surpass the budget, instead of showing a negative remaining balance, it displays “Exceeded”, providing a straightforward
and immediate visual cue that the budget limits have been surpassed.
The “Categories above budget” section offers a concise table summarizing which categories have gone over the budget and by what amount, making it easy for users to identify areas of concern.
The Get Expense Insights feature allows users to analyze their spending patterns and understand where their money goes.
This feature is managed by the GetExpenseInsightsCommand
class, which is initialized by the Parser
class.
The GetExpenseInsightsCommand
holds an ExpenseList
object which contains all expenses added by the user.
The relevance of this Class Attribute in GetExpenseInsightsCommand
is as follows:
Class Attribute | Variable Type | Relevance |
---|---|---|
expenseList | ExpenseList | ExpenseList object containing the list of expenses to be analyzed |
Upon invocation of the execute()
method in BudgetBuddy
, the GetExpenseInsightsCommand
leverages methods from the
ExpenseList
class to calculate and display spending insights.
Method | Return Type | Relevance |
---|---|---|
getExpenseInsights | void | Analyzes expenses and prints insights on spending distribution, highest and lowest spending |
The following UML Sequence diagram illustrates the execution process of the Get Expenses Insights Command when a user enters a valid command:
Here’s a step-by-step explanation of the processes that occur when a user invokes the Get Expense Insights feature:
get expenses insights
and passes it to the Parser
.Parser
interprets the input and creates a new GetExpenseInsightsCommand
object with the ExpenseList
.BudgetBuddy
application then calls execute()
on the GetExpenseInsightsCommand
object.GetExpenseInsightsCommand
object calls the getExpenseInsights
method on the ExpenseList
.ExpenseList
analyzes the expenses, calculating total spendings, average amount, and categorizing the expenses.The Get Savings Insights feature enables users to analyze their savings distribution across various categories and
understand their saving habits. This feature is facilitated by the GetSavingsInsightsCommand
class, which is
instantiated by the Parser
class. In this class, a SavingList
object is maintained, which contains all the savings
added by the user. The significance of the class attribute in GetSavingsInsightsCommand
is as detailed below:
Class Attribute | Variable Type | Relevance |
---|---|---|
savingList | SavingList | SavingList object containing the list of savings to be scrutinized. |
When the execute()
method in BudgetBuddy
is invoked via command.execute()
, the GetSavingsInsightsCommand
leverages methods from the SavingList
class to calculate and exhibit insights about savings.
Method | Return Type | Relevance |
---|---|---|
getSavingsInsights() | void | Analyzes savings and displays insights on savings distribution, highest and lowest savings, etc. |
The following UML Sequence diagram illustrates the execution process of the Get Savings Insights Command when a user enters a valid command:
The sequential flow of execution when a user commands to get savings insights is as follows:
BudgetBuddy
captures it.BudgetBuddy
employs Parser
to decode the input.Parser
constructs a new GetSavingsInsightsCommand
object with the SavingList
.Parser
sends this GetSavingsInsightsCommand
object back to BudgetBuddy
.BudgetBuddy
calls the execute()
method on the GetSavingsInsightsCommand
object.GetSavingsInsightsCommand
invokes the getSavingsInsights()
method from the SavingList
.SavingList
computes and prints the insights, such as the categories with the highest and lowest savings and the overall distribution.The following section describes how documentation for the project was written. Documentation Format follows GitHub-Flavoured Markdown.
The following section describes the testing methodologies followed in this project to ensure the project is of the highest standard and as bug-free as possible.
JUnit tests have been added to the project, which can be found under src/test
. These JUnit tests aid in testing the respective commands and features against
both valid and invalid inputs. To run these tests, on IntelliJ IDE
, simply
right-click
the test
folder followed by More Run/Debug
-> Run Tests with Coverage
. This would run all the pre-defined tests, and also display the
coverage for each file of the main application.
A Global Logger is utilized in certain methods and features which are more prone to errors, etc., methods that may potentially deal with invalid inputs. In the releases, this Logger is disabled using the command
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).setLevel(Level.OFF);
before run()
is called in BudgetBuddy#main()
. However, in the code files, the Logger is still enabled and aids in tracing the code when testing for errors.
This product is for users who can type fast, and wishes to handle and track their current and future expenses on a singular platform.
BudgetBuddy is faster and more efficient way to track and calculate current and future expenses if a user is able to type fast. It also provides the ability to deal with finances on a singular platform.
Version | As a … | I want to … | So that I can … |
---|---|---|---|
v1.0 | user | be able to view my expenses | track my prior expenditures and plan future expenses accordingly |
v1.0 | user | be able to view my savings | plan my budget accordingly |
v1.0 | user | be able to view my expenses by their relevant categories | control my spending |
v1.0 | user | be able to identify my largest savings category | allocate necessary saved funds |
v1.0 | user | add expenses | track my spending |
v1.0 | user | Categorise my expenses | manage my finances more efficiently |
v1.0 | user | Edit or delete expenses | remove any incorrectly added items |
v1.0 | user | allocate saved funds | know how much I will have left after expenses |
v1.0 | user | be able to find expenses by description | know the expenses i have that is associated with the description |
v1.0 | user | be able to find expenses more than a certain amount | know what my deemed larger expenses are |
v1.0 | user | be able to find expenses less than a certain amount | know what my deemed lower expenses are |
v1.0 | User | See what commands i can use | I know how to use the application |
v2.0 | user | Plan my budget | Avoid overspending |
v2.0 | frequent traveler | log my expenses in multiple currencies | accurately track my expenses across different countries |
v2.0 | user | add multiple expenses at once | Add common expenditures i have monthly at one shot |
v2.0 | user | have multiple lists of recurring expenses | separate associated recurring expenses together |
v2.0 | user | view what expenses i have in each of my recurring expenses list | know what expenses i have put into each list |
v2.0 | user | remove a list from my recurring expenses list | remove underutilized lists or wrongly added lists |
v2.0 | user | save my expenses | make sure i do not have to retype all expenses again after closing the application |
v2.0 | user | load my expenses | i can access previously added expenses when i reopen the application |
v2.0 | user | save my expenses in my recurring expenses | make sure i do not have to retype all expenses again after closing the application |
v2.0 | user | load my expenses in my recurring expenses | i can access previously added expenses in my recurring expenses when i reopen the application |
v2.0 | user | divide bills that are meant for splitting | know how much others should pay me |
v2.0 | user | settle bills that others have repaid me | see which bills have not been settled |
v2.0 | user | view my expenses in a graphical representation | to analyse my highest and lowest expense categories |
v2.0 | user | view my savings in a graphical representation | to analyse my highest and lowest saving categories |
(For all use cases below, the System is BudgetBuddy
and the Actor is the user
, unless specified otherwise).
11
or above installed.jar
file and copy into an empty folder.jar
file via a Terminal/PowerShell window.jar
file with the following command: java -jar BudgetBuddy.jar
menu
menu 1
menu string
menu 999
add expense c/Transport a/50 d/Bus fare
Transport
, amount $50
, and description Bus fare
. Confirmation message will be printed in the command line interface.add expense c/Transport a/-50 d/Bus Fare
expense c/Transport a/abc d/Bus Fare
add expense c/abc a/50 d/Bus fare
addSaving(String category, String amount)
Salary
, 500
1
. The category of the saved entry should be Salary
. The amount of the saved entry should be 500
.addSaving(String category, String amount)
Salary
, abc
Invalid amount format. Amount should be a positive number with up to maximum two decimal places.
addSaving(String category, String amount)
Salary
, -1.00
Invalid amount format. Amount should be a positive number with up to maximum two decimal places.
addSaving(String category, String amount)
abc
, 500
The category 'abc' is not listed.
SplitExpenseList
.addSplitExpense(String amount, String numberOfPeople, String description)
12
, 12
, Lunch
1
. The number of people for the split expense should be 12
. The description of the split expense should be Lunch
addSplitExpense(String amount, String numberOfPeople, String description)
abc
, 12
, Lunch
Invalid amount format. Amount should be a number.
addSplitExpense(String amount, String numberOfPeople, String description)
12
, abc
, Lunch
Number of people should be a number.
addSplitExpense(String amount, String numberOfPeople, String description)
-12
, 12
, Lunch
Expenses should not be negative.
Prerequisites : Some savings has been added to the overall savings.
edit savings c/Salary a/2000
Expected : Edits the saving with category “Salary”. If there is no saving with this category, an error message stating invalid category will be printed.edit savings c/Allowance a/2000
Expected : An error message mentioning invalid saving category will be printed.edit savings c/Salary a/-2000
Expected : An error message mentioning invalid amount will be printed.Prerequisites : Some savings has been added to the overall savings.
edit expense c/Transport i/2 a/2000 d/GRAB
Expected : if there is an expense with index 2, it edits the expense at index 2. Else, an error message stating invalid index will be printed.edit expense c/MRT i/2 a/2 d/work
Expected : An error message mentioning invalid saving category will be printed.edit savings c/Entertainment i/2 a/-2000
Expected : An error message mentioning invalid amount will be printed.reduce savings c/Salary a/100
Expected: The savings under ‘Salary’ are reduced by $100, and a confirmation message is displayed.
Prerequisites : No savings under the category ‘Investments’ exist.reduce savings c/Investments a/100
Expected: An error message is displayed indicating no savings found under the category ‘Investments’.
Prerequisites : Savings under the category ‘Salary’ exist but are less than $500reduce savings c/Salary a/500
Expected: An error message is displayed indicating insufficient amount in ‘Salary’ to reduce by $500.delete expense i/1
Expected: The first expense in the list, if any, is deleted and a confirmation message is displayed.delete expense i/999
Expected: An error message is displayed stating that the index is out of boundslist savings
Salary
category and expenses in the list.list savings Salary
Salary
category will be printed, along with the overall remaining savings deducting expenses.list expenses
Transport
category in the list.list expenses Transport
Transport
category will be printed, along with the overall amount.Prerequisites : Some expenses has been added to the overall expense.
find expenses d/cat morethan/ lessthan/
find expenses d/cat morethan/20 lessthan/
find expenses d/cat morethan/string lessthan
rec newlist streaming
streaming
rec newlist
rec newlist |
rec viewlists
, with already added lists rec viewlists
, with no added listsrec viewlists extra
viewlists
should still work as intended, with no exceptions being thrownrec removelist 1
, with a list being present at the list number 1
during rec viewlists
rec removelist string
rec removelist -1
rec removelist
rec newexpense to/1 c/Entertainment a/200 d/description
, with a list being present at list number 1
1
rec newexpense to/1
rec newexpense to/string c/Entertainment a/200 d/description
rec viewexpenses 1
, with a list being present at list number 1
and contains expenses insiderec viewexpenses 1
with a list not being presentrec viewexpenses 1
with a list being present at list number 1
, but does not contain any expenses insiderec addrec 1
, with a list being present at list number 1
and contains expense inside rec addrec 1
, with a list being present a list number 1
but does not contain any expenses insiderec addrec 1
, with a list not being present at list number 1
Prerequisite : The RecurringExpensesFile.txt
should be empty prior to each Test Case
RecurringExpensesFile.txt
called !!! newlist !!!
Expected : A recurring expense list named newlist
will be present when doing a rec viewlists
RecurringExpensesFile.txt
called !!! new!!!list !!!
RecurringExpensesFile.txt
called !!! newlist !!!
and another line below it 1 | 2024-04-13 | Entertainment | 203.35 | movies
newlist
will be present at list number 1 when doing a rec viewlists
and an expense with the above description is present when doing a rec viewexpenses 1
rec newlist streaming services
followed by a bye
RecurringExpensesFile.txt
should now contain a !!! streaming services !!!
. The list will also still be present after Relaunching application.rec newlist streaming services
followed by a rec newexpense to/1 c/Entertainment a/200 d/description
, followed by a bye
streaming services
which contains an expense with the description above will still be present after relaunching the application
change currency USD
change currency USD
set budget c/Groceries b/200
Expected: A budget of $200 is set for ‘Groceries’, and a confirmation message is displayed.set budget c/Transport b/-50
Expected: An error message is displayed indicating the budget cannot be negative.
Prerequisites : A budget for ‘Transport’ exists.set budget c/Transport b/300
Expected: The budget for ‘Transport’ is updated to $300, and a message confirming the update is displayed.Prerequisites : Budgets must be set for multiple categories.
print budget
Expected: All existing budgets are listed with their respective categories and amounts.
Prerequisites : No Budgets are setprint budget
Expected: A message is displayed indicating no budgets have been set.get expenses insights
get savings insights