Welcome to my Project Portfolio. Here you can find out more about my contributions in various projects to help you better evaluate my technical and communication skills.

PROJECT: MediTabs

Introduction

MediTabs is a desktop application for managing medicine stock taking. It was created to provide pharmacist with a straightforward and efficient way to keep track of and maintain their medicine inventory. MediTabs is a brownfield project that initially started as an address book application. It was developed in a team of 4 as part of a software engineering module which spanned a total of about 13 weeks.

In this project, I was in charge of implementing the information panel feature.

Summary of contributions

  • Major enhancement: added the information panel and the sort and update commands used to manipulate information on the panel.

    • What it does: allows users to add, edit and remove information of different batches of medicine. This information is displayed in a table format for easy reference in the information panel. The panel also collates the information and provides a summary of important details such as total quantity and next expiry date. The table can also be sorted by batch number, quantity or expiry date.

    • Justification: Organizing medicine by batch allows for quicker identification of problematic batches. With each medicine having multiple batches, a way to organize the information neatly to avoid confusion for the user is needed. The information panel provides a visual interface that is simple and well structured for users to refer to when updating their inventory.

    • Highlights: A large amount of planning was done to decide what information would be useful to the user. Implementation was challenging as it not only involved changing existing commands (add and edit) but also adding functionality to every component of the architecture, namely Logic, Storage, Model and UI.

  • Minor enhancement: Enhanced the existing find command to be able to search other fields. (Pull requests: #180)

  • Code contributed: code

  • Other contributions:

    • Project management:

      • Helped to manage issue tracker for the first few weeks before individual project boards were set up: (Issues: #9 #2 Project board: #3)

    • Enhancements to existing features:

      • Did initial refactoring from address book to MediTabs (Pull request #34)

      • UI enhancement - Moved tags to bottom of MedicineCard shown in the list to improve readability (Pull request #193)

    • Team contributions:

      • Reviewed team’s pull requests (Notable reviews: #25 #115 #191)

      • Helped edit ContactUs.adoc to reflect our team’s information (Pull request #31)

Contributions to the User Guide

Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users.

Information Panel

UserGuide InformationPanel
Figure 1. Information panel

Having a way to keep track of individual batches of medicine makes medicine management more efficient as problematic batches can easily be located and removed. However, with so many different batches of the same medicine, you need an effective way to organize them or it could get confusing.

The information panel provides all the details and information you need about each batch of medicine in a neat and organized manner.

You can easily refer to the batch table provided in the information panel while updating and managing your inventory. Simply select a medicine using the select command to view all its relevant details. You may refer to Viewing medicine information page : select for more details.

You can also sort the table by any of its columns with the sort command to suit your needs and preference. You may refer to Sorting the batch table : sort for more details.

Inventory Forecasting

MediTabs will store information about your monthly stock level and predict the optimal amount of stock needed for the future. It will be possible to forecast inventory needs up to 3 months in advance with no extra effort from you as all analysis and calculations will take place with data already provided by routine use of MediTabs. It will also be possible to import past inventory data to increase accuracy of forecasting immediately without having to wait for the application to collect data.

Importing or allowing MediTabs to collect data for 6 months or more will produce a more accurate forecast.

Locating medicines : find

Finds medicine whose details contain any of the given keywords and displays them in the list.
Format: find PREFIX KEYWORD [MORE_KEYWORDS]…​

Possible prefixes:
  • n/ : name of medicine is searched.

  • c/: company name of medicine is searched.

  • t/ : tags of medicine are searched.

  • b/ : batch number of batches of medicine are searched.

 

  • Only the category indicated by the entered prefix will be searched. You can only enter one prefix at a time. Prefix must be entered before keywords.

  • The search is case insensitive. e.g sodium will match Sodium.

  • The order of the keywords does not matter. e.g. Sodium Levothyroxine will match Levothyroxine Sodium.

  • Only full words will be matched e.g. Sod will not match Sodium.

  • Medicines matching at least one keyword will be returned (i.e. OR search). e.g. Sodium Ibuprofen will return Levothyroxine Sodium and Ibuprofen.

Examples:

  • find n/ Sodium
    Levothyroxine Sodium and Naproxen Sodium are displayed in the list.

  • find c/ 3M Johnson Pharmaceutical
    All medicines from companies with names containing 3M, Johnson or Pharmaceutical such as 3M Pharmaceuticals are displayed in the list.

  • find t/ fever
    All medicines with tag fever are displayed in the list.

  • find b/ NDC
    All medicines with batches with batch number containing NDC such as NDC 0777-3105-02 are displayed in the list.

Viewing medicine information page : select

Selects a medicine and loads the information page of the medicine.
Format: select INDEX

  • Loads the information page of the medicine at the specified INDEX in the information panel.

  • The information page consists of a table with details of all batches of the selected medicine.

  • These details include: batch number, quantity and expiry date.

  • The total quantity and next expiry date of the medicine is also displayed at the bottom of the table.

UserGuide SelectCommand
Figure 2. An example of the information page loaded when Aspirin is selected

Examples:

  • list
    select 2
    Selects the 2nd medicine in the inventory and loads its information page.

  • find n/ Gabapentin
    select 1
    Selects the 1st medicine in the results of the find command and loads its information page.

Sorting the batch table : sort

Sorts the batch table in the medicine information page based on the entered property and direction
Format: sort p/PROPERTY d/DIRECTION

Possible properties:
  • batchnumber : sorts the table by batch number (lexicographically).

  • expiry: sorts the table by expiry date.

  • quantity : sorts the table by quantity.

Possible directions:
  • ascending: sorts the table in ascending order.

  • descending : sorts the table in descending order.

Examples:

  • sort p/expiry d/descending
    The table is sorted starting from the batch with the furthest expiry date.

  • sort p/quantity d/ascending
    The table is sorted starting from the batch with the lowest quantity.

Updating batch records : update

Updates batch details of a medicine.
Format: update INDEX b/BATCH_NUMBER [q/QUANTITY] [e/EXPIRY_DATE]

  • Updates details of a batch in the batch records of the medicine at specified INDEX.

  • At least one of the optional fields must be provided.

  • If the entered batch number does not already exist in the record, a new batch record is created. Both quantity and expiry date must be entered for new batches.

  • If the batch number already exists, the quantity or expiry date of the batch is replaced with the new information entered.

  • If quantity of a batch is updated to 0, it will be removed.

  • The total quantity and next expiry date of the medicine will also be updated.

  • Note that in order to prevent confusion, you cannot set expiry date to a passed date. You also cannot add a new batch with 0 quantity.

Examples:

  • list
    update 2 b/NDC 0777-3105-02 q/30 e/11/2/2020
    Updates quantity and expiry date of batch NDC 0777-3105-02 in the batch records of the 2nd medicine in the list to 30 and 11/2/2020. A new record is created if batch NDC 0777-3105-02 did not already exist.

  • find n/ Gabapentin
    update 1 b/GKP1684 q/50
    Updates quantity of batch GKP1684 in the batch records of the 1st medicine in the results of the find command to 50. An error message is shown if batch GKP1684 did not already exist.

  • list
    update 1 b/HK85412 q/0
    Removes batch HK85412 from the batch records of the 1st medicine in the list. An error message is shown if batch HK85412 did not already exist.

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.

Given below is an object diagram to better illustrate how details of a medicine is stored in the Model component.

ModelMedicineObjectDiagram
Figure 3. An example of how the medicine "Paracetamol" could be represented by the Medicine class.

Information Panel

Current Implementation

The information panel is mainly driven by InformationPanel which extends UiPart with an added mechanism to interact with the currently selected medicine and information panel settings. It implements the following main operations:

  • InformationPanel#showSelectedInformation(Medicine medicine) — Creates and displays a BatchTable that contains information of the selected medicine and its batches. Values in the BatchTable are sorted according to SortProperty and SortDirection specified in InformationPanelSettings stored in InformationPanel.

  • InformationPanel#emptyInformationPanel() — Deletes the BatchTable being displayed to show an empty pane.

These operations are hidden and are only triggered when the value of the selected medicine or information panel settings changes. The InformationPanel is initialized with the selected medicine and information panel settings passed in as ObservableValue<Medicine> and ObservableValue<InformationPanelSettings objects and ChangeListener objects are added to them. ChangeListener#changed(ObservableValue<? extends T> observable, T oldValue, T newValue) is called whenever the values in either of the ObservableValue objects changes.

Given below is a diagram showing the execution of InformationPanel when a change to the selected medicine occurs. informationPanel variable seen in the diagram is a StackPane object used to display the created BatchTable by adding it as a child node.

InformationPanelSequenceDiagram
Figure 4. Sequence Diagram for InformationPanel when a change in selected medicine occurs

Given below is an example usage scenario and how the information panel behaves at each step when the selected medicine changes.

Step 1. The user launches the application. The selected medicine is always null when the application is launched. An empty InformationPanel is displayed.

Step 2. The user executes select 1 command to select the 1st medicine in the inventory. Since the new value is not null, InformationPanel#showSelectedInformation(Medicine medicine) is called. A new BatchTable with information of the selected medicine is created and displayed.

An update command will also cause ChangeListener#changed(ObservableValue<? extends T> observable, T oldValue, T newValue) to be called as although the same medicine is still selected, the medicine is replaced in the Inventory with updated fields.

Step 3. The user executes find n/Paracetamol. The find command deselects the selected medicine and the new value is null. Only InformationPanel#emptyInformationPanel() is executed.

Changes to the information panel settings results in a similar sequence of events, except the new value of InformationPanelSettings is saved in InformationPanel before InformationPanel#display() is called.

Given below is another example usage scenario of how the information panel interacts with InformationPanelSettings and the sort command.

Step 1. The user launches the application. InformationPanelSettings stored in Model is passed as an ObservableValue<InformationPanelSettings> to initialize the InformationPanel.

Step 2. The user executes sort p/quantity d/ascending command to sort all batch tables by quantity in ascending order. The sort command calls Model#setInformationPanelSettings(InformationPanelSettings informationPanelSettings)) which changes the value of the InformationPanelSettings in Model. The new InformationPanelSettings is saved in InformationPanel. If the selected medicine is not null, InformationPanel#showSelectedInformation(Medicine medicine) is called. Given below is an activity diagram to show how the saved InformationPanelSettings is used to sort the BatchTable during its initialization. A TableView object populated with the details of the selected medicine is created before the sorting takes place.

InformationPanelActivityDiagram
Figure 5. Activity Diagram demonstrating how BatchTable is sorted during initialization
For more information on the TableView class, you may refer to its API here.

Design Considerations

Aspect: How the information panel executes
  • Alternative 1 (current choice): Creates a new BatchTable to be displayed every time a new medicine is selected.

    • Pros: Information can be taken from Model component during initialization so no extra memory is needed to store table information.

    • Cons: May have performance issues in terms of time needed to retrieve the information and build the table, especially if number of batches becomes huge.

  • Alternative 2: Save created BatchTables as a field in Medicine.

    • Pros: Save time needed for creating the BatchTable for faster response time.

    • Cons: More memory needed to store BatchTable. BatchTable may still have to be recreated if the details of the Medicine are changed after the BatchTable has been created.

Updating batch details of a medicine

  1. Updating a medicine with a new batch while all medicines are listed

    1. Prerequisites: List all medicines using the list command. Multiple medicines in the list. All batch numbers used for testing should not exist in the batch records of the selected medicine. Use select 1 to load the information page.

    2. Test case: update 1 b/A q/1 e/1/1/2020 (valid input)
      Expected: New batch is added to the batch table shown in the information panel. Details of the added batch shown in the status message. Total quantity should increase by 1. Next expiry of medicine should change if 01/01/2020 is earlier.

    3. Test case: update 1 q/1 e/1/1/2020 (missing batch number)
      Expected: Error details shown in the status message. No changes to medicine. Status bar remains the same.

    4. Test case: update 1 b/B e/1/1/2020 (missing quantity)
      Expected: Error details shown in the status message. No changes to medicine. Status bar remains the same.

    5. Test case: update 1 b/B q/1 (missing expiry)
      Expected: Error details shown in the status message. No changes to medicine. Status bar remains the same.

Click here to see the remainder of the test cases.