By: CS2103T-W12-1
Since: Jan 2020
Licence: MIT
- 1. About Us
- 2. How to navigate this Developer Guide
- 3. Setting up
- 4. Design
- 5. Implementation
- 6. Documentation
- 7. Testing
- 8. Dev Ops
- Appendix A: Product Scope
- Appendix B: User Stories
- Appendix C: Use Cases
- Appendix D: Non Functional Requirements
- Appendix E: Glossary
- Appendix F: Product Survey
- Appendix G: Instructions for Manual Testing
- G.1. Launch Delino
- G.2. Inserting an order
- G.3. Returning an order
- G.4. Deleting an order
- G.5. Edit orders
- G.6. Import orders
- G.7. List orders
- G.8. Search an order
- G.9. Mark parcel as delivered
- G.10. Clear orders
- G.11. Help
- G.12. Show
- G.13. Obtain all nearby orders based on area or postal sector
- G.14. Saving data
- G.15. Exit
- Appendix H: Effort
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.
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. |
💡
|
This block contains additional tips. |
|
This block contains warning information. |
Important
|
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.
Refer to the guide here.
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.
|
-
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.
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.
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete -o 1
.
The sections below give more details of each 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.
API :
Logic.java
-
Logic uses the DelinoParser class to parse the user command.
-
This results in a Command object which is executed by the LogicManager.
-
The command execution can affect the Model (e.g. adding a new order).
-
The result of the command execution is encapsulated as a CommandResult object which is passed back to the Ui.
-
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.
ℹ️
|
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. |
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>
andObservableList<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. |
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.
This section describes some noteworthy details on how certain features are implemented.
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.
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:
-
Type of Item
-
Comment for Courier
The overview of the InsertCommand Activity Diagram is shown below:
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.
The following diagrams shows the overview of the InsertCommand 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.
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.
Here is the sequence diagram for the Insert Command as shown below:
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 :
-
Some compulsory prefixes are not present :
InsertCommandParser will throw a new ParseException object to the LogicManager. -
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.
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.
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.
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.
The structure of the List Feature is as shown below:
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.
The sequence diagram for the list
command is shown below:
The user first calls the command list
.
ℹ️
|
The second argument of the |
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.
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.
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.
The execution path of the clear
command is shown below:
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.
-
The following diagrams shows the overview of the clear
command Class Diagram:
In the ClearCommand class, there are also some static messages for the different input command the user has key in:
-
MESSAGE_USAGE
clear: Clear either both order list and return order list or one of them.
Parameters: -o/-r/-f
Example: clear -o -f -
MESSAGE_SUCCESS_ORDER_LIST
Inform the user that order list has been cleared successfully. -
MESSAGE_SUCCESS_RETURN_LIST
Inform the user that return order list has been cleared successfully. -
MESSAGE_SUCCESS_BOTH_LIST
Inform the user that both order lists have been cleared successfully. -
MESSAGE_ENQUIRY_ORDER_LIST
Confirmation message to the user if the user want to clear order list. -
MESSAGE_ENQUIRY_RETURN_LIST
Confirmation message to the user if the user want to clear return order list. -
MESSAGE_ENQUIRY_BOTH_LIST
Confirmation message to the user if the user want to clear both order lists.
In this section, the interactions between objects when clear
command is executed will be display in the Clear Command
Sequence Diagram below:
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:
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.
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.
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
ℹ️
|
|
In this section, you will learn more about the execution paths for the delete
command.
There are four possible execution paths for the delete
command
-
User provides an invalid
delete
command input
This results in a parse exception -
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. -
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. -
User provides an invalid
delete
command input that has an invalid flag.
A Command Exception wil be generated.
In this section, you will learn more about the relationships between objects
related to the delete
command.
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:
-
MESSAGE_DELETE_ORDER_SUCCESS
Deleted Order: %1$s -
MESSAGE_DELETE_RETURN_ORDER_SUCCESS
Deleted Return Order: %1$s -
MESSAGE_INVALID_FLAG
Invalid flag given!
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.
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:
-
Invalid
FLAG
argument -
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.
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:
-
Invalid
FLAG
argument -
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.
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.
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 FLAG
that is provided. For instance, if the '-o' FLAG
is provided,
the INDEX
should not be greater than the size of the order list.
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.
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.
The sequence diagrams for the delivered
command are shown below.
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.
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.
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. |
Important
|
Limitation
|
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.
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.
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.
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.
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:
-
return
TRANSACTION_ID
RETURN_TIMESTAMP
If the user provides a validTRANSACTION_ID
andRETURN_TIMESTAMP
in his input, the order with the givenTRANSACTION_ID
will be converted into a return order with the same attributes but with the updatedRETURN_TIMESTAMP
. The created return order will be added into the return order list. -
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.
ℹ️
|
|
In this section, you will learn more about the execution paths for the return
command.
There are three possible execution paths for the return
command
-
User provides an invalid
return
command input
This will result in a parse exception and an error message will be displayed to the user. -
User provides a valid
return
command input with a validTRANSACTION_ID
andRETURN_TIMESTAMP
, i.e.
return
TRANSACTION_ID
RETURN_TIMESTAMP
If the order with the givenTRANSACTION_ID
is delivered, it will be converted to an existing order with the givenTRANSACTION_ID
into a return order with the updatedRETURN_TIMESTAMP
.
This return order will then be added into the return order list. -
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 givenTRANSACTION_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 givenreturn
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. -
User provides a valid
return
command input with an invalidTRANSACTION_ID
This will result in a parse exception and an error message will be displayed to the user. -
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.
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.
The sequence diagrams for the Return Command are shown below.
The sequence diagram for converting an order into a return order are shown below.
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.
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.
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.
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:
-
nearby
FLAG
POSTAL_SECTOR
-
nearby
FLAG
AREA
ℹ️
|
|
In this section, you will learn more about the execution paths for the nearby
command.
There are four possible execution paths for the nearby
command
-
User provides an invalid
nearby
command input
This results in a parse exception -
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) -
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. -
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:
-
Central
-
East
-
North-East
-
West
-
North
In this section, you will learn more about the relationships between objects
related to the nearby
command.
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:
-
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 -
MESSAGE_SUCCESS_POSTAL_SECTOR
Displayed all orders in postal sector.
General Location: %1$s -
MESSAGE_SUCCESS_AREA
Displayed all orders in area (%s) -
MESSAGE_FAILURE_POSTAL_SECTOR
Invalid postal sector given. -
MESSAGE_FAILURE_AREA
Invalid area given.
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.
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.
|
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.
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. |
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.
The exception will be thrown in the NearbyCommandParser.
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.
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.
The execution path of the HelpCommand is shown below:
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.
The following diagram shows the overview structure of the HelpCommand 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.
The sequence diagrams for the help
command are shown below.
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.
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.
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.
The execution path of the ImportCommand is shown below:
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.
The following diagram shows the overview structure of the ImportCommand 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:
-
MESSAGE_USAGE
import: Import the data in .csv file into Delino
Parameters: fileName.csv
Example: import orders.csv -
INVALID_MESSAGE
Invalid order type encountered. -
DUPLICATE_ORDER_MESSAGE
Duplicate order encountered. -
DUPLICATE_RETURN_MESSAGE
Duplicate return order encountered. -
MESSAGE_INVALID_CSV_FILEPATH
The csv file is not found in the data folder. -
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.
In this section, the interactions between the objects when ImportCommand is executed will be shown in the Import Command
Sequence Diagram below:
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.
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]
Important
|
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.
-
Specific search will search orders/return orders/both based on the given
ORDER_ATTRIBUTE_PREFIX
.
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.
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.
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.
💡
|
|
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.
Important
|
|
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.
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.
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
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.
The structure of the show
feature is as shown below:
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.
The sequence diagram for the show
command is shown below:
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.
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
Refer to the guide here.
Refer to the guide here.
Refer to the guide here.
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
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 |
(For all use cases below, the System is the Delino
and the Actor is the user
, unless specified otherwise)
MSS
-
User wants to add an order.
-
User key in the order details.
-
Delino inserts the order details.
-
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 givenDELIVERY_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.
-
MSS
-
User wants to clear all orders.
-
User requests to clear all orders.
-
Delino clear all existing orders.
-
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.
-
Preconditions: There should be a valid order/return order that can be deleted.
MSS
-
User requests to list orders (UC10).
-
User wants to delete a specific order/return oder.
-
User requests to delete a specific order/return order in the list.
-
Delino deletes the order/return order.
-
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.
-
MSS
-
User wants to mark an order or return order as delivered.
-
User request to mark order or return order as delivered.
-
Delino changes the delivery status of the specified order or return order to delivered.
-
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.
-
Preconditions: There should be a valid order/return order that can be edited.
MSS
-
User requests to list orders (UC10).
-
User wants to edit a specific order.
-
User request to edit order details.
-
Delino edit the order details.
-
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.
-
Precondition: User keys in correct exit command syntax.
MSS
-
User wantos to exit the program.
-
User request to exit the program.
-
Delino displays goodbye message.
-
Delino closes the application window.
Use case ends.
Preconditions: There should be a valid order/return order in Delino.
MSS
-
User wants to search a specifc order or return order by a given keyword.
-
User request to search specific order or return order by a given keyword.
-
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.
-
MSS
-
User requests to list all commands in Delino
-
Delino opens a new window after execution of the help command.
-
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.
-
MSS
-
User wants to import a specific orders from an external csv file.
-
User requests to import orders from an external csv file.
-
Delino checks for file existence.
-
Delino imports all orders from the external csv file.
-
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.
-
MSS
-
User wants to view all orders.
-
User requests to view the list of orders.
-
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.
-
MSS
-
User wants to return an order or create a new return order.
-
User requests to return an order or create a new return order.
-
Either an order will be converted to a return order or a new return order will be created
-
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 givenTRANSACTION_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 givenRETURN_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.
-
MSS
-
User wants to obtain all orders in a specified postal sector.
-
User requests to obtain orders in a specified postal sector
-
Delino obtains all orders located in the postal sector
-
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.
-
Preconditions: There should be a delivered order/return order in the list.
MSS
-
User wants to know about their delivery statistics.
-
User requests to see the statistics of orders or return orders.
-
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.
-
Should work on any mainstream OS as long as it has Java
11
or above installed. -
Should be able to hold up to 350 orders without a noticeable sluggishness in performance for typical usage.
-
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.
-
The system should be able to respond within three seconds.
-
The system should work without internet access.
-
A user should be able to get all the information he/she needs within four commands.
-
A user should be able to familiarise himself/herself within an hour of usage.
-
The data cannot be stored in a Database Management System (DBMS).
-
The system should work once downloaded and should not depend on a remote server.
-
The application should not be larger than 50Mb.
-
The application should be crash during its execution. It should show warning messages instead of crashing.
- 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
Prefix | Meaning | Used in the following Command(s) |
---|---|---|
ot/ |
Order Type |
|
tid/ |
Transaction ID |
|
n/ |
Customer Name |
|
a/ |
Address |
|
p/ |
Phone Number |
|
e/ |
||
dts/ |
Delivery Date And Time |
|
rts/ |
Return Date and Time |
|
w/ |
Warehouse Location |
|
cod/ |
Cash On Delivery |
|
c/ |
Comments by Customer |
|
type/ |
Type of Item |
Flag | Meaning | Used in the following Command(s) |
---|---|---|
-f |
Force clear, no user confirmation will be requested |
|
-o |
Order flag, Operation on order list |
|
-r |
Return Order flag, Operation on return order list |
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.
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. |
-
Initial launch
-
Ensure that you have Java 11 installed in your computer
-
Download the latest Delino.jar
-
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
-
-
Insert a minimum of 2 orders
-
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]
-
Test case:
insert
tid/9876543210
n/John Doe
a/Blk 572 Hougang st 51 #10-33 S530572
p/98766789
e/[email protected]
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 -
Test case:
insert
tid/1023456789
n/Amos Cheong
a/Blk 572 Hougang st 51 #11-37 S530572
p/90010019
e/[email protected]
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 -
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 -
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
-
-
Convert a delivered order into a return order or create a new return order
-
Return command format:
return
TRANSACTION_ID
NAME
ADDRESS
PHONE_NUMBER
EMAIL
RETURN_TIMESTAMP
WAREHOUSE_LOCATION
[COMMENTS_BY_CUSTOMER]
[TYPE_OF_ITEM]
ORreturn
TRANSACTION_ID
RETURN_TIMESTAMP
-
Test case:
return
tid/9876543210
n/John Doe
a/Blk 572 Hougang st 51 #10-33 S530572
p/98766789
e/[email protected]
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 -
Test case:
return
tid/1023456789
n/Amos Cheong
a/Blk 572 Hougang st 51 #11-37 S530572
p/90010019
e/[email protected]
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 -
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. -
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. -
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. -
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. -
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. -
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.
-
-
Deleting an order with respect to the current list displayed
-
Delete command format:
delete
FLAG
INDEX
-
Prerequisites: List all orders using the
list
command. Multiple orders in the list -
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 -
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 -
Test case:
delete
20
Expected: No order is deleted as noFLAG
is provided.
An error message will be displayed in the response box. -
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
-
-
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) andNEW_VALUE
(the new value that user want to replace the old ones with). For detailed implementation explanation click here.-
Prerequisite: Call the
list
command to show something orinsert
/return
command to add something before you canedit
. -
Edit command format:
edit
FLAG
INDEX
ORDER_ATTRIBUTE_PREFIX/NEW_VALUE
-
Test case:
edit
-r
1
n/Xuan En
Expected: The first index customer’s name is changed to Xuan En. -
Test case:
edit
-o
2
p/99521654
Expected: The second index phone number is changed to 99521654. -
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. -
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. -
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. -
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.
-
-
Import a new list of orders from a .csv file given by the company
-
Import command format:
import
NAME_OF_FILE.csv
-
Prerequisites : The import file must be a
.csv file
and thecsv file
should be insidedata
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 -
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
-
-
List all the delivery orders for the user. The type of orders to be listed is dependent on the command input from the user
-
Test case:
list
Expected: List all the delivery orders, showing all completed and uncompleted orders. -
Test case:
list
done
Expected: List all completed delivery orders. -
Test case:
list
undone
Expected: List all uncompleted delivery orders. -
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
-
-
Search an order based on the
KEYWORD
andFLAG
(if any) given. For a more detailed explanation of the implementation click here.-
Search command format:
search
FLAG
KEYWORD
-
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 eitherJeremy
,Loh
or both and print it to the user. -
Test case:
list
undone
search
-o
tid/asj2od3943
Expected: Specifically search for any order from the order list that has a Transaction id ofasj2od3943
and print it out to the user. -
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 wordJeremy
. -
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.
-
-
Mark a parcel’s delivery status as delivered based on its
INDEX
andFLAG
whenever the parcel has been delivered.-
Delivered command format:
delivered
FLAG
INDEX
-
Prerequisite: Ensure that your order list or return order list has at least one order.
-
Test case:
delivered
-o
1
Expected: The first order in the currently displayed order list will be marked as delivered -
Test case:
delivered
-r
2
Expected: The second return order in the currently displayed return order list will be marked as delivered -
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
-
-
Clear all orders while all orders are listed
-
Clear command format:
clear
[FLAG]
-
Test case:
clear
Expected: Confirmation message will display in status message.-
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.
-
If No button is pressed, no order list is cleared.
-
-
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. -
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. -
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. -
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 -
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
-
-
Display a list of available commands to user
-
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. -
Test case: Invalid syntax
Expected: An error will occur and the response box will show an error message
-
-
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).
-
Test case:
show
all
Expected: All statistical information of all the orders shown in the statistics tab. -
Test case:
show
today
Expected: All statistical information today shown in the statistics tab. -
Test case:
show
today
2020-12-03
Expected: All statistical information between the dates shown in the statistics tab. -
Test case:
show
2020-12-03
Expected: All statistical information for the given date shown in the statistics tab. -
Test case:
show
2020-12-03
2021-01-01
Expected: All statistical information within the dates shown in the statistics tab. -
Test case: Invalid syntax
Expected: An error will occur and the response box will show an error message.
-
There are two possible search criteria for nearby orders
-
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.-
Nearby command format:
nearby
[FLAG]
POSTAL_SECTOR
-
Prerequisites: Should call a list command before calling nearby. The nearby command will search based on the current list
-
Test case:
nearby
-o
79
Expected: Obtain all orders located in postal sector 79 (Seletar) -
Test case:
nearby
-r
07
Expected: Obtain all return orders located in postal sector 07 (Anson, Tanjong Pagar) -
Test case:
nearby
-o
99
Expected: An error will occur as the given postal sector is invalid -
Test case:
nearby
-o
600
Expected: An error will occur as the given postal sector is invalid -
Test case:
nearby
-o
Expected: An error will occur as it is an invalid syntax (no postal sector is provided)
-
-
Obtain all orders located in the same area.
There are 5 different areas in Singapore: Central, East, North East, West, North-
Nearby command format:
nearby
[FLAG]
AREA
-
Prerequisites: Should call a list command before calling nearby. The nearby command will search based on the current list
-
Test case:
nearby
-o
central
Expected: Obtain all orders located in central area of Singapore -
Test case:
nearby
-r
east
Expected: Obtain all return orders located in east area of Singapore -
Test case:
nearby
-o
north east
Expected: Obtain all orders located in east area of Singapore -
Test case:
nearby
-r
west
Expected: Obtain all return orders located in east area of Singapore -
Test case:
nearby
-r
north
Expected: Obtain all return orders located in east area of Singapore -
Information about each area was obtained from this website
-
-
Manual Saving is not required as data is already saved in the hard disk after any commands that change the data
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
-
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.
-
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.
-
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.
-
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
-
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.
-
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.