By: CS2103T-W12-1 Since: Jan 2020 Licence: MIT

1. About Us

Delino is for couriers who prefer to use a desktop app for managing their delivery tasks. It is optimised for those who have a strong preference towards Command Line Interface (CLI) while still enjoying the benefits of a Graphical User Interface (GUI).

Delino is adapted from the AddressBook-Level3 project created by SE-EDU initiative.

If you wish to contact the Delino team, more details can be found here.

2. How to navigate this Developer Guide

This developer guide is written for anyone who wish to extend/modify Delino. This guide will first touch on the overview of our application in the design architecture. Secondly, the specific implementation of Delino’s commands will be further elaborated in the implementation section.

If you need help setting up your development environment to work on Delino, you can follow the Setting Up guide.

Manual testing of Delino can be done by following Appendix G: Instructions for Manual Testing.

Throughout this developer guide, you might encounter additional symbols. These symbols are used to highlight important information.
This developer guide uses the following symbols:

This block contains additional notes.
It contains more information regarding complex content that you should take note of.

This block contains additional tips.

This block contains warning information.

This block contains important information that you should be mindful of.

text markup : This is used to indicate keywords such as command arguments to Delino. (e.g. exit)
bold : This is used to indicate the various Java files in Delino.

3. Setting up

Refer to the guide here.

4. Design

4.1. Architecture

ArchitectureDiagram
Figure 1. Architecture Diagram

The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.

The .puml files used to create diagrams in this document can be found in the diagrams folder. Refer to the Using PlantUML guide to learn how to create and edit diagrams.

Main has two classes called Main and MainApp. It is responsible for,

  • At app launch: Initializes the components in the correct sequence, and connects them up with each other.

  • At shut down: Shuts down the components and invokes cleanup method where necessary.

Commons represents a collection of classes used by multiple other components. The following class plays an important role at the architecture level:

  • LogsCenter : Used by many classes to write log messages to the App’s log file.

The rest of the App consists of four components.

  • UI: The UI of the App.

  • Logic: The command executor.

  • Model: Holds the data of the App in-memory.

  • Storage: Reads data from, and writes data to, the hard disk.

Each of the four components

  • Defines its API in an interface with the same name as the Component.

  • Exposes its functionality using a {Component Name}Manager class.

For example, the Logic component (see the class diagram given below) defines it’s API in the Logic.java interface and exposes its functionality using the LogicManager.java class.

LogicClassDiagram
Figure 2. Class Diagram of the Logic Component

How the architecture components interact with each other

The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete -o 1.

ArchitectureSequenceDiagram
Figure 3. Component interactions for delete -o 1 command

The sections below give more details of each component.

4.2. UI component

UiClassDiagram
Figure 4. Structure of the UI Component

API : Ui.java

The UI consists of a MainWindow that is made up of parts e.g.CommandBox, ResultDisplay, PersonListPanel 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.

  • Listens for changes to Model data so that the UI can be updated with the modified data.

4.3. Logic component

LogicClassDiagram
Figure 5. Structure of the Logic Component

API : Logic.java

  1. Logic uses the DelinoParser class to parse the user command.

  2. This results in a Command object which is executed by the LogicManager.

  3. The command execution can affect the Model (e.g. adding a new order).

  4. The result of the command execution is encapsulated as a CommandResult object which is passed back to the Ui.

  5. In addition, the CommandResult object can also instruct the Ui to perform certain actions, such as displaying help to the user.

Given below is the Sequence Diagram for interactions within the Logic component for the execute("delete -o 1") API call.

DeleteSequenceDiagram
Figure 6. Interactions Inside the Logic Component for the delete -o 1 Command
The lifeline for DeleteCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.

4.4. Model component

ModelClassDiagram
Figure 7. Structure of the Model Component

API : Model.java

The Model,

  • stores a UserPref object that represents the user’s preferences.

  • stores the Order Book and Return Order Book data.

  • exposes two unmodifiable lists, the ObservableList<ReturnOrder> and ObservableList<Order> that can be 'observed'.
    e.g. The UI can be bound to this list so that the UI automatically updates when the data in the list change.

  • does not depend on any of the other three components.

An Order class consists of ten different fields as shown in the image. Every order is part of a UniqueOrderList and every UniqueOrderList is part of an OrderBook.
Similarly, a ReturnOrder class consists of nine different fields as shown in the image. Every return order is part of a UniqueReturnOrderList and every UniqueReturnOrderList is part of a ReturnOrderBook.

4.5. Storage component

StorageClassDiagram
Figure 8. Structure of the Storage Component

API : Storage.java

The Storage component,

  • can save UserPref objects in json format and read it back.

  • can save both OrderBook and ReturnOrderBook data in json format and read it back.

4.6. Common classes

Classes used by multiple components are in the seedu.delino.commons package.

5. Implementation

This section describes some noteworthy details on how certain features are implemented.

5.1. Insert Feature

In this section, the functionality of the insert feature, the expected execution path, the structure of the InsertCommand class, the structure of the InsertCommandParser class and the interactions between objects with the InsertCommand object will be discussed.

5.1.1. What is the Insert feature

The insert feature allows the user to insert an incoming delivery order into the list using the command line.

The order consists of : Transaction ID, Name, Phone, Address, Email, Delivery Timestamp, Warehouse location, CashOnDelivery

The order also consists of two optional fields that can be added:

  1. Type of Item

  2. Comment for Courier

5.1.2. Path Execution of Insert Command

The overview of the InsertCommand Activity Diagram is shown below:

InsertActivityDiagram
Figure 9. Insert Activity Diagram

After the user calls the insert command, the code will check if the command has all the compulsory prefixes present. The code will throw a ParseException when there are missing prefixes. After that is checked, it will check if the new order added is a duplicate (The Order is already inserted into the application). It will throw a CommandException when the user tries to insert a duplicate order. Otherwise, it will insert the order and prints a success message to the user.

5.1.3. Structure of Insert feature

The following diagrams shows the overview of the InsertCommand Class Diagram:

InsertClassDiagram
Figure 10. Insert Class Diagram

The above class diagram shows the structure of the InsertCommand and its associated classes and interfaces. Some methods and fields are not included because they are not extensively utilised in InsertCommand; such as public static fields and getter/setter methods.

5.1.4. Structure of InsertCommandParser Class

InsertParserClassDiagram
Figure 11. InsertCommandParser Class Diagram

The above class diagram shows the structure of the InsertCommandParser and its associated classes and interfaces. It describes all the class dependencies of the InsertCommandParser class. Some methods and fields are not included because they are not extensively utilised in InsertCommand; such as public static fields and getter/setter methods. As shown in the diagram above, the InsertParser make use of methods from classes such as using the getValue method from the ArgumentMultimap class.

5.1.5. Interaction between objects when the Insert Command is executed

Here is the sequence diagram for the Insert Command as shown below:

InsertCommandSequenceDiagram
Figure 12. Insert

The arguments of the insert command will be parsed using the parse method of the InsertCommandParser class.
The InsertCommandParser will tokenize the arguments parsed in using the tokenize method of ArgumentTokenizer class which returns the tokenized arguments. Using the tokenized arguments, the Parser will check if the arguments parsed in matches with the tokenized arguments using the arePrefixesPresent method.

There are two scenarios :

  1. Some compulsory prefixes are not present :
    InsertCommandParser will throw a new ParseException object to the LogicManager.

  2. All compulsory prefixes are present in the arguments :
    It will the proceed to use the getValue method of the ArgumentMultimap class to get the value of the prefix. For example, if the argument parsed in is tid/A12345, the getValue method will get the value 'A12345'. Subsequently, it will use the ParseUtil methods to get the corresponding object values and put it into the parameters of the new Order object. The order object will be put into the parameter of the InsertCommand object and this will be returned to the LogicManager class for execution.

LogicManager will call the execute() method of this InsertCommand object. In the execute() method, it will use the Model class to call hasOrder method to check for duplicates, if it is a duplicate, the order will throw a CommandException which indicates that there is a duplicate order in the OrderBook already. Else, it will successfully inserts the new order using addOrder method. Finally, it return a new CommandResult object, containing a String that indicates a successful insertion.

5.2. List feature

In this section, the functionality of the list feature, the expected execution path, the structure of the ListCommand class and the interactions between objects with the ListCommand object will be discussed.

5.2.1. What is the List feature

List feature allows the user to see all the orders from both Delivery Orders and Return Orders.

The user can enter list to display all the orders. Besides that, the user can also input done to display all delivered orders and undone to display all orders that are not delivered.

5.2.2. Path execution of the List Command

ListActivityDiagram
Figure 13. List Activity Diagram

The above activity diagram shows the logic and the path execution when the list command is executed. There are only three correct syntax available for ListCommand:

  • list

  • list done

  • list undone

The code will check if the input is one of the three mentioned above. If the input is not one of the three, it will cause the code the throw an error message to the user.

5.2.3. Structure List feature

The structure of the List Feature is as shown below:

ListClassDiagram
Figure 14. List Class Diagram

The above class diagram shows the structure of the ListCommand and all its associated classes and interfaces. The ListCommand has dependencies on the Model class as it uses the two methods from it :

  • updateFilteredOrderList

  • updateReturnFilteredOrderList

There are other variables and strings not shown in this Class Diagrams as they are either static methods or variables.

5.2.4. Interaction between objects during execution of List Command

The sequence diagram for the list command is shown below:

ListCommandSequenceDiagram
Figure 15. List Command Sequence Diagram

The user first calls the command list.

The second argument of the list command can be done or undone or an empty String.

The LogicManager will call the parseCommand method of DelinoParser, which then passes the second argument into the ListCommand object. This object will then be ultimately returned to the LogicManager. Next, the LogicManager will call the execute(model) method using the ListCommand object. In this method, it wil use the Model object to call the methods : updateFilteredOrderList and updateFilteredReturnOrderList. Since in this case, the argument is empty, the predicate that is parsed to the two methods will always result to true, which means to list everything from the order book and return book. When completed, the execute(model) will return a CommandResult object to the LogicManager, indicating that the command execution is a success.

5.3. Clear feature

In this section, the functionality of the clear feature, the expected execution path, the structure of the ClearCommand class and the interactions between objects with the ClearCommand object will be discussed.

5.3.1. What is the Clear feature

The clear feature was implemented as a ClearCommand in the logic package.
The clear feature allows the user to remove the orders and return orders by input one command line.

5.3.2. Execution paths of Clear Command

The execution path of the clear command is shown below:

ClearActivityDiagram
Figure 16. Clear Class Activity Diagram

After user enter the clear command, the ClearCommandParser will run the following two checks:

  • Check if flag in the arguments do not belong to one of the three valid flags: -f, -r and -o

  • Check if both -r and -o flags found in the arguments

If either one of the conditions occurs, exception will be thrown and the error message will be display to the user. Afterward, the new ClearCommand object will be executed.

During the execution of the clear command:

  • If -f flag is found in flags, the respective orders will be cleared and display a success message to the user.

  • If there are no -f flag found in flags, a pop up will appeared with the confirmation message. User would be required to press either one of the following two buttons:

    • Yes button - The respective orders will be cleared and display successful clear message to the user.

    • No button - Pop up closed and end of activity.

5.3.3. Structure of Clear Command

The following diagrams shows the overview of the clear command Class Diagram:

ClearCommandClassDiagram
Figure 17. Clear Command Class Diagram

In the ClearCommand class, there are also some static messages for the different input command the user has key in:

  1. MESSAGE_USAGE
    clear: Clear either both order list and return order list or one of them.
    Parameters: -o/-r/-f
    Example: clear -o -f

  2. MESSAGE_SUCCESS_ORDER_LIST
    Inform the user that order list has been cleared successfully.

  3. MESSAGE_SUCCESS_RETURN_LIST
    Inform the user that return order list has been cleared successfully.

  4. MESSAGE_SUCCESS_BOTH_LIST
    Inform the user that both order lists have been cleared successfully.

  5. MESSAGE_ENQUIRY_ORDER_LIST
    Confirmation message to the user if the user want to clear order list.

  6. MESSAGE_ENQUIRY_RETURN_LIST
    Confirmation message to the user if the user want to clear return order list.

  7. MESSAGE_ENQUIRY_BOTH_LIST
    Confirmation message to the user if the user want to clear both order lists.

5.3.4. Interactions between objects when Clear Command is executed

In this section, the interactions between objects when clear command is executed will be display in the Clear Command Sequence Diagram below:

ClearCommandSequenceDiagram
Figure 18. Clear Command Sequence Diagram

The above sequence diagram illustrate how the clear Command is being processed when the user inputs clear -f to force clear all of the orders and return orders without any prompt.

After the user input. the arguments passed to the clear command will be parsed by the ClearCommandParser class
If the given arguments are valid, a new ClearCommand object will be returned.

In ClearCommandParser, there will be two validation checks:
1. Ensure the flag is one of the three flags: -f, -o and -r
2. Ensure the arguments do not have both -o and -r flags.

After the two validation checks, the flag will be added into HashSet, flags which will then passed to the new ClearCommand object created by ClearCommandParser and it is being returned to the LogicManager. The LogicManager will start to run the execute the clear command, which will be shown in details in below diagram:

ExecuteClearCommand
Figure 19. Execution of Clear Command Sequence Diagram

After LogicManager call the ClearCommand#execute(model), the clear command will update the model by pass a new OrderBook object and a new ReturnOrderBook object to Model. The Model will then update its own orderBook and returnOrderBook. In addition, the clear command will pass back a new CommandResult object with the success message in it to the LogicManager at the end of the execution.

5.4. Delete Feature

In this section, the functionality of the delete feature, the expected execution path, the structure of the DeleteCommand class and the interactions between objects with the DeleteCommand will be discussed.

5.4.1. What is the Delete Feature

The delete feature allows the user to delete orders in either the order list or return order list.

The delete feature was implemented as a DeleteCommand in the Logic package.

The delete command has the following format:

  • delete FLAG INDEX

  1. A FLAG is a compulsory argument that indicates the list to delete from.
    It can be either -o or -r.
    A -o FLAG argument indicates deletion from the order list.
    A -r FLAG argument indicates deletion from the return order list.

  2. An INDEX is a compulsory argument that identifies the specific order to delete in the list.
    The INDEX must be a positive integer i.e. 1, 2, 3, …​

5.4.2. Execution paths of Delete command

In this section, you will learn more about the execution paths for the delete command.

DeleteActivityDiagram
Figure 20. Delete Command Activity Diagram

There are four possible execution paths for the delete command

  1. User provides an invalid delete command input
    This results in a parse exception

  2. User provides a valid delete command input that has a flag indicating deletion from the order list.
    The specified order will be deleted from the order list.

  3. User provides a valid delete command input that has a flag indicating deletion from the return order list.
    The specified return order will be deleted from the return order list.

  4. User provides an invalid delete command input that has an invalid flag.
    A Command Exception wil be generated.

5.4.3. Structure of Delete command

In this section, you will learn more about the relationships between objects related to the delete command.

DeleteClassDiagram
Figure 21. Delete Command Class Diagram

In the DeleteCommand class, there are also static strings present that represent the various possible messages.
For some of the message strings, there are placeholder %s strings used for including dynamic input
These messages are the following:

  1. MESSAGE_DELETE_ORDER_SUCCESS
    Deleted Order: %1$s

  2. MESSAGE_DELETE_RETURN_ORDER_SUCCESS
    Deleted Return Order: %1$s

  3. MESSAGE_INVALID_FLAG
    Invalid flag given!

5.4.4. Interactions between Delete command and its associated objects

In this section, you will learn more about the delete command and its inner workings.

The sequence diagram below shows the interactions for a delete command execution of delete -o 1.
This indicates that the first order should be deleted from the order list.

DeleteSequenceDiagram
Figure 22. Delete Command Sequence Diagram for delete -o 1

The arguments passed to the delete command will be parsed by the DeleteCommandParser class.
If the given arguments are valid, a new DeleteCommand object will be returned.
In this class, invalid arguments will result in a ParseException.
Two checks will be done for the arguments:

  1. Invalid FLAG argument

  2. Invalid INDEX argument

When the LogicManager runs the execute() method of DeleteCommand, DeleteCommand will first check the list to delete from.

The deleteFromOrderList(model) method of DeleteCommand will then be called and the filtered order list will be obtained from the getFilteredOrderList() method of the model.

The specified order at INDEX 1 will be deleted using the deleteOrder(order) method in the model.

A new CommandResult will be created and returned to the LogicManager.

The sequence diagram below shows the interactions for a delete command execution of delete -r 2.
This indicates that the second order should be deleted from the return order list.

DeleteSequenceDiagram2
Figure 23. Delete Command Sequence Diagram for delete -r 2

The arguments passed to the delete command will be parsed by the DeleteCommandParser class.
If the given arguments are valid, a new DeleteCommand object will be returned.
In this class, invalid arguments will result in a ParseException.
Two checks will be done for the arguments:

  1. Invalid FLAG argument

  2. Invalid INDEX argument

When the LogicManager runs the execute() method of DeleteCommand, DeleteCommand will first check the list to delete from.

The deleteFromReturnList(model) method of DeleteCommand will then be called and the filtered return order list will be obtained from the getFilteredReturnOrderList() method of the model.

The specified return order at INDEX 2 will be deleted using the deleteReturnOrder(returnOrder) method in the model.

A new CommandResult will be created and returned to the LogicManager.

5.5. Delivered Feature

In this section, the functionality of the delivered feature, the expected execution path, the structure of the DeliveredCommand class and the interactions between objects with the DeliveredCommand will be discussed.

5.5.1. What is the Delivered feature

The delivered function allows the user to mark orders or return orders as delivered after delivering an order or a return order.

The delivered feature was implemented as the DeliveredCommand in the logic package.
The delivered function requires a valid FLAG and a valid INDEX.
i.e. delivered INDEX FLAG

The FLAG can either be '-o' or '-r', which indicates which list (order list or return order list respectively) to mark the parcel from. The FLAG is only valid when either '-o' and '-r' is used. All other inputs will be regarded as invalid.

The INDEX is a positive integer that determines which order or return order to be marked as delivered. The INDEX is only valid if it is a positive integer and if it is not bigger than the size of the order list or return order list, depending on the FLAGthat is provided. For instance, if the '-o' FLAG is provided, the INDEX should not be greater than the size of the order list.

5.5.2. Execution Paths of Delivered Command

DeliveredCommandActivityDiagram
Figure 24. Activity Diagram of the Delivered Command

The above activity diagram shows the logic behind the DeliveredCommand which is determined in the DeliveredCommandParser class when the user inputs the command word delivered to activate the delivered feature.

5.5.3. Structure of Delivered Command

DeliveredClassDiagram

The above class diagram shows the structure of the DeliveredCommand and its associated classes and interfaces. Some methods and fields are not included because they are not extensively utilised in DeliveredCommand; such as public static fields and getter/setter methods.

5.5.4. Interactions between Delivered command and its associated objects

The sequence diagrams for the delivered command are shown below.

DeliveredSequenceDiagram
Figure 25. Delivered Command Sequence Diagram
DeliveredSequenceDiagram2
Figure 26. Execution of Delivered Command

The arguments typed into Delino by the user will first be done by the execute method in LogicManager. After which, an DelinoParser object will be created to parse the input which is determined by the command word via the parseCommand method. In this case, it is the delivered command word that will be parsed.

Then, a DeliveredCommandParser object will be created to parse the arguments after removing the command word delivered from the user’s input. Based on the command word delivered, a DeliveredCommand object will be created.

Subsequently, the parseCommand method in LogicManager will continue to create a CommandResult based on the validity of the user’s input; which is determined by the execute method in DeliveredCommand.

The execute method of DeliveredCommand will first check if a valid FLAG is present in the user’s input. If the FLAG is not valid, a CommandException will be thrown to the user to tell him/her that their input was invalid and tell them the format which their input should follow.

If a valid FLAG is present, this will trigger the processDeliveryOfOrder method in DeliveredCommand which will check if a valid INDEX is present in the user’s input.

If the INDEX is not valid, processDeliveryOfOrder method will throw a CommandException to the user; telling him/her that their input was invalid and the format that their input should follow. i.e. delivered FLAG INDEX

If both FLAG and INDEX are valid, an Order or ReturnOrder object will be created based on the FLAG. The INDEX will determine which order or return order to take from the order list or return order list respectively using the appropriate getter method. The Order or ReturnOrder object will be checked to see if it was delivered using the checkIfOrderWasDelivered(model) method.

If the Order or ReturnOrder was already delivered, this will call the updateOrderList(model) or updatedReturnOrderList(model) method respectively in DeliveredCommand and a new instance of CommandResult will be created to tell the user that the order or return order was delivered.

If the Order or ReturnOrder was not delivered, this will call the deliverAndUpdateOrderList(model) or deliverAndUpdateReturnOrderList(model) respectively in DeliveredCommand. In these methods, the particular Order or ReturnOrder will be retrieved from the model using the getFilteredOrderList() or getFilteredReturnOrderList() method. Based on the retrieved Order or ReturnOrder, a new Order or ReturnOrder with the delivered delivery status will be instantiated using the createDeliveredOrder or createDeliveredReturnOrder methods respectively.

Then, the setOrder or setReturnOrder method will be called to replace the original Order or ReturnOrder object respectively in model. The deliverOrder or deliverReturnOrder method will be called to to set the delivery status of the object to delivered. Then, the updateFilteredOrderList() method or updateFilteredReturnOrderList() method to update the list in the model.

Based on the new updates, a new CommandResult object will be instantiated to print the message success to the user.

5.6. Edit Feature

In this section, the functionality of the edit feature, the expected execution path, the structure of the EditCommand class and the interactions between objects with the EditCommand object will be discussed.

5.6.1. What is Edit Command

The edit feature was implemented as EditCommand in the Logic package.

edit feature format : edit INDEX FLAG ORDER_ATTRIBUTE_PREFIX/NEW_VALUE [ORDER_ATTRIBUTE_PREFIX/NEW_VALUE]

The edit feature allows the user to edit any field except delivery status of the order or the return order. However, user must provide a FLAG and INDEX.
FLAG to indicate which parcel type to edit; -o and -r FLAG to represent Order or Return Order respectively.
INDEX to indicate which parcel the user wants to edit.
The list of the different parcel fields are listed in Appendix E: Glossary.

This feature allows user to edit more than one field within a command.

Limitation

  • Editing the delivery/return time is that the updated delivery date or return date must not be in the past.

  • There must be an order first for edit command to work.

5.6.2. Execution paths of Edit Command

EditCommandActivityDiagram
Figure 27. EditCommand Activity Diagram

The above figure illustrates the execution path of edit command when performed by the user.

Input when received, will be parsed by the DelinoParser. DelinoParser will check if command word matches any features command word.
In this feature, the command word is edit. If no command word is detected, a exception class should be generated for displaying of error message. CommandException is used in this feature to achieve that function.

Once validated, user input is once again parse and check for validity. At this step, if user have provided input not matching the valid edit format, an exception class is thrown.
Furthermore, if NEW_VALUE is invalid an exception should be thrown as well.
ParseException class is used in this scenario.

Some invalid NEW_VALUE:
1) Editing delivery date or return date to the past.
2) Change the transaction id of one parcel to match another parcel.
3) Violation of any field(s) restriction.

A correct input will prompts Delino to carry out the rest of the steps according.
1) Checking of the FLAG
2) Edits the the parcel. 3) Display edit success message.

5.6.3. Structure of Edit Command

EditCommandClassDiagram
Figure 28. Edit Command Class Diagram

The class diagram above depicts the structure of EditCommand. As per any Command class, EditCommand needs to extend the abstract class Command.
Information that are left out in this class diagram are the common messages used in EditCommand.

5.6.4. Interactions between Edit Command and it’s associated objects

EditCommandSequenceDiagram
Figure 29. Edit Command Sequence Diagram

The above figure illustrates the important interactions of EditCommand when the user successfully edit the first displayed order name to Alice.

The handling of breaking down the user input is done in the EditCommandParser class which is called upon by the DelinoParser after an initial check for correctness of the command input.

The EditParcelDescriptor class is a static class contained in the EditCommand class. It act as a helper class to allow the setting of all the NEW_VALUE to the corresponding ORDER_ATTRIBUTE_PREFIX in the EditCommandParser class. The EditParcelDescriptor object is then passed back as a parameter to instantiate an EditCommand. In the diagram above, the EditParcelDescriptor object is named as epd. The EditCommand object is then passed back as e to the LogicManager which will then call EditCommand#execute. This execute method mainly calls the 3 helper method, not shown, EditCommand#createEditedOrder/EditCommand#createEditedReturnOrder and EditCommand#generalSetParcel. The main function of these methods are to help EditCommand in updating the ObservableList in the Model class which is responsible for the updating of list displayed.

The ObservableList is a JavaFX class which listens and automatically changes the list once an update is performed.

5.7. Return Feature

In this section, the functionality of the return feature, the expected execution path, the structure of the ReturnCommand class and the interactions between objects with the ReturnCommand object will be discussed.

5.7.1. What is the Return Feature

The return feature allows the user to either:
1. Create a new return order from his/her input parcel attributes.
2. Convert an existing delivered order to a return order.

The return feature was implemented as a ReturnCommand in the Logic package.

The return command has two possible formats:

  1. return TRANSACTION_ID RETURN_TIMESTAMP If the user provides a valid TRANSACTION_ID and RETURN_TIMESTAMP in his input, the order with the given TRANSACTION_ID will be converted into a return order with the same attributes but with the updated RETURN_TIMESTAMP. The created return order will be added into the return order list.

  2. return TRANSACTION_ID NAME ADDRESS PHONE_NUMBER EMAIL RETURN_TIMESTAMP WAREHOUSE_LOCATION [COMMENTS] [ITEM_TYPE] If the user provides these compulsory parcel attributes, a return order with the given parcel attributes will be created and added to the return order list.

  1. All return orders do not have the CASH_ON_DELIVERY parcel attribute.

  2. The TRANSACTION_ID is alphanumeric, which determines the TRANSACTION_ID of the resulting return order.

  3. The NAME consists of alphabets and determines the NAME of the resulting return order.

  4. The ADDRESS is alphanumeric and determines the ADDRESS of the resulting return order.

  5. The PHONE_NUMBER consists of only numbers and determines the PHONE_NUMBER of the resulting return order.

  6. The EMAIL is alphanumeric and determines the EMAIL of the resulting return order.

  7. The RETURN_TIMESTAMP should include the date in YYYY-MM-DD format and time in 24-hour format with a whitespace in between the date and time.

  8. The WAREHOUSE_LOCATION is alphanumeric and it determines the WAREHOUSE_LOCATION of the resulting return order.

  9. The [COMMENTS] is an optional alphanumeric field and determines the [COMMENTS] of the resulting return order.

  10. The [ITEM_TYPE] is an optional alphabetic field and determines the [ITEM_TYPE] of the resulting return order.

5.7.2. Execution paths of Return command

In this section, you will learn more about the execution paths for the return command.

ReturnCommandActivityDiagram
Figure 30. Return Command Activity Diagram

There are three possible execution paths for the return command

  1. User provides an invalid return command input
    This will result in a parse exception and an error message will be displayed to the user.

  2. User provides a valid return command input with a valid TRANSACTION_ID and RETURN_TIMESTAMP, i.e.
    return TRANSACTION_ID RETURN_TIMESTAMP
    If the order with the given TRANSACTION_ID is delivered, it will be converted to an existing order with the given TRANSACTION_ID into a return order with the updated RETURN_TIMESTAMP.
    This return order will then be added into the return order list.

  3. User provides a valid return command input with all compulsory parcel attributes, i.e.
    return TRANSACTION_ID NAME ADDRESS PHONE_NUMBER EMAIL RETURN_TIMESTAMP WAREHOUSE_LOCATION [COMMENTS] [ITEM_TYPE]
    If the given TRANSACTION_ID does not exist as an order or return order, this will create a new return order based on the given parcel attributes and the resulting return order will be added to the return order list.
    If the given return TRANSACTION_ID already exists as an order or return order, an error message will be displayed to the user that an order or return order already exists in the order list or return order list respectively.

  4. User provides a valid return command input with an invalid TRANSACTION_ID
    This will result in a parse exception and an error message will be displayed to the user.

  5. User provides a valid return command but one or more of the compulsory parcel attributes is/are invalid. This will result in a parse exception and an error message will be displayed to the user.

5.7.3. Structure of Return Command

ReturnClassDiagram

The above class diagram shows the structure of the ReturnCommand and its associated classes and interfaces. Some methods and fields are not included because they are not extensively utilised in ReturnCommand; such as public static fields and getter/setter methods.

5.7.4. Interactions between objects when Return Command is executed

The sequence diagrams for the Return Command are shown below.

The sequence diagram for converting an order into a return order are shown below.

ReturnSequenceDiagram1 a
Figure 31. Return Command Sequence Diagram
ReturnSequenceDiagram2 a
Figure 32. Execution of Return Command to convert a delivered Order into a Return Order

The arguments typed into Delino by the user will first be done by the execute method in LogicManager. After which, an DelinoParser object will be created to parse the input which is determined by the command word via the parseCommand method. In this case, it is the return command word that will be parsed.

Then, a ReturnCommandParser object will be created to parse the arguments after removing the command word return from the user’s input. Based on the command word return, a ReturnCommand object will be created.

Subsequently, the parseCommand method in LogicManager will continue to create a CommandResult based on the validity of the user’s input; which is determined by the execute method in ReturnCommand.

The execute method of ReturnCommand will first check if the return order in the constructor of ReturnCommand is present. In this case, since we are converting an order into a return order, the return order will not be present in the constructor of ReturnCommand and the isReturnOrderNotPresent() method will return true.

If the given TRANSACTION_ID exists in the order list, the getOrderByTransactionId(model) method will attempt to create a new Order object from the model’s Order list based on the given transaction ID, i.e. orderToBeReturned.

The checkIfOrderWasDelivered(model) method checks if the newly created Order is delivered. If the order was not delivered, it will throw a command exception and display an error message to the user.

If the order was delivered, Delino will proceed to check if the timestamp input was valid. If it was invalid, an exception will be thrown and an error message will be displayed to the user.

If the order was delivered and the timestamp input was valid, the deleteOrder(orderToBeReturned) method will be triggered to delete the order from the model’s order list. Also, a new return order will be created based on the ReturnOrder’s constructor that takes in an Order, i.e. ReturnOrder(orderToBeReturned). This creates a new Return Order object, toBeCreated.

Subsequently, this newly created ReturnOrder object toBeCreated, will be checked against the model’s return order list using the hasParcel(toBeCreated) method. If it exists, a command exception will be thrown and an error message will be displayed to the user.

If the ReturnOrder does not exist in the model’s return order list, the newly created ReturnOrder object, toBeCreated, will be added to the model’s return order list using the addReturnOrder(toBeCreated) method.

Finally, a new CommandResult will be created to display the success message to the user for converting a delivered order to a return order.

The sequence diagram for creating a new return order are shown below.

ReturnSequenceDiagram1 b
Figure 33. Return Command Sequence Diagram
ReturnSequenceDiagram2 b
Figure 34. Execution of Return Command to create a new Return Order

The arguments typed into Delino by the user will first be done by the execute method in LogicManager. After which, an DelinoParser object will be created to parse the input which is determined by the command word via the parseCommand method. In this case, it is the return command word that will be parsed.

Then, a ReturnCommandParser object will be created to parse the arguments after removing the command word return from the user’s input. Based on the command word return, a ReturnCommand object will be created.

Subsequently, the parseCommand method in LogicManager will continue to create a CommandResult based on the validity of the user’s input; which is determined by the execute method in ReturnCommand.

The execute method of ReturnCommand will first check if the return order in the constructor of ReturnCommand is present. In this case, since we are creating a new return order from the given parcel attributes, a return order will be created and it will be used in the constructor of ReturnCommand and the isReturnOrderNotPresent() method will return false.

Also, a new return order will be created based on the ReturnOrder's constructor that takes in an Order, i.e. ReturnOrder(orderToBeReturned). This creates a new ReturnOrder object, toBeCreated.

Subsequently, this newly created ReturnOrder object toBeCreated, will be checked against the model’s return order list using the hasParcel(toBeCreated) method. If it exists, a command exception will be thrown and an error message will be displayed to the user.

If the ReturnOrder does not exist in the model’s return order list, the newly created ReturnOrder object, toBeCreated, will be added to the model’s return order list using the addReturnOrder(toBeCreated) method.

Finally, a new CommandResult will be created to display the success message to the user for creating a new return order with the given parcel attributes.

5.8. Nearby Feature

In this section, the functionality of the nearby feature, the expected execution path, the structure of the NearbyCommand class and the interactions between objects with the NearbyCommand object will be discussed.

In this section, you will learn more about how the nearby feature is implemented.

5.8.1. What is the Nearby Feature

The nearby feature allows the user to view all orders that are located at a particular area based on a given search criteria.

The nearby feature was implemented as a NearbyCommand in the Logic package.

The nearby command has two possible formats:

  1. nearby FLAG POSTAL_SECTOR

  2. nearby FLAG AREA

  1. FLAG is an optional argument and indicates which order list to search on.
    It can be either -o or -r. A -o FLAG argument indicates that the order list will be searched.
    A -r FLAG argument indicates that the return order list will be searched.
    By default, if no FLAG arguments are provided, both order list and return order list will be searched.

  2. Searching of nearby orders is done by either POSTAL_SECTOR or AREA

    • A POSTAL_SECTOR refers to the first two digits of a six digit Singapore postal code.
      The list of postal sectors and their corresponding general locations can be found on this website.

    • An AREA refers to one of the five areas of Singapore:

      • Central

      • East

      • North East

      • West

      • North

      • You can obtain more detailed information about each area from this website

5.8.2. Execution paths of Nearby command

In this section, you will learn more about the execution paths for the nearby command.

NearbyActivityDiagram
Figure 35. Nearby Command Activity Diagram

There are four possible execution paths for the nearby command

  1. User provides an invalid nearby command input
    This results in a parse exception

  2. User provides a valid nearby command input that has no flags
    All matching nearby orders will be shown for all lists (order list and return order list)

  3. User provides a valid nearby command input that has one flag. This flag indicates the order list (-o)
    All matching nearby orders will be shown for the order list.

  4. User provides a valid nearby command input that has one flag. This flag indicates the return order list (-r)
    All matching nearby orders will be shown for the return order list.

The matching orders are determined based on the given user argument.
If a two digit integer is given, searching of nearby orders will be based on their postal sector.
Else, searching of nearby orders will be based on their area.
There are currently five areas that are searchable:

  1. Central

  2. East

  3. North-East

  4. West

  5. North

5.8.3. Structure of Nearby command

In this section, you will learn more about the relationships between objects related to the nearby command.

NearbyClassDiagram
Figure 36. Nearby Command Class Diagram

In the NearbyCommand class, there are also static strings present that represent the various possible messages.
For some of the message strings, there are placeholder %s strings used for including dynamic input
These messages are the following:

  1. MESSAGE_USAGE
    nearby: View all orders located at the same postal sector based on the displayed list.
    Parameters: [FLAG] POSTAL_SECTOR or AREA
    An optional flag may be given to indicate the list to be searched for.
    The flag can be either -o for orders for -r for return orders
    A postal sector is the first two digits of a six digit Singapore postal code
    An area is one of the following: Central, East, North-East, West, North
    Example: nearby -o 14
    Example: nearby -r central
    Example: nearby east

  2. MESSAGE_SUCCESS_POSTAL_SECTOR
    Displayed all orders in postal sector.
    General Location: %1$s

  3. MESSAGE_SUCCESS_AREA
    Displayed all orders in area (%s)

  4. MESSAGE_FAILURE_POSTAL_SECTOR
    Invalid postal sector given.

  5. MESSAGE_FAILURE_AREA
    Invalid area given.

5.8.4. Interactions between Nearby command and its associated objects

In this section, you will learn more about the nearby command and its inner workings.

The sequence diagram below shows the interactions for a nearby command execution of nearby -o 14.
This indicates that the order list should be operated on and all orders in the order list that have a POSTAL_SECTOR of 14 should be displayed to the user.

NearbyCommandSequenceDiagram1
Figure 37. Nearby Command Sequence Diagram for nearby -o 14

The arguments passed to the Nearby Command will be parsed by the NearbyCommandParser class.
If the given arguments are valid, a new NearbyCommand object will be returned.
In this class, invalid arguments will result in a ParseException.
Two types of invalid arguments are checked for: empty arguments and arguments with only whitespace characters.

The execute() function of the NearbyCommand will first check if the given arguments are in the format required for postal sector search (the argument can be converted into an integer). If the first check is successful, the argument will be converted into an integer and a second check is performed via the isValidPostalSector(Index postalSector) function of the NearbyCommandUtil helper class.

NearbyCommandUtil is a helper class that contains functions and variables used for identifying postal sectors and their corresponding general locations.
This class was created to reduce the responsibility of the NearbyCommand class.

  • A HashMap was used to store information about postal sectors and their respective general locations.

The model will then be updated by the updateFilteredOrderList(orderPredicate) function.

A CommandResult is then generated and returned to the LogicManager.

The sequence diagram below shows the interactions for a nearby command execution of nearby -o central.
This indicates that the order list should be operated on and all orders in the order list that have an AREA of central should be displayed to the user.

NearbyCommandSequenceDiagram2
Figure 38. Nearby Command Sequence Diagram of nearby -o central

The NearbyCommandParser will check for invalid arguments given by the user.
Invalid arguments can be either empty arguments or arguments with only whitespace characters. A ParseException will be generated if an invalid argument is present.

A new NearbyCommand will be created and returned to LogicManager.

LogicManager will then call the execute() function of the NearbyCommand.
There will then be a check for whether the given argument is a valid area with the function isValidArea(area) present in the DistrictInfo class.

DistrictInfo is a helper class that contains functions and variables used for identifying areas.
This class was created to reduce the responsibility of the NearbyCommand class.

The model will then be updated using the updateFilteredOrderList(orderPredicate) function.

A new CommandResult will be created and returned to the LogicManager.

The sequence diagram below shows the interactions for a nearby command execution of nearby.
This will result in a ParseException as invalid arguments are provided.

NearbySequenceDiagramParseException
Figure 39. Parse Exception due to invalid nearby command

The exception will be thrown in the NearbyCommandParser.

5.9. Help Feature

In this section, the functionality of the help feature, the expected execution path, the structure of the HelpCommand class and the interactions between objects with the HelpCommand object will be discussed.

5.9.1. What is the Help Feature

The help feature was implemented as the HelpCommand in the logic package.
The help feature allows users to save the trouble of adding the delivery orders and the return orders one by one when they have large amount of delivery orders or return orders to add into Delino.

5.9.2. Execution paths of the Help command

The execution path of the HelpCommand is shown below:

HelpCommandActivityDiagram
Figure 40. Help Command Activity Diagram

After the user enters the help command word, there will be a validation check to ensure that there are no non-whitespace characters following after the help command word so that the help command can be processed as a valid command.

If there are non-whitespace characters following help command word, a ParseException object will be created and thrown to the user by displaying an error message.

If there are no non-whitespace characters following the help command word, a new HelpCommand object will be created and a CommandResult object will be created subsequently to display the success message to the user.

5.9.3. Structure of Help Command

The following diagram shows the overview structure of the HelpCommand Class Diagram:

HelpCommandClassDiagram
Figure 41. Help Command Class Diagram

The above class diagram shows the structure of the HelpCommand and its associated classes and interfaces. Some methods and fields are not included because they are not extensively utilised in HelpCommand; such as public static fields and getter/setter methods.

5.9.4. Interactions between objects when Help Command is executed

The sequence diagrams for the help command are shown below.

HelpCommandSequenceDiagram
Figure 42. Help Command Sequence Diagram

The arguments typed into Delino by the user will first be done by the execute method in LogicManager. After which, an DelinoParser object will be created to parse the input which is determined by the command word via the parseCommand method. In this case, it is the return command word that will be parsed.

Then, a HelpCommandParser object will be created to parse the arguments after removing the command word help from the user’s input. Based on the command word help, a HelpCommand object will be created. The parse() method in HelpCommand will check the validity of the user’s input to see if there are any non-whitespace characters following the help command word.

Subsequently, the parseCommand method in LogicManager will continue to create a CommandResult based on the validity of the user’s input.

If the user input is invalid, i.e. there are non-whitespace characters after the help command word, a ParseException object will be created in the parse method in HelpCommandParser and an error message will be displayed to the user.

If the user input is valid, i.e. there are no non-whitespace characters after the help command word, the parse method of HelpCommandParser will return a new HelpCommand.

Then, a new CommandResult will be created based on the user input. This will then display the success message to the user.

5.10. Import feature

In this section, the functionality of the import feature, the expected execution path, the structure of the ImportCommand class and the interactions between objects with the ImportCommand object will be discussed.

5.10.1. What is the Import feature

The import feature was implemented as the ImportCommand in the logic package.
The import feature allows users to save the trouble of adding the delivery orders and the return orders one by one when they have large amount of delivery orders or return orders to add into Delino.

5.10.2. Execution paths of Import Command

The execution path of the ImportCommand is shown below:

ImportActivityDiagram
Figure 43. Import Command Activity Diagram

After the user enter the import command, there are three validation check for the file based on the input argument, FILE_NAME:

  • Check if the input argument has the .csv file extension at the back:

    • If Yes, continue with the next validation check.

    • If No, display error message to the user.

  • Check if the filePath is valid:

    • If Yes, continue with the next validation check.

    • If No, display error message to the user.

  • Check if the file able to read:

    • If Yes, retrieve the data from the CSV file and process the data.

    • If No, display the error message to the user.

Afterward, a new ImportCommand will be created and executed. For every data inside the list, either order or return order will be added into the order book and return order book respectively based on the orderType value. If the orderType is invalid, add the data into the result, which will be displayed to the user after processing.

5.10.3. Structure of Import Command

The following diagram shows the overview structure of the ImportCommand Class Diagram:

ImportClassDiagram
Figure 44. Import Command Class Diagram

In the ImportCommand Class, there are also a few static message to display to the user for the various scenarios occurred during the importing of data from the CSV file:

  1. MESSAGE_USAGE
    import: Import the data in .csv file into Delino
    Parameters: fileName.csv
    Example: import orders.csv

  2. INVALID_MESSAGE
    Invalid order type encountered.

  3. DUPLICATE_ORDER_MESSAGE
    Duplicate order encountered.

  4. DUPLICATE_RETURN_MESSAGE
    Duplicate return order encountered.

  5. MESSAGE_INVALID_CSV_FILEPATH
    The csv file is not found in the data folder.

  6. PROCESS_FAILED_MESSAGE
    Failed to process the data.
    This could be due to invalid order type encountered or invalid data input for the attributes in order and return order.

5.10.4. Interactions between objects when Import Command is executed

In this section, the interactions between the objects when ImportCommand is executed will be shown in the Import Command Sequence Diagram below:

ImportCommandSequenceDiagram
Figure 45. Import Command Sequence Diagram

The arguments passed to the import command will be parsed by the ImportCommandParser class.
Then, the ImportCommandParser will called the ParseUtil#parseCsvFile() to get the filePath based on the input the user provides. Afterward, CsvProcessor will be called to retrieve the data from the csv file and return the processed fileData back to ParseUtil. The fileData will be further pass to ImportCommandParser and to the constructor of ImportCommand.

CsvProcessor is a helper class that helps to retrieve the data from the csv file and process the data before giving to ImportCommand.

Afterward, the ImportCommand object is being returned to the LogicManager and the LogicManager will start to run the execute the ImportCommand, which will be shown at the diagram below.

ExecuteImportCommand
Figure 46. Execution of Import Command Sequence Diagram

The ImportCommand#execute() will first check if the data given starts with order or return and pass to the InsertCommandParser or ReturnCommandParser respectively.

Afterwards, InsertCommandParser or ReturnCommandParser will return a new InsertCommand or ReturnCommand respectively if it successfully parse the data. The ImportCommand will then call the InsertCommand#execute() or ReturnCommand#execute() depend whether it is delivery order or return order. This will cause a delivery order or return order being added into the Model.

The ImportCommand will call its own printResult() function and return a String message to the CommandResult object which is then pass back to the LogicManager.

In this section, the functionality of the search feature, the expected execution path, the structure of the SearchCommand class and the interactions between objects with the SearchCommand object will be discussed.

The search feature was implemented as the SearchCommand in the logic package.

The search feature allow users to search for any orders according to the provided input.

search feature format: search [FLAG] [ORDER_ATTRIBUTE_PREFIX]/[KEYWORD]

A space is needed in between each word.
Keyword search is case-insensitive. E.g: Given Jeremy it matches JeReMy, jeremy or any permutations of alphabet casing.

There are two mode of searching, general search or specific search.
If the user does not provide any ORDER_ATTRIBUTE_PREFIX, a general search mode will be performed on orders, return orders, or both depending on the FLAG.

The [FLAG] -o when given, searches only for parcels in the order list.
The [FLAG] -r when given, searches only for the parcels in the return order list.

  • General search will search for all fields in an order/return orders/both that have any matching fields.

If the user provide any ORDER_ATTRIBUTE_PREFIX, a specific search will be performed.

5.11.2. Execution paths of Search Command

SearchCommandActivityDiagram
Figure 47. Search Command Activity Diagram

The above activity diagram illustrates the different execution paths of search command.
Whenever a user keys in an input with the search keyword, the SearchCommandParser class will handle the parsing of input.
User input will be validated in the SearchCommandParser class.

Input is deemed as invalid and ParseException is thrown under these scenarios:
1) FLAG given is not -o or -r.
2) Multiple FLAG detected.
3) No KEYWORD is given after search.

View the list of allowed prefixes in this search command here.

5.11.3. Structure of Search Command

SearchCommandClassDiagram
Figure 48. Search Command Class Diagram

The above class diagram depicts the structure of the class SearchCommand. As per any Command class, SearchCommand needs to extend the abstract class Command.
Information that are left out in this class diagram are the common messages used in SearchCommand.

5.11.4. Interactions between objects when Search Command is executed

SearchCommandSequenceDiagram
Figure 49. Search Command Sequence Diagram

The sequence diagram above illustrates the interactions between objects when search command is performed by the user.
Particularly, the interactions shown is a success search command executed by the user and only an abstract view is shown.

LogicManager first calls parseCommand with arguments representing the user input, Alice. The SearchCommandParser will then check for any invalid arguments passed by the user.

  • If the given arguments are valid, SearchCommandParser will return a new SearchCommand object.

  • If the given arguments are invalid or empty, a ParseException object will be thrown (not shown in the diagram).

The SearchCommandParser will then checks for the presence of any FLAG. The presence of one will result in different SearchCommand constructor being called.
The SearchCommandParser will call the both the OrderContainsKeywordsPredicate constructor and the ReturnOrderContainsKeywordsPredicate if no FLAG is given.
However, if a FLAG is given, the corresponding predicate will be instantiated and passed as an parameter for the SearchCommand constructor with the other left as null value.

  • What is not shown is that optionally, either OrderContainsKeywordsPredicate or ReturnOrderContainsKeywordsPredicate can be null if a FLAG is given. However, under no circumstances should both be null.

The parsing of user input utilises ArgumentTokenzier (not shown in sequence diagram) to process and split each KEYWORD to it’s corresponding ORDER_ATTRIBUTE_PREFIX, if given any.

If the preamble to any ORDER_ATTRIBUTE_PREFIX is not empty, a general search will be performed in which KEYWORD will be searched through all fields of parcel.
However, if ORDER_ATTRIBUTE_PREFIX is given and the preamble is empty, the specific search will be performed. Only parcel fields that correspond to the given ORDER_ATTRIBUTE_PREFIX will be searched and matched with the KEYWORD.

The order and return order list updates automatically as the JavaFX class ObservableList is used to listen to any changes.

5.12. Show feature

In this section, the functionality of the show feature, the expected execution path, the structure of the ShowCommand class and the interactions between objects with the ShowCommand object will be discussed.

5.12.1. What is the Show feature

The show feature allows the user to see the statistical information of all the orders for both Delivery Orders and Return Orders.

There are a few ways in which the user can input to the command box to execute the show command:

  • show START_DATE [END_DATE]

  • show all

  • show today

  • show DATE

5.12.2. Path execution of the Show Command

ShowCommandActivityDiagram
Figure 50. Show Command Activity Diagram

The above activity diagram shows the logic and the path execution when the show command is executed.

The main logic of the ShowCommand is to check if the number of arguments in the input besides show is one or two. If it is neither, the code will throw an exception. If there is only one argument, the code will check if the word provided is either all or today or simply just a DATE the value of DATE will be validated to check if it is a valid date. It throws an error if it is invalid. When its correct, the code will execute the input accordingly. If the number is two arguments, it will check if the dates provided are valid or invalid date. It throws an error for the latter. The code will then ensure that the START_DATE is before the END_DATE. Once the input passes all the validations in the ShowCommand code, the command will then be executed and it prints a success message to the user.

5.12.3. Structure Show feature

The structure of the show feature is as shown below:

Show Command Class Diagram

ShowCommandClassDiagram

The above diagram shows all the methods and variables that the ShowCommand class is using when the command is executed. All the static methods and variables are not mentioned in this diagram. Furthermore, there are some methods and variables omitted from this diagram as it is irrelevant to the ShowCommand class.

5.12.4. Interaction between objects during execution of Show Command

The sequence diagram for the show command is shown below:

ShowCommandSequenceDiagram
Figure 51. Show Command Sequence Diagram

The user first calls the command "show all".

It can accept either one or two arguments.

The LogicManager will call the parseCommand method of DelinoParser, which then passes the second argument into the ShowCommand object. Within the object, it will call the parseData method to make sense of the dates given. After that, it returns the object to the LogicManager. Next, the LogicManager will call the execute(model) method using the ShowCommand object. When completed, the execute(model) will return a CommandResult object to the LogicManager, indicating that the command execution is a success. In this case where the input is "show all", it will have a message that indicates that the command is showing all information.

5.13. Logging

We are using java.util.logging package for logging. The LogsCenter class is used to manage the logging levels and logging destinations.

  • The logging level can be controlled using the logLevel setting in the configuration file (See Section 5.14, “Configuration”)

  • The Logger for a class can be obtained using LogsCenter.getLogger(Class) which will log messages according to the specified logging level

  • Currently log messages are output through: Console and to a .log file.

Logging Levels

  • SEVERE : Critical problem detected which may possibly cause the termination of the application

  • WARNING : Can continue, but with caution

  • INFO : Information showing the noteworthy actions by the App

  • FINE : Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size

5.14. Configuration

Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json).

6. Documentation

Refer to the guide here.

7. Testing

Refer to the guide here.

8. Dev Ops

Refer to the guide here.

Appendix A: Product Scope

Target user profile:

  • has a need to manage his or her delivery orders and return orders conveniently

  • has a need to search the orders or return orders by region

  • want to check his or her today’s earnings.

  • prefer desktop apps over other types

  • can type fast

  • prefers typing over mouse input

  • is reasonably comfortable using CLI apps

Value proposition: manage their deliveries faster than a typical mouse/GUI driven app

Appendix B: User Stories

Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *

Priority As a …​ I want to …​ So that I can…​

* * *

new courier

see usage instructions

refer to instructions when I forget how to use the App

* * *

courier

import a list of orders

refer to the list of orders to be delivered

* * *

courier

see a list of orders that are yet to be delivered

gauge how long I need to complete my orders

* * *

courier

find an order by name/transaction ID/timestamp

locate details of an order without having to go through the entire list

* * *

courier

recover any deletion of orders

recover any accidental deletions

* * *

courier

edit information in delivery orders

rectify any errors in delivery orders

* * *

courier

view delivery orders based on a given postal sector

easily find delivery orders in the same general location

* * *

courier

see the warehouse details of the orders

know where to get the packages from

* * *

courier

see my delivery orders without internet access

continue with deliveries as per normal

* * *

courier

know the delivery location of the parcels

plan my delivery route better

* * *

courier

be able to navigate the application easily

minimize the downtime in using the App

* * *

courier

mark my deliveries as done upon completion

keep track of orders better

* * *

courier

know whether customer will pay cash on delivery

be prepared to collect any payment upon delivery

* *

courier

know the nearest popstation/pick-up location for returned parcels

plan my route to pick up parcels to be returned

* *

advanced courier

use shorter versions of a command

type a command faster

* *

courier

keep track of the amount I have received for the day’s orders and the change I should give back

know whether the cash balance is correct at the end of the day

* *

caring courier

generate CSV based on what order I select

send the list of orders to my colleagues

* *

courier

report areas of traffic congestion to my colleagues

help my colleagues reduce their delivery times. (Requires Internet Connection)

* *

courier

keep track of areas with traffic congestion

speed up my delivery time

* *

courier

let the customer acknowledge when I have delivered the package

provide proof that the customer has received the package

* *

courier

know the nearest customer to me

reduce the time spent and distance travelled

* *

busy courier

let another courier handle one of my orders

request my colleagues to help me when I cannot complete the orders by today

* *

courier

contact my colleagues easily

ask for help if I am not able to deliver the packages

* *

courier

change the colour scheme of the application to better suit my eyes such as dark mode or a custom colour scheme

customize my user experience

* *

courier

filter all the deliveries to a particular region

arrange to deliver all packages in that region

* *

courier

be able to notify the customer when I am on my way

let the customer know when I am delivering the package to their location

* *

forgetful courier

have visual cues or notification if my order is an urgent delivery

prioritize on which order to deliver first

* *

curious and helpful courier

see how others are doing with their orders

help them if they have any difficulties delivering all of their parcels by the deadline

*

mindful courier

know about the weather of the day

plan ahead for any changes to my deliveries

*

courier

look at the current time

revise my delivery routes if necessary

Appendix C: Use Cases

(For all use cases below, the System is the Delino and the Actor is the user, unless specified otherwise)

Use case: UC01 - Insert an order

MSS

  1. User wants to add an order.

  2. User key in the order details.

  3. Delino inserts the order details.

  4. Delino displays order added.

    Use case ends.

Extensions

  • 2a. Delino detects invalid syntax from user input.

    • 2a1. Delino shows an error message.

      Use case ends.

  • 2b. Delino detects the insertion of a duplicate order.

    • 2b1. Delino shows duplicate order message.

      Use case ends.

  • 2c. Delino detects invalid DELIVERY_TIMESTAMP, i.e. order with the given DELIVERY_TIMESTAMP is before the delivery time stamp of the order.

    • 2c1. Delino shows an error message to the user.

      Use case ends.

  • 2d. Delino detects missing parcel attributes.

    • 2d1. Delino shows an error message to the user.

      Use case ends.

Use case: UC02 - Clear all orders

MSS

  1. User wants to clear all orders.

  2. User requests to clear all orders.

  3. Delino clear all existing orders.

  4. Delino displays order cleared message.

    Use case ends.

Extensions

  • 2a. Delino detects invalid syntax from user input.

    • 2a1. Delino shows an error message.

      Use case ends.

  • 2b. Delino detects no flag -f.

    • 2b1. Delino trigger pop-up message.

      • 2b2a. User select yes button.

        • 2b2a1. Return to step 2.

      • 2b2b. User select no button.

        • 2b2b1. Use case ends.

  • 2c. Delino detects no orders.

    • 2c1. Delino shows no order to be cleared message.

      Use case ends.

Use case: UC03 - Delete an order

Preconditions: There should be a valid order/return order that can be deleted.

MSS

  1. User requests to list orders (UC10).

  2. User wants to delete a specific order/return oder.

  3. User requests to delete a specific order/return order in the list.

  4. Delino deletes the order/return order.

  5. Delino displays order/return order deleted.

    Use case ends.

Extensions

  • 3a. Delino detects invalid syntax from user input.

    • 3a1. Delino shows an error message.

      Use case ends.

  • 3b. The given index for deletion is not valid.

    • 3b1. Delino shows an error message indicating an invalid deletion index has been provided.

      Use case ends.

Use case: UC04 - Mark order or return order as delivered

MSS

  1. User wants to mark an order or return order as delivered.

  2. User request to mark order or return order as delivered.

  3. Delino changes the delivery status of the specified order or return order to delivered.

  4. Delino will display an updated order list or return order list.

    Use case ends.

Extensions

  • 2a. Delino detects invalid syntax from user input.

    • 2a1. Delino shows an error message.

      Use case ends.

  • 2b. Delino unable to detect any parcel with the INDEX provided.

    • 2b1. Delino shows error message to the user.

      Use case ends.

  • 2c. Delino unable to detect valid INDEX provided.

    • 2c1. Delino shows error message to the user.

      Use case ends.

  • 2d. Delino unable to detect valid FLAG provided.

    • 2d1. Delino shows error message to the user.

      Use case ends.

Use case: UC05 - Editing order details

Preconditions: There should be a valid order/return order that can be edited.

MSS

  1. User requests to list orders (UC10).

  2. User wants to edit a specific order.

  3. User request to edit order details.

  4. Delino edit the order details.

  5. Delino display changes made.

    Use case ends.

Extensions

  • 3a. Delino detects invalid syntax from user input.

    • 3a1. Delino shows an error message.

      Use case ends.

  • 3b. Delino unable to detect any parcel specified by the user.

    • 3b1. Delino shows no parcel found message.

  • 3c. Delino detects duplicate parcel.

    • 3c1. Delino shows duplicate parcel message.

      Use case ends.

Use case: UC06 - Exit the program

Precondition: User keys in correct exit command syntax.

MSS

  1. User wantos to exit the program.

  2. User request to exit the program.

  3. Delino displays goodbye message.

  4. Delino closes the application window.

    Use case ends.

Use case: UC07 - Search an order

Preconditions: There should be a valid order/return order in Delino.

MSS

  1. User wants to search a specifc order or return order by a given keyword.

  2. User request to search specific order or return order by a given keyword.

  3. Delino display the requested order.

    Use case ends.

Extensions

  • 2a. Delino detects invalid syntax from user input.

    • 2a1. Delino shows an error message.

      Use case ends.

  • 2b. Delino unable to find any parcel field that matches the given keyword.

    • 2b1. Delino display parcel not found message.

      Use case ends.

Use case: UC08 - Request for help

MSS

  1. User requests to list all commands in Delino

  2. Delino opens a new window after execution of the help command.

  3. Delino display the list of commands and a button to provide user a link to Delino’s User Guide

    Use case ends.

Extensions

  • 1a. Delino detects invalid syntax.

    • 1a1. Delino shows an error message to tell user the right way to use the help command.

      Use case ends.

  • 1b. Delino detects additional non-whitespace characters after the command word, help.

    • 1b1. Delino shows an error message to tell user the right way to use the help command.

      Use case ends.

Use case: UC09 - Importing order details

MSS

  1. User wants to import a specific orders from an external csv file.

  2. User requests to import orders from an external csv file.

  3. Delino checks for file existence.

  4. Delino imports all orders from the external csv file.

  5. Delino displays all orders imported.

    Use case ends.

Extensions

  • 2a. Delino detects invalid syntax from user input.

    • 2a1. Delino shows an error message.

      Use case ends.

  • 3a. Delino detects invalid file path.

    • 3a1. Delino shows the invalid file path error message

      Use case ends.

  • 4a. Delino is unable to open the file.

    • 4a1. Delino shows permission denied error message.

      Use case ends.

Use case: UC10 - Listing all orders

MSS

  1. User wants to view all orders.

  2. User requests to view the list of orders.

  3. Delino display list of orders.

    Use case ends.

Extensions

  • 2a. Delino detects invalid syntax from user input.

    • 2a1. Delino shows an error message.

      Use case ends.

  • 3a. Delino detects no orders.

    • 3a1. Delino shows empty order list message.

      Use case ends.

Use case: UC11 - Returning an order

MSS

  1. User wants to return an order or create a new return order.

  2. User requests to return an order or create a new return order.

  3. Either an order will be converted to a return order or a new return order will be created

  4. Delino displays the updated return order list with the new return order.

    Use case ends.

Extensions

  • 2a. Delino detects invalid syntax from user input.

    • 2a1. Delino shows an error message.

      Use case ends.

  • 2b. Delino detects invalid parcel attributes.

    • 2b1. Delino shows an error message to the user.

      Use case ends.

  • 2c. Delino detects invalid TRANSACTION_ID, i.e. order with the given TRANSACTION_ID does not exist.

    • 2c1. Delino shows an error message to the user.

      Use case ends.

  • 2d. Delino detects invalid RETURN_TIMESTAMP, i.e. order with the given RETURN_TIMESTAMP is bfeore the delivery time stamp of the order.

    • 2d1. Delino shows an error message to the user.

      Use case ends.

  • 2e. Delino detects missing parcel attributes.

    • 2e1. Delino shows an error message to the user.

      Use case ends.

Use case: UC12 - Obtain orders in a postal sector

MSS

  1. User wants to obtain all orders in a specified postal sector.

  2. User requests to obtain orders in a specified postal sector

  3. Delino obtains all orders located in the postal sector

  4. Delino display the list of orders

    Use case ends.

Extensions

  • 2a. Delino detects invalid syntax from user input.

    • 2a1. Delino shows an error message.

      Use case ends.

  • 3a. Delino detects no orders.

    • 3a1. Delino shows empty order list message.

      Use case ends.

Use case: UC13 - Show statistics

Preconditions: There should be a delivered order/return order in the list.

MSS

  1. User wants to know about their delivery statistics.

  2. User requests to see the statistics of orders or return orders.

  3. Delino displays the statistics.

Extensions

  • 2a. Delino detects invalid syntax from user input.

    • 2a1. Delino shows an error message.

  • 2b. Delino detecs an invalid date from user input.

    • 2b1. Delino shows an error message.

Use case ends.

Appendix D: Non Functional Requirements

  1. Should work on any mainstream OS as long as it has Java 11 or above installed.

  2. Should be able to hold up to 350 orders without a noticeable sluggishness in performance for typical usage.

  3. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.

  4. The system should be able to respond within three seconds.

  5. The system should work without internet access.

  6. A user should be able to get all the information he/she needs within four commands.

  7. A user should be able to familiarise himself/herself within an hour of usage.

  8. The data cannot be stored in a Database Management System (DBMS).

  9. The system should work once downloaded and should not depend on a remote server.

  10. The application should not be larger than 50Mb.

  11. The application should be crash during its execution. It should show warning messages instead of crashing.

Appendix E: Glossary

Mainstream OS

Windows, Linux, Unix, OS-X

CLI

Command line interface

MSS

Main Success Scenario, the most straightforward interaction for a given use case, which assumes that nothing goes wrong

Extensions

Possible alternative flow of events of MSS.

Returns

An order that is rejected and needs to be returned to the warehouse

Invalid syntax

Any syntax used that does not correspond to the required format

Status Bar

Refers to the display field showing the results of an executed command

Table 1. Command Prefix
Prefix Meaning Used in the following Command(s)

ot/

Order Type

Import

tid/

Transaction ID

Edit, Import, Insert, Return, Search

n/

Customer Name

Edit, Import, Insert, Return, Search

a/

Address

Edit, Import, Insert, Return, Search

p/

Phone Number

Edit, Import, Insert, Return, Search

e/

Email

Import, Insert, Edit, Return, Search

dts/

Delivery Date And Time

Edit, Import, Insert, Return, Search

rts/

Return Date and Time

Import, Return, Search

w/

Warehouse Location

Edit, Import, Insert, Return, Search

cod/

Cash On Delivery

Edit, Insert, Search

c/

Comments by Customer

Edit, Import, Insert, Return, Search

type/

Type of Item

Edit, Import, Insert, Return, Search

Table 2. Possible Command Flags
Flag Meaning Used in the following Command(s)

-f

Force clear, no user confirmation will be requested

Clear

-o

Order flag, Operation on order list

Clear, Delete, Delivered, Edit, Nearby, Search

-r

Return Order flag, Operation on return order list

Clear, Delete, Delivered, Edit, Nearby, Search

Appendix F: Product Survey

Pros:

  • You can take a picture of the parcel and it is automatically added to the application for tracking.

  • You can also receive weekly statistics on your delivery tasks and time saved.

  • The application interface looks good and easy to navigate.

Cons:

  • Required to scan the parcels one by one, which can be slow and tedious.

  • There does not seem to be a feature to keep track of parcels in a particular area/region.

Pros:

  • You can take a picture of the parcel barcode to add to the application for tracking.

  • There is language support for chinese language (in addition to english)

Cons:

  • There are no statistics available.

  • Required to scan the parcels one by one, which can be slow and tedious.

Appendix G: Instructions for Manual Testing

Given below are instructions to test the app manually.

These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing.

G.1. Launch Delino

  1. Initial launch

    1. Ensure that you have Java 11 installed in your computer

    2. Download the latest Delino.jar

    3. Copy the jar file to the folder you would like to use as a home address for Delino application Expected: Shows the GUI of the Delino App. The window size may not be optimum

G.2. Inserting an order

  1. Insert a minimum of 2 orders

    1. Insert command format: insert TRANSACTION_ID CUSTOMER_NAME ADDRESS PHONE_NUMBER EMAIL DELIVERY_TIMESTAMP WAREHOUSE_LOCATION CASH_ON_DELIVERY [COMMENTS_BY_CUSTOMER] [TYPE_OF_ITEM]

    2. Test case: insert tid/9876543210 n/John Doe a/Blk 572 Hougang st 51 #10-33 S530572 p/98766789 e/johndoe@example.com dts/2020-05-20 1300 w/Yishun cod/$4
      Expected: Inserts an order with the above details to the list and displayed on the GUI

    3. Test case: insert tid/1023456789 n/Amos Cheong a/Blk 572 Hougang st 51 #11-37 S530572 p/90010019 e/amoscheong@example.com dts/2020-05-10 1650 w/Marsiling cod/$5 c/Leave it at the riser type/glass
      Expected: Inserts the order to the list, including the item type and the order comment

    4. Test case: Invalid Syntax
      Expected: No order is added. Error details shown in the response message. A help message displayed for user to insert accordingly. Status bar remain unchanged

    5. Test case: Insert order with existing Transaction ID in list
      Expected: An error will occur and a message will be displayed, stating that order with duplicate ID cannot be inserted into the list

G.3. Returning an order

  1. Convert a delivered order into a return order or create a new return order

    1. Return command format: return TRANSACTION_ID NAME ADDRESS PHONE_NUMBER EMAIL RETURN_TIMESTAMP WAREHOUSE_LOCATION [COMMENTS_BY_CUSTOMER] [TYPE_OF_ITEM]
      OR return TRANSACTION_ID RETURN_TIMESTAMP

    2. Test case: return tid/9876543210 n/John Doe a/Blk 572 Hougang st 51 #10-33 S530572 p/98766789 e/johndoe@example.com rts/2020-05-20 1300 w/Yishun
      Expected: Creates a new return order with the above details and adds it into the return order list. This will be displayed on the GUI

    3. Test case: return tid/1023456789 n/Amos Cheong a/Blk 572 Hougang st 51 #11-37 S530572 p/90010019 e/amoscheong@example.com rts/2020-05-10 1650 w/Marsiling c/Leave it at the riser type/glass
      Expected: Creates a new return order with the above details, including type and comments and adds it into the return order list. This will be displayed on the GUI

    4. Test case: return tid/1023456789 rts/2020-05-12 1300
      Expected: Checks if an order with the given Transaction ID exists. If it exists and it was delivered, check if the given return time stamp is after the delivery time stamp. If it is both delivered and the return time stamp is after the delivery time stamp, the order will be converted into a return order and added into the return order list.

    5. Test case: Invalid Syntax
      Expected: No return order is added. Error details shown in the response message. A help message displayed for user to use the return command accordingly.

    6. Test case: Return order with invalid Transaction ID in order list
      Expected: An error will occur and a message will be displayed, stating that order with the given Transaction ID cannot be found in the order list.

    7. Test case: Return order with invalid return time stamp
      Expected: An error will occur and a message will be displayed, stating that the return time stamp is not valid.

    8. Test case: Return order with missing parcel attributes
      Expected: An error will occur and a message will be displayed, indicating the right message usage of the return feature.

    9. Test case: Order to be converted was not delivered
      Expected: An error will occur and a message will be displayed, indicating that the order was not delivered and cannot be returned.

G.4. Deleting an order

  1. Deleting an order with respect to the current list displayed

    1. Delete command format: delete FLAG INDEX

    2. Prerequisites: List all orders using the list command. Multiple orders in the list

    3. Test case: delete -o 1
      Expected: The first order item in the current order list will be removed. Details of the deleted order will be displayed in the response box

    4. Test case: delete -r 2
      Expected: The second item in the current return order list will be removed. Details of the deleted order will be displayed in the response box

    5. Test case: delete 20
      Expected: No order is deleted as no FLAG is provided.
      An error message will be displayed in the response box.

    6. Test case: delete -r INVALID_INDEX
      Expected: No order is deleted. An error message will be displayed in the response box, indicating that the index cannot be found in the list

G.5. Edit orders

  1. Edit the details of the delivery order by specifying the FLAG (order type), INDEX (parcel number displayed), ORDER_ATTRIBUTE_PREFIX (the field user want to change) and NEW_VALUE (the new value that user want to replace the old ones with). For detailed implementation explanation click here.

    1. Prerequisite: Call the list command to show something or insert/return command to add something before you can edit.

    2. Edit command format: edit FLAG INDEX ORDER_ATTRIBUTE_PREFIX/NEW_VALUE

    3. Test case: edit -r 1 n/Xuan En
      Expected: The first index customer’s name is changed to Xuan En.

    4. Test case: edit -o 2 p/99521654
      Expected: The second index phone number is changed to 99521654.

    5. Test case: edit -o 1 a/Blk 123 Pasir Ris street 51 #12-23 S510123
      Expected: The first index is edited where the address of the customer of the order will be changed to Blk 123 Pasir Ris Street 51 #12-23 S510123.

    6. Test case: edit -r 2 n/Mr Tan p/98776655 a/Blk 841 Yishun st 81 #01-02 S760841
      Expected: The second index of the list is edited. The name is changed to Mr Tan, phone number changed to 98776655 and address will be changed to Blk 841 Yishun st 81 #01-02 S760841.

    7. Test case: edit -o 1 dts/2020-08-09
      Expected: The delivery date of the first index of the customer will be rescheduled to 09/08/2020.

    8. Test case: edit -r 1 rts/1900-02-02
      Expected: The response box will display an error message as it is impossible to put a date that is already passed.

G.6. Import orders

  1. Import a new list of orders from a .csv file given by the company

    1. Import command format: import NAME_OF_FILE.csv

    2. Prerequisites : The import file must be a .csv file and the csv file should be inside data folder which is the same directory as the JAR file. Otherwise, it will cause the app to raise an exception and print the error message. Should not import a file that is non-existent

    3. Test case: import customers_20_02_2020.csv
      Expected: In the response box, a message will appear to indicate that the import is successful. At the same time, the contents of the .csv file will be shown to the user in the form of a list of orders

G.7. List orders

  1. List all the delivery orders for the user. The type of orders to be listed is dependent on the command input from the user

    1. Test case: list
      Expected: List all the delivery orders, showing all completed and uncompleted orders.

    2. Test case: list done
      Expected: List all completed delivery orders.

    3. Test case: list undone
      Expected: List all uncompleted delivery orders.

    4. Test case: list ANY_WORD_OTHER_THAN_UNDONE_AND_DONE
      Expected: An error will occur, a message will appear in the response box, indicating an invalid list command

G.8. Search an order

  1. Search an order based on the KEYWORD and FLAG(if any) given. For a more detailed explanation of the implementation click here.

    1. Search command format: search FLAG KEYWORD

    2. Test case: list done
      search -r Jeremy Loh
      Expected: Specifically search for any return order from the return order list that has any field matching the keyword of either Jeremy, Loh or both and print it to the user.

    3. Test case: list undone
      search -o tid/asj2od3943
      Expected: Specifically search for any order from the order list that has a Transaction id of asj2od3943 and print it out to the user.

    4. Test case: list
      search n/Jeremy
      Expected: Specifically search for both return order or order from both list that has one word of the name matching the key word Jeremy.

    5. Test case: list
      search
      Expected: An error message will appear in the response box, stating that the argument cannot be empty and there are no changes to the list itself.

G.9. Mark parcel as delivered

  1. Mark a parcel’s delivery status as delivered based on its INDEX and FLAG whenever the parcel has been delivered.

    1. Delivered command format: delivered FLAG INDEX

    2. Prerequisite: Ensure that your order list or return order list has at least one order.

    3. Test case: delivered -o 1
      Expected: The first order in the currently displayed order list will be marked as delivered

    4. Test case: delivered -r 2
      Expected: The second return order in the currently displayed return order list will be marked as delivered

    5. Test case: Invalid syntax
      Expected: No parcel is marked as delivered. The error message will be displayed on the error response box describing the error

G.10. Clear orders

  1. Clear all orders while all orders are listed

    1. Clear command format: clear [FLAG]

    2. Test case: clear
      Expected: Confirmation message will display in status message.

      1. If Yes button is pressed, the both order and return order lists will be cleared. Notify the user that both order lists have been cleared in the status message.

      2. If No button is pressed, no order list is cleared.

    3. Test case: clear -f
      Expected: Both order list and return order list will be cleared. Notify the user that both order lists have been cleared in the status message.

    4. Test case: clear -f -r
      Expected: Only return order list will be cleared. Notify the user that return order list has been cleared in the status message.

    5. Test case: clear -r -r -f
      Expected: Only return order list will be cleared. Notify the user that return order list has been cleared in the status message.

    6. Test case: clear -r -o
      Expected: Invalid command input, as both -r and -o cannot be in a single command.
      Error details shown in the response message. A help message displayed for the user to type the correct command. Status bar remains unchanged

    7. Test case: clear -r-f
      Expected: Invalid command input, as space is required in between flags.
      Error details shown in the response message. A help message displayed for the user to type the correct command. Status bar remains unchanged

G.11. Help

  1. Display a list of available commands to user

    1. Test case: help
      Expected: A list of commands will be displayed in a new pop-up window and the response box will indicate a successful command.

    2. Test case: Invalid syntax
      Expected: An error will occur and the response box will show an error message

G.12. Show

  1. Opens a window which shows the statistics of the current lists of orders. It displays information such as earnings made, orders delivered and orders returned (Including a PieChart).

    1. Test case: show all
      Expected: All statistical information of all the orders shown in the statistics tab.

    2. Test case: show today
      Expected: All statistical information today shown in the statistics tab.

    3. Test case: show today 2020-12-03
      Expected: All statistical information between the dates shown in the statistics tab.

    4. Test case: show 2020-12-03
      Expected: All statistical information for the given date shown in the statistics tab.

    5. Test case: show 2020-12-03 2021-01-01
      Expected: All statistical information within the dates shown in the statistics tab.

    6. Test case: Invalid syntax
      Expected: An error will occur and the response box will show an error message.

G.13. Obtain all nearby orders based on area or postal sector

There are two possible search criteria for nearby orders

  1. Obtain all orders located in the same postal sector.
    The postal sector to search for is given by the user.
    A postal sector is the first two digits of a six digit Singapore postal code.
    The list of postal sectors and their corresponding general locations can be found here.

    1. Nearby command format: nearby [FLAG] POSTAL_SECTOR

    2. Prerequisites: Should call a list command before calling nearby. The nearby command will search based on the current list

    3. Test case: nearby -o 79
      Expected: Obtain all orders located in postal sector 79 (Seletar)

    4. Test case: nearby -r 07
      Expected: Obtain all return orders located in postal sector 07 (Anson, Tanjong Pagar)

    5. Test case: nearby -o 99
      Expected: An error will occur as the given postal sector is invalid

    6. Test case: nearby -o 600
      Expected: An error will occur as the given postal sector is invalid

    7. Test case: nearby -o
      Expected: An error will occur as it is an invalid syntax (no postal sector is provided)

  2. Obtain all orders located in the same area.
    There are 5 different areas in Singapore: Central, East, North East, West, North

    1. Nearby command format: nearby [FLAG] AREA

    2. Prerequisites: Should call a list command before calling nearby. The nearby command will search based on the current list

    3. Test case: nearby -o central
      Expected: Obtain all orders located in central area of Singapore

    4. Test case: nearby -r east
      Expected: Obtain all return orders located in east area of Singapore

    5. Test case: nearby -o north east
      Expected: Obtain all orders located in east area of Singapore

    6. Test case: nearby -r west
      Expected: Obtain all return orders located in east area of Singapore

    7. Test case: nearby -r north
      Expected: Obtain all return orders located in east area of Singapore

    8. Information about each area was obtained from this website

G.14. Saving data

  1. Manual Saving is not required as data is already saved in the hard disk after any commands that change the data

G.15. Exit

  1. Exits the Delino App using the exit command

    1. Test case: exit
      Expected: The GUI window will be closed

    2. Test case: Adding any other words as the second argument of the exit command Expected: The response box will display an invalid command message

Appendix H: Effort

Overview
Our team wanted to make an application that could reduce the hassle of managing couriers' orders. We decided to build Delino which aims to provide a centralised platform for couriers to easily manage their deliveries. Delino is significantly different from Address Book 3 (AB3). In addition to the existing basic features of AB3, we needed to add additional features to satisfy the needs of our target audience, couriers. Features that are unique to Delino are Nearby, Show, Import, Return and the enhanced Search.

Challenges faced

  1. Brainstorming of ideas - Ideation was the first hurdle we faced as a team. Coming up with ideas was easy, however, the conflict arose when we were deciding on which idea to implement as every member wanted to solve a different problem. We listed the pros and cons of each proposed idea, and had a few group meetings to evaluate the proposed ideas. We finally chose an idea that was deemed to be most feasible.

  2. Debugging - Had to spend a huge amount of time tracing through the code of more than 7kLoC in order to determine coding bugs/errors. Sometimes, the problem could have been solved by a simple removal or addition of a line of code, in order to resolve the long list of error messages that were displayed to us.

  3. Separate the return order from order - It is important to be able to show two lists, one with orders and the other with return orders. However, this caused list updating to be a major problem for most of the commands. This required significant modifications to our code.

  4. Documentation - It was difficult to efficiently ensure that everything was standardised in the user guide and developer guide as we encountered a lot of different terms that required group discussion before we could finalise on a proper way of dealing with it.

In order to deal with this documentation problem, it often resulted in us having to meet up for long hours (up to 10 hours/day) on consecutive days in order for us to finalise a document together. As a result, it was one of the most time-consuming parts of this project as we usually had to use one person’s screen and go through an entire document together so that we could standardise it consistently.

Achievements

  1. Implementing commands - Ensuring that our commands were implemented in an OOP manner was essential for further extension or fixing of bugs. Throughout the project, we made various code restructuring to allow for better code maintainability.

  2. Maintaining test coverage - As a group, we set a soft-limit for our test coverage to be 80% as we wanted to ensure that the code that we wrote as a team is functional and extensively covered by all the different test-cases. As much as possible, we applied the different testing methods taught in lessons such as Regression testing, Integration testing and Unit testing.

Conclusion
In conclusion, Our team had a great time working with one another and we are proud to have come up with a product like Delino by working tirelessly to build it together. Overall, we believe that Delino is a good testament to our hard work and time spent on perfecting it.