Overview
This portfolio documents my contributions towards the project, IchiFund, which is part of an introductory software engineering module, CS2103T. My team of 5 was tasked to morph or enhance an existing address book software. Our resulting product, IchiFund, is a desktop finance management application for students to manage transactions, budgets and loans. It is optimised for students that prefer using a CLI. My role was to develop the Transactions component of the application.
Summary of contributions
-
Major enhancement: Developed the
Model
,Logic
,Storage
, andUi
infrastructure for transactions.-
Functionality: Provides the foundation on which features related to transactions, such as
add
,filter
,edit
anddelete
, are built. -
Justification: The ability to easily create, read, update and delete transactions on the GUI of the application depends on properly establishing the infrastructure for transaction.
-
Highlights: This enhancement demonstrates a deep understanding of the underlying MVC design pattern of the existing code. The modifications to the GUI (addition of a filter title and reorganizing information in cells) also demonstrate an understanding of how to work with JavaFX.
-
-
Major enhancement: Added the ability to add and filter transactions with optional arguments based on the current filter (enhancement with greatest depth)
-
Functionality: The
filter
command changes the existing filter for the list of transactions. Theadd
command adds a transaction to the list of transactions. If left unfilled, the values taken by the optional arguments are inferred from the current filter. -
Justification: The add and filter features on their own are basic functionalities of the software. The implementation of optional arguments filled in based on the current filter allows user to provide minimal information to add a transaction, which significantly improves user experience.
-
Highlights: This enhancement required the implementation of an intermediate between
Model
andLogic
,TransactionContext
forLogic
to easily access information about the current filter used in the list of transactions. Moving forward, this can be generalized to aContext
component that stores read-only information about the state ofModel
that is vital to the function ofLogic
.
-
-
Minor enhancement: Added the ability to edit and delete transactions (PR #175)
-
Code contributed: Click here to view the code I have contributed.
-
Other contributions:
-
Project management:
-
Managed pull requests (PRs), issue tracker and project milestones
-
Refactored existing code of Address Book 3 to IchiFund (PR #252)
-
-
Enhancements to existing features:
-
Restructured architecture of code to enable separate parsing for features in different tabs using the same command line (PR #137)
-
Modified sample data for initialization of IchiFund (PR #239)
-
Modified documentation on existing features to be more reader-friendly
-
-
Community:
-
Contributions to the User Guide
Given below is a sample of what I have contributed to the User Guide. It showcases my ability to write documentation targeting end-users. |
Creating transaction: add
Format: add de/DESCRIPTION a/AMOUNT [c/CATEGORY] [d/DAY] [m/MONTH] [y/YEAR] [ty/TRANSACTION_TYPE]
As painful as it is to remind yourself each time you part with your money, it is essential to meticulously
record your transactions. add
eases this process.
Imagine you are browsing your transactions under the category of "Transportation" in November. Your GUI may look like this:
Let’s say you remember that spent $12.31 on lunch on 31 October 2019.
If you want to record this transaction under the category "FOOD", you can enter the full
command add de/Lunch a/12.31 c/food d/31 m/10 y/2019 ty/exp
. The application now looks like this:
Here, IchiFund automatically changes the filter for you, so that you can review the addition you made. This makes it convenient if you want to edit your transactions, as detailed in [edittx]
Also, note that the transaction appears at the top of the list. This is because we automatically sort your transactions by date, followed by category, so that you can systematically look through your transactions.
When specifying whether a transaction is an expenditure item or an income item, use the arguments
ty/exp or ty/in respectively, similar to how would do so in Filtering Transactions
|
Optional arguments
You may find the command used earlier too cumbersome to type. If so, you can leave out some of the optional arguments. To illustrate this, let’s return to the earlier scenario:
Let’s say it is 1 November 2019 today. You have just spent another $10.00 hiring a cab to go to the hospital,
and want to record this transaction under the category of "Transportation". You can simply enter
the command add a/10 de/Cab to hospital
, and obtain the following result:
Here, as the month, year, and category arguments are left empty, IchiFund fills it in according to the filter title. The day argument is taken to be the current day of the month, according to the system date. IchiFund also assumes that most transactions are expenditure items, and uses that as a default value.
The following table summarizes the default values that optional arguments take if left unspecified.
Argument | Default values |
---|---|
Day |
According to system time and date. |
Month |
According to the filter |
Year |
According to the filter |
Category |
According to the filter, if applicable, or "Uncategorised" otherwise. |
Type |
According to the filter, if applicable, or "exp" otherwise. |
The default value of the day argument is the current day of month in the system time. Hence, to utilise this feature to its fullest, you are recommended to add transactions on the day it occurs. |
For more sample user guide contributions, refer to the Navigation and Transactions sections of the User Guide. |
Contributions to the Developer Guide
Given below is a sample of what I have contributed to the Developer Guide. It showcases my ability to write technical documentation and the technical depth of my contributions to the project. |
Overview of the Transactions Model
Implementation
The transactions in IchiFund are represented using the Transaction
class. While users are able to edit transactions,
objects of the Transaction
class are immutable in the internal structure. The following class diagram summarizes
the details of the Transaction
class:
We differentiate income items from expenditure items using the TransactionType field, which accepts
two unique string values, "in" for income and "exp" for expenditure in the constructor.
|
In addition, the list of transactions is subject to a filter created by an immutable TransactionContext
.
TransactionContext
keeps track of the Month
, Year
, Category
(optional) and TransactionType
(optional) in the current filter.
Naturally, this implies that a filter for Month
and Year
is always applied to the list of transactions.
The TransactionContext
is also used to fill in optional fields that are not specified by the user when adding transactions.
We summarise the role of the TransactionContext
class in the following conceptual class diagram:
TransactionContext
Design Considerations
We encountered two major decisions when implementing our model for transactions. Here, we discuss the alternatives we considered, as well as the rationale for the current implementation.
Multiplicity of Category
Currently, each Transaction
object can have only one Category
object associated to it. In the problem domain, it is
also natural to think of transactions being associated with multiple categories. The table below summarizes the pros and cons of each choice.
Description of Implementation | Pros and Cons |
---|---|
Each |
Pros: Simple to implement. No overlaps in apportionment of expenditure to categories Cons: Less flexibility for the user to classify transactions |
Each |
Pros: More flexibility for the user to classify transactions Cons: Overlaps in apportionment of expenditure to categories |
While both implementations are visible, we chose to only have one Category
associated to each
Transaction
as the absence of overlaps in expenditure allows us to eventually implement a clean visual
breakdown of expenditure by category in the future.
Developers, however, are welcome to implement an additional Tags
field for Transaction
objects, to allow
for multiple associations.
Differentiating between Income and Expenditure
Currently, we differentiate income items from expenditure items using the TransactionType
field in
Transaction
. We considered the natural alternative of using inheritance as well.
Description of Implementation | Pros and Cons |
---|---|
Using the field |
Pros: Fits the parsing methods used in the current architecture well Cons: More tedious to code for different behaviours for income and expenditure items in the future |
Using inheritance |
Pros: Allows for polymorphism of methods from a Cons: Requires either the use of separate commands, or asymmetry in the parsing of command arguments |
While it was a tough decision, we eventually decided to use TransactionType
for differentiation as we valued maintaining the
symmetry in the implementation of parsing in our current architecture, and we did not want to use separate commands for adding transactions.
Furthermore, we did not envision further use of polymorphism in future developments. Hence the benefit of using inheritance becomes
very limited.
Filtering Transactions
The filter transactions feature allows the user to change the filter for the list of transactions.
As described in [Design-Logic], this feature is facilitated by TransactionFeatureParser
, FilterTransactionCommandParser
, and FilterTransactionCommand
.
The arguments supported by this feature are: Month
, Year
, Category
and TransactionType
. All of these arguments are
optional, but the user has to input at least one argument for the command to be valid.
Implementation
We omit the details of parsing facilitated by IchiFundParser
, TransactionFeatureParser
and FilterTransactionCommandParser
. Instead,
we immediately delve into the details of FilterTransactionCommand#execute
.
As prefaced in Overview of the Transactions Model, the filter
command interacts with TransactionContext
to filter the list of
transactions exposed to the UI component.
Following the creation of FilterTransactionCommand
, the execution of the command results
in the following chain of events:
Step 1: FilterTransactionCommand
retrieves the current TransactionContext
from the model.
Step 2: FilterTransactionCommand
creates a new TransactionContext
, facilitated by TransactionContextBuilder
Step 3: FilterTransactionCommand
sets the new context in model as the newly created TransactionContext
.
Step 4: ModelManager
retrieves a Predicate<Transaction>
from the new TransactionContext
.
Step 5: ModelManager
filters the list of transactions using the Predicate<Transaction>
.
The above sequence of events is shown in greater detail in the following sequence diagram:
FilterTransactionCommand
Adding Transactions
The add transaction feature allows the user to add a transaction into IchiFund. It further ensures that the current
filter of the list of transactions is changed to allow the user to view the transaction.
As described in [Design-Logic], this feature is facilitated by TransactionFeatureParser
, AddTransactionCommandParser
, and AddTransactionCommand
.
The arguments supported by this feature are: Description
, Amount
, Category
, Day
, Month
, Year
and TransactionType
.
Of these arguments, only Description
and Amount
are mandatory.
Implementation
We omit the details of parsing facilitated by IchiFundParser
, TransactionFeatureParser
and AddTransactionCommandParser
. Instead,
we immediately delve into the details of the AddTransactionCommand#execute
.
As prefaced in Overview of the Transactions Model, AddTransactionCommand
interacts with TransactionContext
to generate
a Transaction
to be added to the model.
The execution of an AddTransactionCommand
results in the following sequence of events:
Step 1: AddTransactionCommand
retrieves the current TransactionContext
from the model.
Step 2: AddTransactionCommand
generates a new Transaction
based on the arguments and TransactionContext
Step 3: AddTransactionCommand
adds the new Transaction
to the model.
Step 4: ModelManager
automatically sorts the list of transactions.
Step 5: AddTransactionCommand
calls model to execute updateTransactionContext
Step 6: ModelManager
updates TransactionContext
such that the new Transaction
is shown.
To create a new Transaction
, AddTransactionCommand
fills in the missing arguments using
values obtained from TransactionContext
, or default values. This is illustrated in the activity diagram below:
AddTransactionCommand
The above activity diagram shows the decision flow for a general optional argument. However, some optional
arguments are never stored in TransactionContext
, and some are always stored. The
following table describes the particular details for each optional argument.
Argument | Stored in TransactionContext ? |
Default value |
---|---|---|
|
Never |
Current day of month from system time |
|
Always |
Not applicable |
|
Always |
Not applicable |
|
Sometimes |
Uncategorised |
|
Sometimes |
Expenditure |
After adding the Transaction
, a new TransactionContext
is created such that the new Transaction
is displayed
on the list of transactions. Specifically, the Month
and Year
filters are set to the Month
and Year
of the
new Transaction
respectively, and the Category
and TransactionType
filters are removed if necessary.
Design Considerations
In implementing the add
and filter
commands, we had to decide on the underlying data structure for the list of
transactions. Currently, we store all transactions in a single iterable list. Given the use of a mandatory
month and year filter, a natural alternative would be to store each month’s worth of transactions in a
list, and stores these lists in another list, forming a multi-level list.
Description of Implementation | Pros and Cons |
---|---|
Storing all transactions in a single list (current choice) |
Pros: Suits existing architecture of software very well, easy to implement Cons: Slow performance anticipated with large number of transactions |
Storing transactions in multi-level list |
Pros: Faster performance, more scalable Cons: May disrupt abstractions in current architecture, more time needed to implement |
Ultimately, we decided to avoid disrupting the existing architecture, and instead focus our efforts on developing more features to better address the needs of the target user profile.
However, moving forward, we recognise that the current architecture severely lacks scalability, especially given the constantly growing number of transactions we expect users to create. Hence, we eventually intend to switch to a multi-level list.
Developers who choose to change the underlying data structures should bear in mind that many other components (Repeaters, Budgets, Analytics) depend on the model of Transactions, and care must be taken to ensure that these components still work well. |
For more sample developer guide contributions, refer to the Separate Parsing and Tab Switching and Transactions sections of the User Guide. |