Overview
This project portfolio documents my role in the CS2113T module project. My main role was in handling documentation and the scheduling and tracking of tasks.
As part of the module, my teammates and I collaborated to develop a drink management application - Drink I/O. Drink I/O is targeted at small drink distribution companies and provides inventory management and financial tools. Users interact with the app using CLI, and it has a GUI created with JavaFX. This project is written in Java and has approximately 30 kLoC.
Summary of contributions
-
Major enhancement: Added Batch List and Batch Handling functionality
In drink companies, whenever drinks are imported, they are imported in batches and cartons. This enhancement simulates the situation in the real world and helps drink companies to manage their stock better.-
Functionality: Each drink has its own batches stored in a batch list. Whenever drinks are purchased, they are assigned to a batch based on date of import and stored in the batch list for that drink. Whenever drinks are sold, the stocks are automatically deducted across the batches, deducting from the batch with the earliest import date first.
-
Justification: This feature improves inventory management significantly as it ensures that drinks that were imported first into the warehouse are sold first. This reduces turnover time and wastage due to drinks expiring. This is especially applicable as drink distribution companies often have multiple batches of the same drink with different import dates in their warehouse at any time.
-
Highlights: This enhancement required in-depth knowledge of the model and the associations between the different classes to properly handle updates to the objects.
-
-
Major enhancement: Displaying of Drink Details
Added display panels to summarise and display more details about a drink allowing users to view the information they need in a organised and easy to understand manner. In drink companies, whenever drinks are imported, they are imported in batches and cartons. This enhancement simulates the situation in the real world and helps drink companies to manage their stock better.-
Functionality: Allows users to see at a glance a summary of the details of the drinks and upon selecting the relevant drink, to see all other details such as every batch in the batch list of a drink and the import date of the earliest and latest batch.
-
Justification: Applications should be easy for the user to use to be effective, so this enables users to easily retrieve more details and data in an easy to read and understand form with a single click or a single command.
-
Highlights: Required knowledge of JavaFx and FXML to construct the various panels and an understanding of event handlers to ensure that the panels remain updated when there were changes to the batches.
-
-
Major enhancement: Enhancement of Search function Enhanced the Search function allowing users to search through the inventory based on name, quantity and date.
-
Functionality: Users can search through the entire inventory list for drinks by name, drinks that have quantity less than or equal to the input, and drinks that have dates earlier than or equal to the input.
-
Justification: The main concern of small drink distribution companies when managing their inventory is how to know which drink is low on stock and requires restocking or which drink batches have been in the inventory for very long and need to be cleared before they expire. This feature allows them to get this information quickly and easily via just 1 command.
-
Highlights: Implementing this feature required in-depth knowledge of the logic and model components and the way in which they interact together.
-
-
Minor enhancement: Morphed the existing storage to store the drinks and their respective batch lists. Required knowledge of XML to wrap the batch lists in a wrapper such that they would be stored properly.
-
Code contributed: [Functional and Test code]
-
Other contributions:
Contributions to the User Guide
This section documents my contributions to the User Guide. They showcase my ability to write documentation targeting end-users. |
Searching for specific drink(s)
Finds drinks which meet specific criteria depending on the input prefix.
Summary |
Searching by drink name
You can search for specific drinks by name using this search function
Finds all drinks which names contain any of the given keywords.
Format: find n/KEYWORD [MORE_KEYWORDS]
Examples:
-
find n/Tea
ReturnsMilk Tea
andGreen Tea
-
find n/Tea Milk Coke
Returns any drink havingTea
,Milk
, orCoke
in their names
Searching by drink quantity
To find out which drinks in your drink company are in need of restocking, you can utilise this search function which will return the drinks with quantity less than or equal to the quantity input.
Finds all drinks which have quantity less than or equal to the given quantity.
Format: find q/QUANTITY
Examples:
-
find q/400
ReturnsCoke
andGreen Tea
which have a quantity less than 400
Searching by batch import date
To find out which drinks have been in the warehouse for a long period of time you can utilise this search function which will return the drinks that have batches older than or have the same date as the date input.
Find drinks which have batches that are older or have the same date as the given date.
Format find d/DATE
Examples:
-
find d/02/11/2018
Returns all drinks which have batches imported on or before 2nd November 2018 -
find d/9/11/2018
Returns all drinks which have batches imported on or before 9th November 2018
Viewing all drinks in inventory
To show the full list of drinks in the inventory list, use list
.
This is especially useful after using a find
command.
Summary |
Step-by-Step Instructions
To view all drinks in Drink I/O,
-
Enter
list
into the command box -
Press enter
-
You will see all the drinks listed in the inventory panel on the left of the interface.
Format: list
Viewing drink details
To view further details of the drink such as its batches that are not displayed on the drink card panel, you can simply click on the relevant drink card to select it or use the select command.
Selects the drink identified by the index number used in the displayed drink list.
Format: select INDEX
Contributions to the Developer Guide
Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project. |
UI component
API : Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, InventoryListPanel
, BatchListPanel
, StatusBarFooter
, DrinkDetailPane
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. -
Binds itself to some data in the
Model
so that the UI can auto-update when data in theModel
change. -
Responds to events raised from various parts of the App and updates the UI accordingly.
Inventory Management
In Drink I/O, inventory is managed in the model, through the use of Drink Objects with the attributes name
, price
, quantity
, tags
, UniqueBatchList
. In Drink I/O, drink purchases are stored in Batch
objects which are made unique by their BatchDate
attribute.
These Batch
objects contain a BatchId
, a BatchQuantity
and a BatchDate
attribute and are stored in the UniqueBatchList
of the relevant drink.
Buying a drink with buy n/DRINK_NAME q/QUANTITY
A user may enter a buy command with the above parameters to record a purchase of drinks.
The following is the sequence of steps when the user enters an buy command with specified name and quantity:
Step 1. User enters a buy command (i.e. buy
n/Coca cola
q/400
).
Step 2. The appropriate parser parses the name and quantity parameters and assigns the name
and quantity
variables to the buy
command.
Step 3. The buy command is executed, and a new Transaction
object is created with the name
, quantity
and a transactionType
variable. This Transaction
object is then passed to the StockTakerModelManager.
Step 4. In the StockTakerModelManager, recordTransaction(Transaction)
is used to record the transaction and increaseDrinkQuantity(Name, Quantity)
is called to update the change in quantity in the inventory list.
Step 5. The inventory list then passes the name
and quantity
variables down to the UniqueDrinkList
which calls the increaseQuantity(Quantity)
method in the relevant Drink
object.
Step 6. In the Drink
object, a new Batch
object is created with the name
and quantity
variables and passed to the Drink’s UniqueBatchList
through the addBatch
method.
Step 7. In the UniqueBatchList
, the Batch
that was passed down would be checked against the other Batch
objects in the list for uniqueness based on its date. If it has a unique date, a new Batch
would be created and stored in the UniqueBatchList
, else the currently existing Batch
object in the UniqueBatchList
with the same date will have its Quantity
attribute incremented by the quantity
value of the Batch
object added.
Step 8. The totalQuantity
attribute of the UniqueBatchList
is then updated by looping through the batches in the list, and is handed up to the Drink
object which updates its Quantity
attribute with the value of the totalQuantity
attribute.
Selling a drink
To facilitate sales of drinks from the stock of the company, sales of drinks from the inventory are conducted with the command sell
n/DRINK_NAME
q/QUANTITY
A user may enter a buy command with the above parameters to record a purchase of drinks.
The following is the sequence of steps when the user enters an buy command with specified name and quantity:
Step 1. User enters a sell command (i.e. sell
n/Coca cola
q/400
).
Step 2. The appropriate parser parses the name and quantity parameters and assigns the name
and quantity
variables to the sell
command.
Step 3. The sell command is executed, and a new Transaction
object is created with the name
, quantity
and a transactionType
variable. This Transaction
object is then passed to the StockTakerModelManager.
Step 4. In the StockTakerModelManager, recordTransaction(Transaction)
is used to record the transaction and decreaseQuantity(Name, Quantity)
is called to update the change in quantity in the inventory list.
Step 5. The inventory list then passes the name
and quantity
variables down to the UniqueDrinkList
which calls the decreaseQuantity(Quantity)
method in the relevant Drink
object.
Step 6. In the Drink
object, updateBatchTransaction(Quantity)
is called and the quantity
variable is passed down to the UniqueBatchList
.
Step 7. In the UniqueBatchList
, quantity
passed down will be checked against the totalQuantity
variable. If quantity
is more than totalQuantity
, a InsufficientQuantityException will be thrown which would be handled in the SellDrinkCommand
class. Else, the updateBatchTransaction
would loop through the UniqueBatchList
and decrement the quantity of the individual batches starting from the one with the oldest date.
Step 8. The totalQuantity
attribute of the UniqueBatchList
is then updated by looping through the batches in the list, and is handed up to the Drink
object which updates its Quantity
attribute with the value of the totalQuantity
attribute.
Design Considerations
Aspect: Facilitating the Buy and Sell Commands
-
Current Implementation: Sorting the
UniqueBatchList
byBatchDate
using a Custom Comparator.-
Pros:
-
Makes implementation of methods such as
addBatch
,updateBatchTransaction
,getEarliestBatchDate
,getOldestBatchDate
much easier asBatch
objects are already indate
order. -
Easy to modify, allowing users to sort batches based on
quantity
by just editing the Custom Comparator. -
Allows batches shown in the BatchListPanel to be easily ordered based on date.
-
-
Cons:
-
When users replace the Custom Comparator with another comparator, methods such as
getEarliestBatchDate
will have to be edited as they depend on theUniqueBatchList
being in date-sorted order.
-
-
-
Alternative: Loop through all batches in the
UniqueBatchList
for all methods.-
Pros: When the
UniqueBatchList
is sorted differently, methods do not have to be rewritten. -
Cons: May have time performance issues if there are many batches.
-