- Developer Guide
- GSON Library for JSON parsing (https://github.com/google/gson)
- Retrofit Library for HTTP requests (https://github.com/square/retrofit
- AB-3 Developer Guide (https://se-education.org/addressbook-level3/DeveloperGuide.html)
- app.diagrams.net for creating diagrams (https://app.diagrams.net/)
First, fork this repo, and clone the fork into your computer. If you plan to use Intellij IDEA (highly recommended):
- Configure the JDK: Follow the guide [se-edu/guides] IDEA: Configuring the JDK to ensure Intellij is configured to use **JDK 11 **.
- Import the project as a Gradle project: Follow the guide [se-edu/guides] IDEA: Importing a Gradle
project to import the project into
IDEA.
❗ Note: Importing a Gradle project is slightly different from importing a normal Java project. - Verify the setup:
- Run the
com.moneymoover.MoneyMooverand try a few commands. - Run the tests using
./gradlew checkto ensure they all pass.
- Run the
- Configure the coding style
If using IDEA, you can use the following steps to import the code style settings.
- Go to
File → Settings → Editor → Code Style - Click the Gear Icon next to the
Schemebox and then clickImport Scheme → IntelliJ IDEA code style XML. - Select the
DefaultCodeStyle.xmlfile in the root of the project directory.
- Go to
- Set up CI
This project comes with a GitHub Actions config files (in
.github/workflowsfolder). When GitHub detects those files, it will run the CI for your project automatically at each push to themasterbranch or to any PR. No set up required. - Learn the design When you are ready to start coding, we recommend that you get some sense of the overall design by reading about MoneyMoover’s architecture.
When you are ready to start coding, we recommend that you get some sense of the overall design by reading about MoneyMoover’s architecture.
The diagram above provides a high-level overview of how the project is structured. The main components are:
- The
Mainclass which initialises all the other components at startup, and connects them with each other - The
UIcomponent which is responsible for all user input and output - The
Parsercomponent which parses user input and creates the relevant Command objects - The
Commandcomponent which executes the logic - The
Accountscomponent which manages the user's accounts - The
Forex(Foreign Exchange) component which handles exchange-rate related logic - The
Transactionscomponent which manages the user's transactions - The
Storagecomponent which handles the saving and loading of data to disk
The following is a high-level sequence of a single create-account SGD command, which demonstrates how the components
interact with each other:
The API of this component is specified in the Ui.java.
The UI class deals with the user interaction with the application, which includes the printing and the logic to read in
inputs. We will pass in the instance of UI into the execute method of the Command class. The main features includes:
-
Printing text such as new line, spacer, farewell message, greeting message.
-
Empowers the users to print customised message in
printfandprintMessagemethod. -
Reads in the user input as
String.
The Parser Component
- Parses the user input and creates the relevant
Commandobject - Makes use of the
CommandTypeenum to determine the type of command to create
Here is a class diagram of the Accounts component
The Accounts Component
- Stores the
AccountListwhich contains all the user's accounts AccountListhandles all logic dealing with accountsAccountstores both its currency type and its balance- There can be only one
CurrencyperAccount - There can be only one
Accountof eachCurrency
Here is a class diagram of the Forex component

The Forex Component
- Stores the exchange rates of 1 SGD to all supported currencies in a hash map
- Each
Forexobject represents the relationship between two currencies convertcan be called on aForexobject to convert an amount using the relationship- Each
Forexobject has an initial and targetCurrency - There is only one instance of the
exchangeRateshash map.
The Currency Enum
- Keeps all currency types supported by the exchange
- Exchange rates are manually pulled from https://www.xe.com/currencyconverter/convert
- Each
Forexinstance must have twoCurrencyassociated with it
When MoneyMoover starts, the Forex class calls its static method initializeRates(). This method calls the constructor of the ExchangeRates class, then sleeps for 5 seconds, then retrieves the HashMap that ExchangeRates has created from the method fetchExchangeRates within its constructor. Forex copies the HashMap and uses it for the rest of the user session.
fetchExchangeRates retrieves a Retrofit instance from the ExchangeRatesApiClient class, and uses it to create an instance of the ExchangeRatesApi, an interface that defines the methods for retrieving the exchange rates data from Open Exchange Rates API.
fetchExchangeRates then makes a call to getLatestExchangeRates to retrieve the exchange rates using the ExchangeRatesApi instance, and a base currency of USD, and our API token from Open Exchange Rates.
getLatestExchangeRates returns a Call object, and we enqueue a Callback object to get the onResponse() and onFailure() methods that will be called depending on the outcome of the Call. If the call is successful, onResponse() returns an ExchangeRatesResponse object containing the HashMap of ISO currency tags as Strings for keys, and doubles for rates. This data is then extracted using saveMap, which filters out the rates for our supported currencies and performs type conversion. The savedMap attribute of ExchangeRates is set to this filtered map, which is then passed to Forex via getExchangeRates.
If onFailure() is called, it means an unexpected error was encountered, such as losing Internet connection.
Below is a UML Diagram of the classes and their respective methods.

Here is a class diagram of the Transactions component

The Transactions component
- A
Transactionis recorded upon every command that changes the balance of an account - Certain commands allow the provision of a description parameter to associate a custom description to a transaction
Transactionsare only accessed through theTransactionManagerTransactionsassociated to an account are deleted if and only if the account is deleted
This feature is facilitated by AccountList Class within the Accounts Component.
The method called from AccountList is the addAccount method which creates a new Account object.The deleteAccount
method called from AccountList delete the specified Account object.
The current implementation initialises the Account with 0 balance.
Only currency account which 0 balance can be deleted.
Given below is an example of the usage of this feature and the mechanism at each step
Step 1: The user launches the application for the first time and AccountList is created with no Account
Step 2: The user passes in the command create-account <CURRENCY>, where CURRENCY is a valid string representing one
of the elements of the Currency enum
Step 3: The user passes in the command create-account <CURRENCY>, where CURRENCY is also valid but different to that
in step 1.
Step 4: The user passes the command delete-account CURRENCY, for example delete-account SGD.
The following sequence diagram shows how the Create Account operation works
The following sequence diagram shows how the Delete Account operation works
The add money(deposit) and withdraw money feature is facilitated by AddCommand and WithdrawCommand which both
extends the Command class. With the provided input from user (CURRENCY and AMOUNT), AddCommand
and WithdrawCommand
update the balance of respective currency account accordingly.
Step 1. The newly created SGD account has an initial balance of 0
Step 2. The user passes command add CURRENCY AMOUNT (eg. add SGD 100), where CURRENCY must be one of the available
currency and AMOUNT must be positive numbers.
Step 3. The user passes command withdraw (eg. withdraw SGD 25), where AMOUNT must be smaller than the currency
account balance.
The following sequence diagram shows how the add money operation works.
The following sequence diagram shows how the money withdrawal operation works.
The view balance feature is facilitated using Account instances stored within the AccountList object. The main
functionality is to view the balance of a specific currency if the currency is specified, else view all the currencies
in the account.
The exchange feature is facilitated using two Forex instances to represent the
exchange rates between two currencies. The current implementation reads manual exchange
rates from an online source. Future implementation will use an API to maintain up-to-date
exchange rates.
Exchange rate source: https://www.xe.com/currencyconverter/convert
The show-rate command executes as follows
- The initial and target currency are parsed from the input
- If the user included an amount, the amount is also parsed
- A
Forexobject showing the rate from the initial to the target currency is made - A
Forexobject showing the rate from the target to the initial currency is made - The Ui prints the exchanged amount if an amount was provided by the user for both rates
- The Ui will print the unit rate both ways if no amount was provided
The following sequence diagram shows how the Show Rate command works
The exchange feature is facilitated using Account instances stored within an AccountList
object. The main functionality is facilitated by the convert function within the Forex
component. The current implementation reads manual exchange rates from an online source. Future
implementation will use an API to maintain up-to-date exchange rates. An exchange call will produce two
transaction activity. A debit transaction will reflect on initial account and credit transaction will
reflect on target account
Exchange rate source: https://www.xe.com/currencyconverter/convert
This command is executed under the assumption that an Account for both the initial and target
currencies exist. To avoid redundancy, please see the create-account feature in the developer
guide for more specific steps on how Accounts are created.
The exchange command executes as follows:
- Initial and target currencies are parsed from the user input
- A Forex object is created using the parsed currencies (see
Forexcomponent for more information) - The amount to be exchanged is parsed from the user input
- The
Accountsfor both currencies are retrieved - The converted value is calculated using the
Forexobject - The value of the initial
Accountis updated - The value of the target
Accountis updated - The new balances are printed
The following sequence diagram shows how the Exchange command works
The show transactions feature is facilitated by TransactionCommand, extending from the Command class.
Since any one user might have many transactions, flags are used to specify search parameters for the command.
The Transaction command executes as follows:
- The command is parsed to determine if there are additional search parameters
- Interaction with the
TransactionManagerto retrieve relevant accounts - The relevant transactions are printed
The following sequence diagram shows how the Transaction command works
- Students who are planning to travel overseas
- People who need to exchange money for travel
- People who are comfortable using a CLI
MoneyMoover is a CLI application for managing and transferring international currencies, optimized for use via a Command Line Interface (CLI) while still having the features of other money management applications.
| Version | As a ... | I want to ... | So that I can ... |
|---|---|---|---|
| v1.0 | new user | see usage instructions | refer to them when I forget how to use the application |
| v1.0 | student planning to travel | know the currency exchange rates | better plan out my budget |
| v1.0 | user | create accounts for different currencies | |
| v1.0 | user | top up my account | have sufficient balance in the app |
| v1.0 | user | withdraw money from my accounts | I can spend it as cash |
| v1.0 | user | delete accounts I am no longer using | |
| v1.0 | student planning to travel | quickly exchange my money for local currency | spend in different currencies |
| v2.0 | user | view my previously saved accounts | avoid having to key in the same information every time |
| v2.0 | user | add descriptions to my transactions | categorise and track my spending and deposits |
| v2.0 | user | view my previous transactions in reverse chronological order | view my most recent transactions more easily |
| v2.0 | user | jump to a specific date | view transactions on that date |
| v2.0 | user | view transactions with a specific description | view how much I spend on specific categories or items |
- Should work on any mainstream OS as long as it has Java
11or above installed. - Should be able to hold up to 100 transactions without sluggishness in performance.
- A user that is able to type quickly should be able to accomplish most of the tasks faster than using a GUI equivalent with a mouse.
- Mainstream OS: Windows, Linux, Unix, OS-X
- The API Key for retrieving exchange rates is stored in the
src/main/java/com/moneymoover/api/ExchangeRates.javafile as theAPP_IDproperty. - If you wish to use your own API Key, you will need to go to "https://openexchangerates.org/signup/free" and sign up
for a free account, then replace the
APP_IDin theExchangeRates.javafile with your new key.



















