By: Team T14-4
Since: Sep 2019
Licence: MIT
- 1. Setting up
- 2. Design
- 3. Implementation
- 4. Documentation
- 5. Testing
- 6. Dev Ops
- Appendix A: Product Scope
- Appendix B: User Stories
- Appendix C: Use Cases
- C.1. UC01 - Get Help
- C.2. UC02 - Create an expense
- C.3. UC03 - Create a recurring expense
- C.4. UC04 - Retrieve all expenses
- C.5. UC05 - Retrieve all recurring expenses
- C.6. UC06 - Find an expense
- C.7. UC07 - Update an expense
- C.8. UC08 - Delete an expense
- C.9. UC09 - Delete a recurring expense
- C.10. UC10 - Set a budget for a specific period
- C.11. UC11 - Visualize funds left for current month
- C.12. UC12 - Notify when funds are < 50%
- C.13. UC13 - Visualize expenditure
- C.14. UC14 - Visualize expenditure breakdown by tag
- C.15. UC15 - Recall commands previously used in current session
- C.16. UC16 - Set default currency of expenses
- C.17. UC17 - Create expense with specific currency
- C.18. UC18 - Automatically convert expenses in foreign currencies to default currency
- C.1. UC01 - Get Help
- Appendix D: Non Functional Requirements
- Appendix E: Glossary
- Appendix F: Product Survey
- Appendix G: Instructions for Manual Testing
1. Setting up
Refer to the guide here.
2. Design
2.1. Architecture
The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.
The .puml files used to create diagrams in this document can be found in the diagrams folder.
Refer to the Using PlantUML guide to learn how to create and edit diagrams.
|
-
At app launch: Initializes the components in the correct sequence, and connects them up with each other.
-
At shut down: Shuts down the components and invokes cleanup method where necessary.
Commons
represents a collection of classes used by multiple other components.
The following class plays an important role at the architecture level:
-
LogsCenter
: Used by many classes to write log messages to the App’s log file.
The rest of the App consists of four components.
Each of the four components
-
Defines its API in an
interface
with the same name as the Component. -
Exposes its functionality using a
{Component Name}Manager
class.
For example, the Logic
component (see the class diagram given below) defines its API in the Logic.java
interface and exposes its functionality using the LogicManager.java
class.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete 1
.
delete 1
commandThe sections below give more details of each component.
2.2. UI component
API : Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, ExpenseListPanel
, StatusBarFooter
etc. All these, including the MainWindow
, inherit from the abstract UiPart
class.
The UI
component uses JavaFx UI framework. The layout of these UI parts are defined in matching .fxml
files that are in the src/main/resources/view
folder. For example, the layout of the MainWindow
is specified in MainWindow.fxml
The UI
component,
-
Executes user commands using the
Logic
component. -
Listens for changes to
Model
data so that the UI can be updated with the modified data.
2.3. Logic component
API :
Logic.java
-
Logic
uses theMymParser
class to parse the user command. -
This results in a
Command
object which is executed by theLogicManager
. -
The command execution can affect the
Model
(e.g. adding an expense). -
The result of the command execution is encapsulated as a
CommandResult
object which is passed back to theUi
. -
In addition, the
CommandResult
object can also instruct theUi
to perform certain actions, such as displaying help to the user.
Given below is the Sequence Diagram for interactions within the Logic
component for the execute("delete 1")
API call.
delete 1
Command
The lifeline for DeleteCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
|
2.4. Model component
API : Model.java
The Model
,
-
stores a
UserPref
object that represents the user’s preferences. -
stores a
BudgetList
object that represents the user’s budgets. -
stores an
ExpenseList
object that represents the user’s untagged expenses. -
stores an
ExchangeData
object that represents the foreign exchange rates for conversion of currencies. -
exposes an unmodifiable
ObservableList<Expense>
and an unmodifiableObservableList<Budget>
that can be 'observed' e.g. the UI can be bound to either list so that the UI automatically updates when the data in the list change.
2.5. Storage component
API : Storage.java
The Storage
component,
-
can save
UserPref
objects in json format and read it back. -
can save
Budget
objects in json format and read it back. -
can save
Expense
objects in json format and read it back. -
can read
Exchange
objects in json format.
2.6. Common classes
Classes used by multiple components are in the seedu.addressbook.commons
package.
3. Implementation
This section describes some noteworthy details on how certain features are implemented.
3.1. Budget Feature
3.1.1. Overview
The Budget feature allows users to track their expenses in relation to the budget set. Expenses created by the user after a budget is set and falls into a budget period will automatically be added into that budget.
The feature allows the user to view a list of all the budgets created in the app. From the list of budgets, users may view any specific budget showing all the expenses allocated into the budget, along with the amount left in the budget. Users may add, delete, edit a budget as well as the expenses inside the budget.
3.1.2. Implementation
The BudgetList
stores all the budgets created in the App. To facilitate the adding, deleting and editing of budgets, the BudgetList provides a
few operations such as:
BudgetList#addBudget(budget)
- Add a new budget into the list of budgets in the budget list.
BudgetList#setBudget(budget, editedBudget)
- Edit a current existing budget to a different budget
BudgetList#removeBudget(budget)
- Remove a specified budget
Given below is an activity diagram to show how a budget is added.
Given below is an activity diagram to show how an expense is added after the implementation of budget.
Given below is a class diagram of a Budget.
Notice that the budget consists of 2 Amounts and 2 Dates.
The 2 Amounts refer to the Budget Amount set by the user and the Budget Amount
currently left after deducting all expenses in the budget.
The 2 Dates refer to the Start Date of the Budget and the End Date of the budget. All expenses added after the budget is created,
and fall within this 2 dates, will be automatically added into the budget.
Given below is an example of a object diagram of a newly created Budget.
The Budget consists of an ExpenseList which holds all expenses added into the Budget.
3.1.3. Design Consideration
There were 2 main design choices we had to choose from for the implementation of the Budget Feature.
Aspect: A single source of truth
The model consists of an expense list and a budget list.
-
Alternative 1: Have a master expense list to store all expenses created and a budget list that consist of an internal expense list that stores copies of the expenses from master expense list that fall into the budget. In this option, commands that affect expenses, will require an update in the master expense list and the expense lists inside budgets affected.
-
Pros: Easy to implement, easy to keep track of a overall expenses.
-
Cons: Multiple objects of the same expense. An update to an expense in the overall expense list will require a same update to the same expense located in the budget. May result in bugs when commands affect expenses.
-
-
Alternative 2: Have a default expense list that stores only expenses that do not fall into a budget, and a budget list that consist of an internal expense list that stores the expenses that fall into a budget when the expense is added or edited. In this option, there is only 1 copy of any expense created by the user. Any edit or delete of an expense affects directly to the original expense object.
-
Pros: Achieve a single source of truth. Does not introduce possible bugs that may be present if there were multiple copies of the same expense.
-
Cons: More complex to implement. In order to view all expenses in the app, the program will have to loop through the default expense list and the expense lists of every single budget.
-
Alternative 2 was chosen. Reason is because a single source of truth would eliminate duplicate entries of the same data. This would also reduce the possibility of bugs that may come with duplicate entries.
3.2. AutoComplete Feature
3.2.1. Implementation
Autocomplete is facilitated by several parts.
The logic part is implemented through java.seedu.address.logic.search
package which contains AutoComplete
and
BinarySearch
.
The model is constructed through java.seedu.address.model.autocomplete
which contains AutoCompleteModel
and Word
.
The Ui part is implemented through java.seedu.address.ui.QueryCard
on top of CommandBox
.
Given below is an example usage scenario and how the autocomplete mechanism behaves at each step. (p.s. details are omitted)
Step 1. The user launches MYMorise and the user will be prompted to enter a command as shown in the command box.
Step 2. User enter a
and the listener is triggered. Then AutoComplete#initAc()
and
AutoComplete#getSuggestions()
is invoked.
Step 3. initAc()
calls AutoComplete#readWordsFromFile()
which reads the vocabulary from our local dictionary to get
the database and then construct an AutocompleteModel
with the vocabulary read.
Step 4. getSuggestions(input)
calls AutocompleteModel#allMatches()
which utilises the improved version of binary
search algorithm BinarySearch
. The algorithm will return the first and last index of potential matched results.
Since the result is based on a pre-order for sorting, all the words inside this range will be the qualified ones.
Step 5. The listview of QueryCard
will be updated based on the words and weights given and attached to the
TextField
.
The following sequence diagram shows how autocomplete operation works:
The following activity diagram summarizes what happens when a user enter something new.
3.2.2. Design Considerations
Aspect: How Autocomplete works
In terms of the retrieving suggestion list, an enhanced binary search algorithm is used. Since a word (which represents a autocomplete term) has a name and weight, the default "vocabulary" will be first sort based on weight and for same weight, sort alphanumerically.
In terms of replacing the target term to the TextField
, 2 approaches are proposed
-
Approach 1 (current choice): 2 listeners were added. 1) 1st listener for
TextFormatter
, this is especially utilised to retrieving the updated cursor position, which is where it outperforms. 2) 2nd listener forTextInputControl
to detect the text change ofTextField
. Then combined with previously returned caret position, we can replace the corresponding position with target term (the one user selected) -
Approach 2. 1 listener for
caretProperty
is added to detect the change of position of caret (i.e., cursor). This approach is simpler with regard to logic but more complicated during implementation. Since caret position change does not necessarily mean textField change, therefore extra check would be required, also resulting in potential inaccuracy.
In terms of user interaction, different listeners are added for different valid actions (e.g. press TAB, ENTER and navigate using UP and DOWN) to make user benefit by typing faster.
3.3. History Feature
3.3.1. Implementation
History is mainly facilitated by CommandHistory
with HistoryPointer
. When the app starts, a CommandHistory
instance is created and any command executed (no matter valid or not) will be saved to a list of history commands.
And when the user calls the history
, the overall history list will display on the resultDisplayPanel
. And when
user press F3 and F4 to navigate through the history list, the HistoryPointer
will point to corresponding
history.
Similar to Section 3.1, the history displayed on textField
is facilitated by KeyEventListener
. When the keyinput
event of F3 or F4 is triggered, it will navigate to previous input and next input correspondingly.
The following class diagram illustrates the interaction between historyCommand
and other parts:
The following sequence diagram illustrates the flow of how history commands works:
3.4. Currency Conversion
3.4.1. Implementation
The Currency conversion is achieved by having a default base currency that all expenses and budgets use if one is not specified. The expenses that are stored with a different currency can be converted from the base currency and back. Every time a currency is specified, the present day exchange rate is stored with the expense. This is to ensure that the expense value is timeless.
This was implemented in the java.seedu.address.model.exchangedata
package, which contains ExchangeDataSingleton
, ExchangeData
, and Rates
. These classes facilitate retrieval of exchange rates that will be requested from various parts of the app, namely Expense
and Budget
.
Step 1
The foreign currency exchange rates are downloaded for the app to use from ExchangeRatesAPI.io using their endpoint https://api.exchangeratesapi.io/latest?base=SGD
. The endpoint returns the data in JSON format, which works well with the existing JSON based storage used for Expense
and Budget
. This was implemented in the java.seedu.address.commons.utils
package containing HttpsClientUtil
which facilitates the Asynchronous calls to the endpoint to update the local copy of the foreign currency exchange rates upon app startup.
Step 2 The JSON response is persisted on disk. A default data-set of exchange rates will be generated at runtime (but not stored) in the case of unstable or no internet access if one is not yet present. If one was present however a more recent one could not be downloaded, the existing data will be reused.
Step 3
If the exchange data is present as a JSON, it will first be loaded into its JSON reflection class JsonAdaptedExchangeData
which depends on JsonAdaptedRates
. These classes assist in the conversions of the JSON to the Model Class ExchangeData
.
Presently, ExchangeData is also stored in the StorageManager which was intended to be used to store multiple instances of ExchangeData to load historical exchange rates when the user does an edit, however this proved to be infeasible to implement within the course of the project.
Step 4
The ExchangeDataSingleton
is updated with the new ExchangeData
using the ExchangeDataSingleton#updateInstance
. The reason for using the Singleton pattern in this case was to ensure that one and only one instance of ExchangeData
is being referenced to retrieve data at any point in time. Since it is also required to be accessed by Expense
and Budget
.
Step 5
Conversions are done in Expense#getConvertedAmount
for conversion back into the base currency (SGD) and Expense#getConvertedAmount(Currency currency)
for conversions to any other currency. As most transactions in the app that require the conversion of currency involve an expense (including recomputing amountLeft
of Budget
), the computation is done in the expense. The following are the instance where the currency is converted:
-
Whenever an expense is displayed on the
ExpenseCard
orCommandResult
, its converted value will be computed and displayed together with its conversion rate and original amount.
The following sequence diagram shows how currency conversion works:
3.4.2. Design Consideration
There were 3 main design choices we had to choose from for the implementation of the Currency Conversion Feature.
-
Alternative 1: Do not store currency rates when expenses are added with a selected currency and simply store the currency.
-
Pros: Easy to implement, recompute the amount of the expense based on the present day currency exchange rate.
-
Cons: If there was a crash in any currency, the expense amount will no longer be timeless. For instance, if an expense of of 10 MYR was stored today and was converted to 3 SGD (converted at 3.33), then the exchange rate became 2.0 the following day, the budget would reflect the amount left wrongly when it was recomputed the next day.
-
-
Alternative 2: Persist all the exchange rates to file every time the app is launched to ensure that the user’s expenses are computed based on the exchange rate that was on that specific day. The specific exchange rate used is not stored in the expense itself.
-
Pros: Achieve timeless expense which will provide the most accurate values when computing the budget amount left.
-
Cons: Slightly harder to implement as there are multiple sources for exchange rate data based on dates. This will also bloat the amount of space requirement of the app as time persists.
-
-
Alternative 3: Store the specific exchange rate used together with the expense whenever it is added, update the exchange rates daily and only persist the latest rates.
-
Pros: Achieve timeless expense which will provide the most accurate values when computing the budget amount left, without the need to store historical exchange rates. Reduced space used and single source of truth for computing exchange rates.
-
Cons: Expenses added in the past that have their currencies changed will not be able to use the exchange rate of that specific day.
-
Alternative 3 was chosen as it was a balance between the cons across all 3 considerations, and the timelessness of an expense carries more weight than the unlikely event that the user would need to alter the currency of a past expense.
3.5. Logging
We are using java.util.logging
package for logging. The LogsCenter
class is used to manage the logging levels and logging destinations.
-
The logging level can be controlled using the
logLevel
setting in the configuration file (See Section 3.6, “Configuration”) -
The
Logger
for a class can be obtained usingLogsCenter.getLogger(Class)
which will log messages according to the specified logging level -
Currently log messages are output through:
Console
and to a.log
file.
Logging Levels
-
SEVERE
: Critical problem detected which may possibly cause the termination of the application -
WARNING
: Can continue, but with caution -
INFO
: Information showing the noteworthy actions by the App -
FINE
: Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size
3.6. Configuration
Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json
).
4. Documentation
Refer to the guide here.
5. Testing
Refer to the guide here.
6. Dev Ops
Refer to the guide here.
Appendix A: Product Scope
Target user profile:
-
has a need to manage expenses,
-
requires categorization of expenses,
-
prefer desktop apps,
-
prefers CLI type interfaces.
Value proposition:
-
manage expenses faster than a typical mouse/GUI driven app.
-
easily view spending metrics.
Appendix B: User Stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
Basic Functionality |
|||
|
new user |
see usage instructions |
refer to instructions when I forget how to use the App |
|
user |
create an expense |
|
|
user |
create an expense with a tag |
identify my expenses by tags |
|
user |
retrieve all expenses |
review my spending |
|
user |
find an expense name |
locate a specific expense without having to go through the entire list |
|
user |
edit an expense |
change the expense amount, date or tag |
|
user |
delete an expense |
|
|
user |
terminate a recurring expense |
|
|
user |
retrieve all expenses for today |
review my spending for the day |
|
user |
create a recurring expense |
don’t have to input recurring expenses every time |
|
user |
retrieve list of all recurring expenses |
view all my recurring expenses |
|
user |
retrieve all expenses for the week |
review my spending for the week |
|
user |
retrieve all expenses for the month |
review my spending for the month |
|
user |
retrieve all expenses for the year |
review my spending for the year |
Budgeting |
|||
|
user |
set a budget for a period |
track my expenses according to the budget amount |
|
user |
delete a budget |
remove a budget that is not needed anymore |
|
user |
edit a budget |
change my budget details |
|
user |
view a list of my budgets |
see what budgets i have already set |
|
user |
view a budget |
know my expenses and how much I have left to spend in the budget |
|
user |
be notified every time I add an expense if I have less than 50% of my budget left |
notify myself that i may be spending too much according to my budget |
UI |
|||
|
user |
view in a pie chart expenditure breakdown by tag |
view my expenses easily with visual aid |
|
user |
view in a pie chart how much of my budget is spent/available for the current month |
view how much of my budget is left |
|
user |
view in a bar chart my expenditure |
visualise my spending habits |
Inputs |
|||
|
user |
recall commands previously used in session |
improve my productivity |
|
user |
command autocomplete suggestions |
improve my productivity |
Multi-Currency |
|||
|
user |
set my default currency for tracking |
|
|
user |
store expenses in a specific currency |
track expenses in a different currency |
|
user |
automatically convert the expense to my default currency |
track expenses of different currency in terms of my default currency |
{More may be added}
Appendix C: Use Cases
Note: For all use cases below, the System is MYMorise(MYM)
, the Actor is the user
and the Precondition is
MYMorise is running
, unless specified otherwise).
Inputs specified in a square bracket i.e [input] are optional inputs from the user.
C.1. UC01 - Get Help
Guarantees:
-
The list of all commands will be shown.
MSS
-
User requests for help.
-
MYM responds with the list of all commands.
Use case ends.
C.2. UC02 - Create an expense
Guarantees:
-
A new expense will be added into MYM if valid data were specified.
MSS
-
User requests to add an expense specifying data.
-
MYM creates and stores the expense with the specified data.
Use case ends.
Extensions
-
1a. MYM detects an error in entered data.
-
1a1. MYM informs the user what data was invalid.
Use case ends.
-
C.3. UC03 - Create a recurring expense
Guarantees:
-
A new recurring expense with will be added into MYM if valid data were specified.
-
A single expense with will be added into MYM if valid data were specified.
MSS
-
User requests to add a recurring expense specifying data.
-
MYM creates and stores the expense with the specified data .
Use case ends.
Extensions
-
1a. MYM detects an error in entered data.
-
1a1. MYM informs the user what data was invalid.
Use case ends.
-
C.4. UC04 - Retrieve all expenses
Preconditions: MYMorise is running, there is at least 1 expense stored. Guarantees:
-
A list of all expenses is shown.
MSS
-
User requests to see all expenses.
-
MYM shows all expenses.
Use case ends.
Extensions
-
1a. User requests to see all expenses made today.
-
1a1. MYM shows a list of all expenses made today.
Use case ends.
-
-
1b. User requests to see all expenses made for the current week.
-
1b1. MYM shows a list of all expenses made for the current week.
Use case ends.
-
-
1c. User requests to see all expenses made for the current month.
-
1c1. MYM shows a list of all expenses made for the current month.
Use case ends.
-
-
1d. User requests to see all expenses made for the specified date range.
-
1d1. MYM shows a list of all expenses made for the the specified date range.
Use case ends.
-
C.5. UC05 - Retrieve all recurring expenses
Preconditions: MYMorise is running, there is at least 1 recurring expense stored.
Guarantees:
-
A list of all recurring expenses is shown.
MSS
-
User requests to see for all recurring expenses.
-
MYM shows a list of all expenses made for the day.
Use case ends.
C.6. UC06 - Find an expense
Preconditions: MYMorise is running, there is at least 1 recurring expense stored.
Guarantees:
-
A list of all expenses containing the specified keyword if any were found
MSS
-
User requests for all expenses containing a keyword.
-
MYM shows a list of all expenses containing the keyword.
Use case ends.
Extensions
-
1a. No expenses contain the keyword specified.
-
1a1. MYM informs user that no matching expenses were found.
Use case ends.
-
C.7. UC07 - Update an expense
Preconditions: MYMorise is running, there is at least 1 expense stored.
Guarantees:
-
The expense selected for editing will be updated with the new data.
MSS
-
User reviews the list of expenses.
-
User requests to update an expense from the list and provides the new data.
-
MYM updates the selected expense with the new data.
Use case ends.
Extensions
-
2a. User decides not to edit the expense.
Use case ends.
-
2b. User could not locate the expense to be edited.
Use case resumes at step 1.
-
3a. MYM detects an error in entered data.
-
3a1. MYM informs the user what data was invalid.
Use case resumes at step 2.
-
C.8. UC08 - Delete an expense
Preconditions: MYMorise is running, there is at least 1 expense stored.
Guarantees:
-
The expense specified for deletion will be deleted.
MSS
-
User reviews the list of expenses.
-
User requests to delete the expense with a specific index from the list.
-
MYM deletes the expense with the specified index.
Use case ends.
Extensions
-
2a. User decides not to delete the expense.
Use case ends.
-
2b. User could not locate the expense to be deleted.
Use case resumes at step 1.
-
3a. MYM detects an error in entered data.
-
3a1. MYM informs the user what data was invalid.
Use case resumes at step 2.
-
C.9. UC09 - Delete a recurring expense
Preconditions: MYMorise is running, there is at least 1 recurring expense stored.
Guarantees:
-
The recurring expense specified for deletion will be deleted.
MSS
-
User reviews the list of recurring expenses.
-
User requests to delete the recurring expense with a specific index from the list.
-
MYM deletes the expense with the specified index.
Use case ends.
Extensions
-
2a. User decides not to delete the recurring expense.
Use case ends.
-
3a. MYM detects an error in entered data.
-
3a1. MYM informs the user what data was invalid.
Use case resumes at step 2.
-
C.10. UC10 - Set a budget for a specific period
Guarantees:
-
The budget will be set to a specified amount for a specific period.
MSS
-
User requests to set the budget, specifying the amount, the start date and the end date of the period.
-
MYM sets the budget for the amount and period specified.
Use case ends.
Extensions
-
1a. MYM detects an error in the entered data.
-
1a1. MYM requests for the correct data.
-
1a2. User enters new data.
-
Steps 1a1-1a2 are repeated until the data are correct.
-
Use case resumes from step 2.
-
-
1b. MYM detects a budget period clash.
-
1b1. MYM requests for different period dates.
-
1b2. User enters new data.
-
Steps 1b1-1b2 are repeated until the dates do not clash with existing budget periods.
-
Use case resumes from step 2.
-
C.11. UC11 - Visualize funds left for current month
Preconditions: MYMorise is running, A budget should have been set (UC10)
Guarantees:
-
Visualization of funds left for current month will be updated.
MSS
-
User creates an expense (UC02) OR User updates an expense (UC07) OR User deletes an expense (UC08)
-
MYM updates the visualization of funds left for the month.
Use case ends.
C.12. UC12 - Notify when funds are < 50%
Preconditions: MYMorise is running, A budget should have been set (UC10)
Guarantees:
-
The user is notified that funds are low, if resulting budget balance is < 50%.
MSS
-
Use case ends.
Extensions
-
1a. Resulting budget balance is < 50%
-
1a1. MYM informs the user the new budget balance and that funds are running low.
Use case ends.
-
C.13. UC13 - Visualize expenditure
Guarantees:
-
Visualisation of expenditure will be shown if there is sufficient data.
MSS
-
MYM updates visualization based on expenses requested in Step 1.
Use case ends.
Extensions
-
2a. There are no expenditures.
-
2a1. MYM informs User that there is not enough data to visualise expenditure breakdown by tag.
Use case ends.
-
C.14. UC14 - Visualize expenditure breakdown by tag
Guarantees:
-
Breakdown by tag visualisation will be shown if there is sufficient data.
MSS
-
User creates an expense (UC02) OR User updates an expense (UC07) OR User deletes an expense (UC08)
-
MYM updates the breakdown of expenditure by tag visualisation.
Use case ends.
Extensions
-
2a. There are no expenditures.
-
2a1. MYM informs User that there is not enough data to visualise expenditure breakdown by tag.
Use case ends.
-
C.15. UC15 - Recall commands previously used in current session
Guarantees:
-
Commands used previously can be cycled through by the user if there are previously used commands in the current session.
MSS
-
User request for previous command.
-
Step 1 is repeated till user found the target command.
Use case ends.
Extensions
-
1a. No prior commands entered.
Use case ends.
C.16. UC16 - Set default currency of expenses
Guarantees:
-
MYMorise will convert display amounts in the specified currency, if the specified currency is valid..
MSS
-
User requests to set the default currency
-
MYM converts all expenses into the defualt currency and updates the display.
Use case ends.
Extensions
-
1a. The specified currency is not valid.
-
1a1. MYM informs the user that the currency specified is not valid.
Use case ends.
-
C.17. UC17 - Create expense with specific currency
Guarantees:
-
A new expense with the specified currency will be added into MYM if the specified data is valid.
MSS
-
User requests to create an expense specifying required data.
-
MYM creates and stores the expense with the specified data.
Use case ends.
Extensions
-
1a. MYM detects an error in entered data.
-
1a1. MYM informs the user what data was invalid.
Use case ends.
-
C.18. UC18 - Automatically convert expenses in foreign currencies to default currency
Preconditions: Preconditions: MYMorise is running, at least 1 expense stored in foreign currency
Guarantees:
-
Expense will display expense amount in both default and foreign currencies but all computations will default converted amount.
MSS
-
MYM shows list of expenses. Expenses with foreign currencies are shown together with their default currency converted amounts.
Use case ends.
{More may be added}
Appendix D: Non Functional Requirements
-
(Technical) Should work on any mainstream OS as long as it has Java
11
or above installed. -
(Capacity, Performance) Should be able to hold up to 10000 expenses without a noticeable sluggishness in performance for typical usage.
-
(Scalability) Should be able to handle expense amounts up to 1012.
-
(Process) Project should be production ready by 11th November 2019.
{More to be added}
Appendix F: Product Survey
Product Name
Author: …
Pros:
-
…
-
…
Cons:
-
…
-
…
Appendix G: Instructions for Manual Testing
Given below are instructions to test the app manually.
These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing. |
G.1. Launch and Shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder
-
Double-click the jar file
Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
-
-
Saving window preferences
-
Resize the window to an optimum size. Move the window to a different location. Close the window.
-
Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
-
{ more test cases … }
G.2. Deleting an expense
-
Deleting an expense while all expenses are listed
-
Prerequisites: List all expenses using the
list
command. Multiple expenses in the list. -
Test case:
delete 1
Expected: First expense is deleted from the list. Details of the deleted expense shown in the status message. Timestamp in the status bar is updated. -
Test case:
delete 0
Expected: No expense is deleted. Error details shown in the status message. Status bar remains the same. -
Other incorrect delete commands to try:
delete
,delete x
(where x is larger than the list size) {give more}
Expected: Similar to previous.
-
{ more test cases … }
G.3. Saving data
-
Dealing with missing/corrupted data files
-
{explain how to simulate a missing/corrupted file and the expected behavior}
-
{ more test cases … }