PROJECT: AddressBook - Level 4


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:

    • Enhancements to existing features:

      • Updated the GUI color scheme (Pull requests #155)

      • Designed the Drink I/O logo (Featured on 1st page of UG)

    • Documentation:

      • Edited User Guide for formatting and language (Pull requests #160, #170)

    • Community:

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
Command format:
find n/ KEYWORD [MORE_KEYWORDS]
find q/ QUANTITY
find d/ DATE

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]

  • The search is case insensitive. e.g coke will match Coke

  • The order of the keywords does not matter. e.g. Tea Green will match Green Tea

  • Only the drink name is searched.

  • Only full words will be matched e.g. Cok will not match Coke

  • Drinks matching at least one keyword will be returned (i.e. OR search). e.g. Tea will return Green Tea, Milk Tea

Examples:

  • find n/Tea
    Returns Milk Tea and Green Tea

  • find n/Tea Milk Coke
    Returns any drink having Tea, Milk, or Coke 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

  • Only numbers are allowed in the Quantity field

Examples:

  • find q/400
    Returns Coke and Green 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

  • Date must be in either of the following formats:

    • DD/MM/YYYY

    • D/MM/YYYY

  • Date must be an existing date in the calendar

    • i.e. 30/02/2018 is a nonexistent date

  • Even if a drink has only 1 batch that meets the requirements, it will be shown

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
Command format: list

Step-by-Step Instructions
To view all drinks in Drink I/O,

  1. Enter list into the command box

  2. Press enter

  3. 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

  • Selects the drink and loads the Drink detail page and the batch list page of the drink at the specified INDEX.

  • The index refers to the numbered bullet shown in the displayed drink list.

  • The index must be a positive integer 1, 2, 3, …​

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

UiClassDiagram
Figure 1. Structure of the 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 the Model 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.

SellCommandSequenceDiagram1
Figure 2. Sequence Diagram of SellCommand to StockTakerModelManager
SellCommandSequenceDiagram2
Figure 3. Sequence Diagram of StockTakerModelManager to Batch

Design Considerations

Aspect: Facilitating the Buy and Sell Commands

  • Current Implementation: Sorting the UniqueBatchList by BatchDate using a Custom Comparator.

    • Pros:

      • Makes implementation of methods such as addBatch , updateBatchTransaction , getEarliestBatchDate , getOldestBatchDate much easier as Batch objects are already in date 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 the UniqueBatchList 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.