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 TeaandGreen Tea -
find n/Tea Milk Coke
Returns any drink havingTea,Milk, orCokein 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
ReturnsCokeandGreen Teawhich 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
listinto 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
Logiccomponent. -
Binds itself to some data in the
Modelso that the UI can auto-update when data in theModelchange. -
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
UniqueBatchListbyBatchDateusing a Custom Comparator.-
Pros:
-
Makes implementation of methods such as
addBatch,updateBatchTransaction,getEarliestBatchDate,getOldestBatchDatemuch easier asBatchobjects are already indateorder. -
Easy to modify, allowing users to sort batches based on
quantityby 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
getEarliestBatchDatewill have to be edited as they depend on theUniqueBatchListbeing in date-sorted order.
-
-
-
Alternative: Loop through all batches in the
UniqueBatchListfor all methods.-
Pros: When the
UniqueBatchListis sorted differently, methods do not have to be rewritten. -
Cons: May have time performance issues if there are many batches.
-