PROJECT: IchiFund


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, and Ui infrastructure for transactions.

    • Functionality: Provides the foundation on which features related to transactions, such as add, filter, edit and delete, 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. The add 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 and Logic, TransactionContext for Logic to easily access information about the current filter used in the list of transactions. Moving forward, this can be generalized to a Context component that stores read-only information about the state of Model that is vital to the function of Logic.

  • 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:

    • 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:

      • Reported bugs and suggestions for other teams in the class (examples: 196, 197, 198, 200, 201)

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:

addtx1

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:

addtx2

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:

addtx1

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:

addtx3

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:

TransactionClassDiagram
Figure 1. Class Diagram from Transactions Model
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:

TransactionContextOodm
Figure 2. Conceptual Class Diagram of 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 Transaction only has one Category (current choice)

Pros: Simple to implement. No overlaps in apportionment of expenditure to categories

Cons: Less flexibility for the user to classify transactions

Each Transaction can have more than one Category

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 TransactionType (current choice)

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 Transaction interface in the long run

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:

FilterTransactionSequenceDiagram
Figure 3. Sequence Diagram for 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:

AddTransactionActivityDiagram
Figure 4. Activity Diagram for Optional Arguments in 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

Day

Never

Current day of month from system time

Month

Always

Not applicable

Year

Always

Not applicable

Category

Sometimes

Uncategorised

TransactionType

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.