By: Team ET
Since: Jan 2020
Licence: MIT
1. Introduction
(Contributed by Teng Le)
E.T. (Easy Travel) is a desktop travel planning application made for travellers who want to plan for their trip. It focuses on the Command Line Interface (CLI) while providing users with a simple and clean Graphical User Interface (GUI). Thus, the main interaction with E.T. will be done through commands.
E.T. allows users to keep track of their trip planning in a single, simple-to-use platform. The information that can be managed by E.T. includes:
-
Trip information
-
Planned activities
-
Transport bookings
-
Accommodation bookings
-
Packing list
-
Fixed expenses
-
Progress of their planning
The purpose of this Developer Guide is to help you understand the design and implementation of E.T. so that you can get started on your contributions to E.T..
2. Setting up
Refer to the guide here.
3. Design
In this section, you will learn about the general design and structure of E.T.. Subsequently, this section will also describe and explain how each component in E.T. works individually. E.T. is coded using the Object-Oriented Programming paradigm and it follows the Facade Pattern and Command Pattern in software design.
3.1. Architecture
(Contributed by Charlotte)
The Architecture Diagram below explains the high-level design of the E.T..
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.
|
The following table gives a quick overview of each component of E.T.. More details about the components can be found in the following subsections.
Component | Description |
---|---|
|
|
|
Represents a collection of classes used by multiple different components. It contains the LogCenter component. The LogCenter component plays an important role at the architectural level and is used by many classes to write log messages to the App’s log file. |
|
The UI of the App. Defines its API in the |
|
Column 2, row 4 |
|
Holds the data of the App in-memory. Defines its API in the |
|
Reads data from, and writes data to, the hard disk. Defines its API in the |
How the architecture components interact with each other
The Sequence Diagram below shows how the different components interact with one another for the scenario where the user issues the command deleteitem 1
.
deleteitem 1
commandThe following subsections will outline the major components in detail.
3.2. UI Component
(Contributed by Joshua Wee)
This segment will explain the structure and responsibilities of the Ui
component.
3.2.1. Structure
Ui
componentAPI:
Ui.java
The Ui
component consists of a MainWindow
that is made up of smaller parts such as ResultDisplay
and CommandBox
as shown in the Class Diagram above. All UI parts in the Ui
component including MainWindow
inherit from the abstract UiPart
class.
The TabPanel
is an abstract class that represents a tab in the GUI and each tab will display information on different features of E.T.. The following classes inherit from the TabPanel
abstract class:
-
ScheduleTabPanel
-
ActivityTabPanel
-
AccommodationBookingTabPanel
-
TransportBookingTabPanel
-
PackingListTabPanel
-
FixedExpenseTabPanel
-
HelpTabPanel
Each tab may also contain smaller parts known as cards. A card is a UI component that contains information that is shown to the user. E.g. An ActivityCard
will contain information about a particular activity.
A generic tab is referred to as an XYZTabPanel while a generic card is referred to as an XYZCard .
|
The MainWindow
also has access to 2 more windows, namely:
-
ListPresetWindow
-
StatusWindow
XYZWindow is used to refer to the 2 windows listed above.
|
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
3.2.2. Responsibilities
The Ui
component,
-
Executes user commands using the
Logic
component. -
Listens for changes to
Model
data so that the GUI can be updated with the modified data.
3.3. Logic component
(Contributed by Joshua Wee)
This segment will explain the structure and responsibilities of the Ui
component.
3.3.1. Structure
Logic
componentAPI:
Logic.java
From the diagram above, you can see that the Logic
component is split into 2 groups, one for command and another for command parsing. As E.T. follows a Command Pattern, a specific XYZCommand
class will inherit from the abstract Command
class. This allows the LogicManager
to execute these commands without having to know each command type.
3.3.2. Responsibilities
The Logic
component is in charge of command parsing from the commands given by the user through the Ui
component. It is also responsible for command execution.
-
Logic uses the
EasyTravelParser
class to parse the user command. -
This results in a
Command
object which is executed by theLogicManager
. -
The command execution can affect the
Model
(e.g. adding an activity). -
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 theUi
to perform certain actions, such as displaying help to the user.
The steps described above will be the standard command parsing and execution of every command in E.T.. To illustrate these steps, the Sequence Diagram for interactions within the Logic
component when the command deleteitem 1
is shown below. The diagram starts with the execute("deleteitem 1")
API call.
Logic
component for the deleteitem 1
command
The lifelines for the DeleteItemCommandParser and DeleteItemCommand should end at the destroy marker (X). However, due to a limitation of PlantUML, the lifelines reache the end of the diagram.
|
3.4. Model component
(Contributed by Catherine)
This segment will explain the structure and responsibilities of the Model
component.
3.4.1. Structure
Model
componentAPI:
Model.java
The UserPrefs
class represents the user’s preference.
The XYZManager
is a generic name given to the following managers which represent the manager for each feature of E.T.:
-
TripManager
-
ActivityManager
-
AccommodationBookingManager
-
TransportBookingManager
-
PackingListManager
-
FixedExpenseManager
The ObservableList
abstract class is exposed by the Model
component for the Ui
component to observe and automatically update the GUI when data in the Model
component changes. This follows the Observer Pattern in software design.
3.4.2. Responsibilities
The Model
component,
-
Represents data of different features of E.T..
-
Stores these data in-memory when the App is running.
-
Does not depend on the
Ui
,Logic
andStorage
components. -
Contains observable data so that the GUI can automatically update upon data changes.
3.5. Storage component
(Contributed by Teng Le)
This segment will explain the structure and responsibilities of the Storage
component.
3.5.1. Structure
Storage
componentAPI:
Storage.java
The UserPrefsStorage
interface and XYZStorage
interface define the API for reading and saving the Model
component’s data from and to the hard disk.
The JsonXYZStorage
is the implementation of the XYZStorage
interface which manages the storage for various features. The following Class Diagram will describe the structure of a JsonFixedExpenseStorage
as an example. The other storage class will follow a similar structure.
FixedExpenseStorage
3.5.2. Responsibilities
The Storage
component,
3.6. Common classes
The Common
component contains classes used by multiple other components in the team.easytravel.commons
package.
4. Implementation
This section describes some noteworthy details on how certain features are implemented.
4.1. Trip Manager
(Contributed by Charlotte)
E.T allows the user to plan for an overseas trip. E.T is implemented in a way that the user can only plan for one single trip at any time. i.e. Only a single trip’s data can be managed. In this Trip Manager feature, the user can set, edit and delete his/her trip details. The trip details includes:
-
title
-
budget
-
exchangeRate
-
startDate
-
endDate
4.1.1. Rationale
The Trip Manager feature is included in E.T. because it is the core feature of the application. If the user wants to plan for an overseas trip, he/she has to record details about the trip.
4.1.2. Current Implementation
The TripManager
class in the Model
component is responsible for all operations on the trip which is represented by the Trip
class. The following Class Diagram describes the structure of the TripManager
and its relevant classes.
TripManager
and its relevant classesAs seen from the diagram, the TripManager
can only manage one trip at any point in time.
Next, the following table shows the commands related to managing the trip details.
Command | Purpose |
---|---|
|
Adds a trip and sets the trip details. |
|
Edits the trip title. |
|
Edits the budget of the trip. |
|
Deletes the trip and all the data in the App. |
This ability to change the start and end dates and the exchange rate of the trip is not available.
4.1.3. Design Consideration
Aspect: Number of trips allowed to be managed
Pros | Cons | |
---|---|---|
Option 1 (Current) |
Easy to implement. |
Less flexibility for the user. |
Option 2 |
More flexibility for the user. |
More overhead, especially in terms of space. |
Reasons for choosing the option 1:
-
A typical user would only plan one trip at a time. Thus, the overhead incurred by option 2 is not justified.
-
Limited time for implementing this feature. Thus, option 1 is more ideal.
Aspect: Ability to edit the details of the trip
Pros | Cons | |
---|---|---|
Option 1 (Current) |
Easy to implement. Nothing depends on the trip title and budget. |
Users who need to change the dates or exchange rate of the trip need to delete and then set the trip which is troublesome. |
Option 2 |
More flexibility and convenience for the user. |
The schedule feature depends on the trip dates while the expense feature depends on the exchange rate. Thus, allowing these fields to be changed is very difficult to implement and likely to result in bugs. |
Reasons for choosing option 1:
-
The exchange rate of a trip does not tend to fluctuate much, thus the cons of option 2 outweigh the pros for the exchange rate.
-
As for the trip dates, the schedule feature is a big feature of E.T. and it depends on the trip dates. Given the limited time for implementation, we decided to opt for a less bug-prone approach that can showcase E.T.’s feature.
4.2. List Managers
(Contributed by Catherine)
E.T. allows the user to manage different essential lists for their trip.
These list include:
* Activities
* Transport Bookings
* Fix Expenses
* Accommodation Bookings
* Packing List
All these lists are managed by `ListManager`s which support basic CRUD operations and some additional operations for users to manage their list efficiently. The term item will be used to refer to the elements stored in a list.
Common commands for all `ListManager`s:
-
add
— Creates a new item -
delete
— Deletes an existing item -
edit
— Edits an existing item -
sort
— Sorts the list by the given specification -
list
— List all items in the list.
4.2.1. Rationale
When planning for a trip, there are many things that the user may want to keep track of. This is our reason for creating the 5 lists stated above. The `ListManager`s are thus created to help the user manage the 5 lists so that they can plan their trip conveniently and efficiently.
4.2.2. Current Implementation
In this section, we will first explain the structure of a typical ListManager
also known as an XYZListManager
. As mentioned earlier in the overview of this section, the term item will be used to refer to the elements stored in a list.
The XYZListManager
contains a UniqueList
which is a data structure that stores all the items of a list. The UniqueList
makes use of Java’s generics and can only contain items that implement the UniqueListElement
interface. This is because the uniqueness of an element in the UniqueList
is determined by the returned value of the isSame()
method of the UniqueListElement interface.
In addition, the XYZListManager
implements the ReadOnlyXYZManager
interface. This interface has the getXYZList()
method which returns an ObservableList
of items. For example, ActivityManager
implements ReadOnlyActivityManager
. The ObservableList
of items allows the Ui
model to use the Observer Pattern to update the GUI.
The following Class Diagram describes the aforementioned structure of the ActivityManager
.
ActivityManager
The following paragraphs will describe what happens when the user performs an operation on a ListManager
through commands. XYZCommand
here will refer to a command described above for the 5 ListManager
s. (e.g. AddActivityCommand
, EditTransportBookingCommand
).
As described in [Design-Logic], after the user enters a command, the EasyTravelParser
will generate an XYZCommandParser
which parses the user input parameters and generate an executable XYZCommand
that performs an operation on the list.
We will describe the execution of an XYZCommand
, using AddActivityCommand
as an example. All other XYZCommand
will be executed in similar ways.
When AddActivityCommand
is executed, an Activity
will be added to the list of activities managed by the ActivityManager
in the Model
component.
The Sequence Diagram below shows the execution of the AddActivityCommand
:
AddActivityCommand
The lifeline for the This sequence diagram does not take into consideration the possible exceptions which might occur during the |
4.2.3. Design Consideration
Aspect: Separation between scheduling and activity management
Pros | Cons | |
---|---|---|
Option 1 (Current) |
Keeps everything separate which abide by the Separation of Concerns Principle (SoC) principle. Achieves better modularity by separating the code into distinct sections, such that each section addresses a separate concern. Allows for different behaviours of each list manager |
Tedious to implement as we have many lists to manage. |
Option 2 |
Easy to implement as we only need to write one |
Violates SoC. |
Reason for choosing option 1:
Applying SoC limits the ripple effect when changes are introduced to a specific part of the system. Since we are constantly changing our system during development, abiding by SoC will save us time in the long-run as less code is affected when changes to the system are made.
Aspect: Implementation behind a list manager
Pros | Cons | |
---|---|---|
Option 1 (Current) |
Abide by the Don’t Repeat Yourself (DRY) principle. Minimize repeated code as all |
All |
Option 2 |
Each |
Violates the DRY principle as there will be common operations between |
Reason for choosing option 1:
-
It is a good coding practice to follow the DRY principle.
-
The implementations of the
ListManager
s are done quite early on, where our team has more flexibility in terms of deadline. Thus, we can afford to spend more time developing theUniqueList
data structure before starting on the implementation of anyListManager
4.3. Activity Manager
(Contributed by Charlotte)
E.T. allows the user to keep track of their activities for his/her trip. The activity manager is one of the ListManager
s (See [List-Manager]). On top of the basic operations provided by a ListManager
, it also allows the user to search for their activities using the findacitivty
command. The parameters of the findactivity
command are keywords in the activity entries that the user wants to search for. E.g. findactivity sightseeing carnival
will search and list all activity entries with sightseeing
or carnival
in their detail. Another similar command, findactivitytag
has the same functionality but only searches for the tags of activity entries.
4.3.1. Rationale
The activity manager is an important feature to have because any oversea trip will be packed with activities for the traveller. Thus, we decided to create an activity manager as one of the ListManager
s.
4.3.2. Current Implementation
The current implementation of the activity manager only allows the user to keep track of a list of activities for their trip. It does not allow the user to indicate the start and end time of an activity. Instead, the ability to indicate a start time for an activity will be in another feature known as the Schedule Feature (See [Schedule-Feature]).
In this section, we will outline the findactivity
command of the activity manager which is summarised by the Activity Diagram below.
findactivity
commandWhen the user enters the findactivity
command to search for activities, the user input command undergoes the same command parsing as described in [Design-Logic]. During the parsing, a predicate is created. This predicate checks if a given Activity
contains the user input keywords. The FindActivityCommand
will then receive this predicate when it is created.
The following steps will describe the execution of the FindActivityCommand
in detail, assuming that no error is encountered.
-
When the
execute()
method of theFindActivityCommand
is called, theModelManager
’supdateFilteredActivityList()
method is called. -
The
ModelManager
then proceeds to call theupdateFilteredActivityList()
method of theActivityManager
. -
The
ActivityManager
will then update its filtered list of `Activity`s to contain only `Activity`s that fulfil the given predicate. -
The
Ui
component will detect this change and update the GUI. -
If the above steps are all successful, the
ScheduleCommand
will then create aCommandResult
object and return the result.
The Sequence Diagram below summarises the aforementioned steps.
FindActivityCommand
The lifeline for the This sequence diagram does not take into consideration the possible exceptions which might occur during the |
4.3.3. Design Consideration
We do not have other implementation options for the FindActivityCommand
as the current implementation is the only option that we came up with. This option is quite easy to understand and follows good coding principles.
4.4. Schedule Feature
(Contributed by Teng Le)
E.T. allows the user to schedule an activity from the activity list to a specified time of a day. This is done using the schedule
command which requires the user to specify the ACTIVITY_INDEX
of an activity from the displayed activity list, the DAY_INDEX
of the trip and the START_TIME
of the activity to be scheduled.
4.4.1. Rationale
The schedule feature is an important feature that allows the users to manage and plan for their trip schedule or itinerary. This feature is added to E.T. to separate from the activity management feature from the schedule. This can increase the ease of planning because users can just focus on the time management aspect when scheduling proposed activities from the activity list. The schedule feature also automatically adds any transport bookings into the schedule.
4.4.2. Current Implementation
The schedule feature uses a separate system and structure as compared to the ListManager
s. Instead, the schedule feature will be more closely related to the trip feature because it heavily relies on information about the Trip
such as the startDate
and endDate
.
As such, the TripManager
is in charge of managing the schedule. The TripManager
, contains a list of DaySchedule
s which represents the schedule of a specific day of the Trip
. Thus, the number of DaySchedule
s equals the number of days in the Trip
. E.g. a trip of 2 days means that the TripManager
contains 2 DaySchedule
objects.
Within each DaySchedule
object, there is a UniqueList
of DayScheduleEntry
. The DayScheduleEntry
object represents an entry in the schedule.
As an example, the following UML object diagram describes the relevant objects related to this feature when a Trip
of 2 days is set.
When the user enters the schedule
command to schedule an activity, the user input command undergoes the same command parsing as described in [Design-Logic] . A ScheduleCommand
will then be created.
The following steps describe the execution of the ScheduleCommand
, assuming that no error is encountered.
-
When
execute()
of theScheduleCommand
is called, theModelManager
retrieves the displayed list of activities shown to the user. -
Then, it retrieves the target
Activity
using the user-specifiedINDEX
. -
The
ModelManager
’sscheduleActivity()
method is called to schedule the targetActivity
. -
The
ModelManager
proceeds to call thescheduleActivity()
method of theTripManager
. -
The
TripManager
then uses the given activity to create a correspondingDayScheduleEntry
object. -
The
TripManager
will calculate which day of the trip to schedule this activity and get theDaySchedule
representing the schedule of the target day. -
The target activity is then scheduled on the target day through the
addScheduleEntry()
method of the targetDaySchedule
. -
If the above steps are all successful, the
ScheduleCommand
will then create aCommandResult
object and return the result.
The Sequence Diagram below summarizes the execution of the ScheduleCommand
.
ScheduleCommand
The lifeline for the This sequence diagram does not take into consideration the possible exceptions which might occur during the |
4.4.3. Design Consideration
Aspect: Separation between scheduling and activity management
Pros | Cons | |
---|---|---|
Option 1 (Current) |
Better user experience. Allows for extensions as other types of objects such as a |
Complicated to implement and more likely to result in bugs if undesirable dependencies are introduced. |
Option 2 |
Straightforward and simple to implement. |
Other types of objects such as |
Reasons for choosing option 1:
-
The schedule feature is a major feature because it is the main part of planning for a trip. Thus, we decided to opt for the option with better user experience.
-
The ability for other objects to be converted into a
DayScheduleEntry
object in option 1 is also beneficial for future versions of E.T. if we want to extend this feature to schedule other items such as accommodation bookings.
4.5. Accommodation Booking Manager
(Contributed by Joshua Wee)
E.T. allows the user to keep track of their accommodation bookings for his/her trip. The accommodation booking manager is one of the ListManager
s (See [List-Manager]). On top of the basic operations provided by a ListManager
, it also prevents the user from having overlapping accommodation bookings.
4.5.1. Rationale
The transport booking manager is an important feature to have because any oversea trip of more than one day will require some form of accommodation. Thus, we decided to create an accommodation booking manager as one of the ListManager
s.
4.5.2. Current Implementation
When a user adds an accommodation booking, the Logic
Component parses the user input and creates an AddAccommodationBookingCommand
object (See [Design-Logic]). When the execute()
method of AddAccommodationBookingCommand
is called, the execution will check if the new accommodation booking overlaps with any other other current bookings.
Using a Java’s stream, the new accommodation booking will be checked against all other bookings in the list to look for any overlaps. We used an interval overlap detection algorithm to check for overlap between 2 accommodation bookings. If the total duration of the 2 accommodation bookings is within the acceptable duration of the algorithm, then there is no overlap. acceptable duration = latest end day - earliest start day
The following diagram gives a visual explanation on this interval overlap detection algorithm.
The following steps describe the flow of an overlap check between 2 accommodation bookings:
-
The start day and end day of both bookings are retrieved using
getStartDay()
andgetEndDay()
methods of theAccommodationBooking
object. -
The total duration of both accommodation bookings is calculated.
-
The latest end day and earliest start day is obtained.
-
The acceptable duration is calculated.
-
If the acceptable duration is greater than the total duration of both bookings, there is no overlap. The overlap check will continue for the next accommodation booking until the last. If there is an overlap, the check will stop and the user will receive a message that informs them that the new accommodation booking will overlap with another booking.
The Activity Diagram below summaries the above steps.
4.5.3. Design Consideration
Aspect: Calculating overlap of the new accommodation booking with the other accommodation bookings in the list
Pros |
Cons |
|
Option 1 (Current) In the worst case, the checking for overlap against all accommodation booking takes O(n) time where n is the number of accommodation bookings |
Simple and easy to implement. Only require constant space to calculate overlaps between 2 intervals. |
Requires some calculation. |
Option 2 In the worst case, the checking for overlap against all accommodation booking takes O(d) time where d is the number of days. |
Simple and easy to implement. Checking for any particular day takes constant time. |
Require a large amount of storage space to save the hashtable data. |
Reason for choosing option 1:
-
Both options are simple and easy to implement. However, option 2 has a larger overhead due to the hashtable it uses. Thus, we decided option 1 is better.
4.6. Transport Booking Manager
(Contributed by Teng Le)
E.T. allows the user to keep track of their transport bookings for his/her trip. The transport booking manager is one of the ListManager
s (See [List-Manager]). On top of the basic operations provided by a ListManager
, it also automatically adds all the transport bookings into the trip schedule.
4.6.1. Rationale
The transport booking manager is an important feature to have because any oversea trip will require some form of transportation to the destination and back. Thus, we decided to create a transport booking manager as one of the ListManager
s.
4.6.2. Current Implementation
The transport bookings are managed by the TransportBookingManager
class. In this section, we will describe how a transport booking is automatically added to the schedule when the user adds a transport booking.
The following Class Diagram describes the structure of the TransportBookingManager
and how it is related to the TripManager
which handles the scheduling of activities and transport bookings. Only relevant classes and methods are shown in the diagram.
TransportBookingManager
From the diagram, it is clear that the TransportBookingManager
has no direct association with the TripManager
. The following steps will outline how a transport booking is added to the schedule managed by the TripManager
when the user tries to add a transport booking to the TransportBookingManager
using the addtransport
command.
-
The user enters the
addtransport
command to add a transport booking. -
The command is parsed by the
Logic
component and anAddTransportBookingCommand
is created. (See [Design-Logic]) -
During the execution of the
AddTransportBookingCommand
, aDayScheduleEntry
representing this transport booking is first created. (See [Schedule-Feature] for more information on the schedule feature) -
The day to schedule this transport booking is calculated.
-
If the calculation returns an out-of-bound day of the current
Trip
, an error message will be shown to the user. -
Else, the
AddTransportBookingCommand
will add theDayScheduleEntry
to the schedule through theModelManager
’sscheduleTransportBooking()
method. -
Finally,
AddTransportBookingCommand
will then add the transport booking into theTransportBookingManager
.
The following Activity Diagram summarizes the workflow mentioned above.
4.6.3. Design Consideration
The design consideration for this feature is similar to that of the Schedule feature. (See [Schedule-Design-Consideration])
This is because if we let the ActivityManager
manage the schedule and activities, then the schedule can only contain activities. This means that transport bookings will become a basic ListManager
(See [List-Manager]) with no special functionalities. Thus, we decided to adopt the current implementation for better user experience and potential future extensions.
4.7. Packing List Manager
(Contributed by Catherine)
E.T. allows the user to keep track of their packing list for his/her trip. The packing list manager is one of the ListManager
s (See [List-Manager]). On top of the basic operations provided by a ListManager
, it also allows the user to add built-in lists of items into his/her current packing list through the addpreset
command.
E.g. the addpreset swimming
will add items related to swimming into the packing list. The term preset will be used to refer to the built-in list of packing list items.
4.7.1. Rationale
The packing list manager is an important feature to have because there are many things that a traveller wants to bring for his/her oversea trip. The packing list will help the user ensure that he/she did not forget to pack anything for the trip. Thus, we decided to create a packing list manager as one of the `ListManager`s.
4.7.2. Current Implementation
When a user enters the addpreset
command, the Logic
Component parses the user input and creates an AddPresetCommand
object (See [Design-Logic]). When the execute()
method of AddPresetCommand
is called, the execution of this command will retrieve the target preset specified by the user into the packing list.
The Activity Diagram below shows how a preset is added to the packing list.
addpreset
command4.7.3. Design Consideration
Aspect: Customizability of the preset
Pros | Cons | |
---|---|---|
Option 1 (Current): |
Provides the user with more convenience as it allows the user to add an existing built-in list into their packing list instead of adding one item at a time. |
Restricts the freedom of the user due to lack of customizability |
Option 2: |
Gives the user a lot of freedom to customise their presets and packing list, making the application user focused. |
Difficult to implement as we would need to introduce more validation rules and checks to ensure the user creates a valid preset. |
Option 3: |
Provides the best user experience as this option gets the benefit of both the previous 2 options. |
Complicated and takes a long time to implement. |
Reasons for choosing option 1:
-
Due to time restriction, we only have enough time to implement either option 1 or 2 by E.T. v1.4.
-
We want to focus on giving the user the best first time experience when using E.T.. Thus, option 1 is more suitable as it provides convenience for the user when he first use E.T..
-
Option 2 is only useful when the user uses E.T. for more than one trip and he/she wants to save his previous packing list to add for the next trip.
4.8. Fixed Expense Manager
(Contributed by Joshua Lay)
E.T. allows the user to keep track of their fixed expenses for his/her trip. The fixed expense manager is one of the ListManager
s (See [List-Manager]). On top of the basic operations provided by a ListManager
, it also allows the user to set a budget for the trip and automatically converts any fixed expenses entered in foreign currency into Singapore Dollars (SGD).
4.8.1. Rationale
The fixed expense manager is an important feature to have because many travellers would want to manage their expense for an overseas trip. We also found out that most accommodations are commonly charged in a foreign currency instead of SGD. This prevented travelers from having a clearer picture of how much they have spent on these big ticket items before their trip. Thus, we decided to create a transport booking manager as one of the ListManager
s with an automatic conversion feature.
==== Current Implementation
Currently, the information on the trip’s budget and the exchange rate is stored as fields in the Trip
class which is managed by the TripManager
. All fixed expenses, on the other hand, is managed by the FixedExpenseManager
.
The following Class Diagram shows the association between relevant classes of this feature.
FixedExpenseManager
and its relevant classes.The Activity Diagram below summarises what happens when the user adds a fixed expense entry using the addexpense
command.
addexpense
commandWhen a user enters the addexpense
command, the Logic
Component parses the user input and creates an AddExpenseCommand
object. [Design-Logic]
The following steps describes the execution of the AddFixedExpenseCommand:
-
When
execute()
of theAddExpenseCommand
is called, the current exchange rate is obtained fromTripManager
throughModelManager
. -
A new
FixedExpense
object is created. The amount will be converted to SGD if it is in foreign currency. -
The newly created
FixedExpense
object is added to theFixedExpenseManager
through theModelManager
’saddFixedExpense()
method. -
The total sum of all expenses is obtained by calling the
getTotalExpense()
method. -
The budget of the trip is obtained by calling the
getBudget()
method. -
The remaining budget is calculated.
-
A
CommandResult
object which consists of a contains the success message along with the remaining budget is created and returned.
The following sequence diagram describes the execution of the AddExpenseCommand
when its execute()
method is called.
addexpense
command
The lifeline for the This sequence diagram does not take into consideration the possible exceptions which might occur during the |
4.8.2. Design Consideration
Aspect: Which class to store the trip’s budget and fixed expense
Pros | Cons | |
---|---|---|
Option 1 (Current): |
Follows the Separation of Concerns (SoC) principle. The budget for the trip is an attribute of the trip. Thus, only the |
The |
Option 2: |
Faster to implement as calculations for the remaining budget can be done internally in the |
Breaks the Single Responsibility Principle (SRP) as the |
Reasons for choosing option 1:
-
Option 1 follows good coding practices and principles (the SoC and SRP) which makes it more ideal.
-
The implementation of this feature is done quite early on, where our team has more flexibility in terms of deadline. Thus, we can afford to spend more time on option 1’s implementation.
4.9. Progress Checker
(Contributed by Joshua Lay)
This feature allows the user to keep track of the progress of his/her planning. It integrates multiple features to show the user what has been done and what needs to be done for his/her trip. The command to check the current progress is status
. The following aspect of the trip will be shown to the user:
-
Accommodation
- Accommodation coverage -
Schedule
- Time clash in the schedule -
PackingList
- Number of items packed or yet to be packed -
Expense
- Remaining budget
4.9.1. Rationale
This feature is added because as a travel planning application, the user would want to know his progress when planning for a trip. Thus, information on what is done and what needs to be done will help the user gauge his planning progress. The user would also want to know if they have forgotten to plan for any aspect of a trip which will be provided by this feature.
4.9.2. Current Implementation
The following Activity Diagram summarizes what happens when a user enters the status
command.
status
commandWhen a user enters the status
command, the Logic
Component parses and creates a CheckStatusCommand
object. (See [Design-Logic]).
The execution of the CheckStatusCommand
undergoes the following steps.
-
The
ModelManager
’sgetStatus()
will first be called. -
The
ModelManager
calls thegetScheduleStatus()
method of theTripManager
. -
The
ModelManager
calls thegetStatus()
method of thePackingListManager
. -
The
ModelManager
calls thegetStatus()
method of theFixedExpenseManager
. -
The
ModelManager
calls thegetStatus()
method of theAccommodationBookingManager
. -
After all the required data is obtained, the
ModelManager
will return the data to theCheckStatusCommand
. -
The
CheckStatusCommand
will then create a newCommandResult
object using the data obtained and return thisCommandResult
object.
CheckStatusCommand
The lifeline for the This sequence diagram does not take into consideration the possible exceptions which might occur during the |
4.9.3. Design Consideration
We do not have other implementation options for this feature as the current implementation is the only option that we came up with. It is also a good option because it follows good coding principles such as the Law of Demeter (LoD). In our implementation, each object only calls the methods of other objects that it is directly associated with.
E.g. the CheckStatusCommand
object only calls the the ModelManager
object’s getStatus()
method and the ModelManager
object only calls the the PackingListManager
object’s getStatus()
. The CheckStatusCommand
object does not know or have access to the getStatus()
method of the PackingListManager
object.
4.10. 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 [Implementation-Configuration]) -
The
Logger
for a class can be obtained usingLogsCenter.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
4.11. Configuration
Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json
).
5. Documentation
Refer to the guide here.
6. Testing
Refer to the guide here.
7. Dev Ops
Refer to the guide here.
Appendix A: Product Scope
(Contributed by Teng Le)
Target user profile:
-
want to micromanage all parts of their trips
-
meticulously plan all details of the trip before leaving
-
is inexperienced in planning for overseas trips
-
prefer to have everything in one application
-
want to manage their trip without an internet connection
-
prefer desktop apps over other types
-
can type fast
-
prefers typing over mouse input
-
is reasonably comfortable using [cli] apps
Value proposition:
-
An all in one travel planner and manager, that guides the user from head to tail in planning for an overseas trip. Even those who have never planned for a trip before will be able to focus on enjoying their trip while the app guides them in planning and managing the perfect overseas trip.
-
E.T. can manage trips faster than a typical mouse/GUI driven app.
Appendix B: User Stories
(Contributed by Charlotte)
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
|
Organised traveller |
Add activities to my daily itinerary |
Plan for my trip |
|
Spendthrift traveller |
Notified if my spending goes beyond my planned levels |
Adjust my budget and expenses |
|
Traveller |
Get my expenses to automatically converted to SGD |
Avoid manual currency conversion |
|
Traveller |
Get my expenses to automatically converted to SGD |
Avoid manual currency conversion |
|
Traveller |
Record my spending |
See amount spent each day/trip and balance left for each day/trip |
|
Forgetful user |
Make a checklist for items to bring |
Pack without forgetting anything |
|
Lazy traveller |
Have a built-in standard packing list |
Have recommendations on what to bring on the trip. |
|
Cautious Traveller |
Be notified if I miss out any dates I did not plan on accommodation |
Account my accommodation for every night |
|
Forgetful traveller |
Keep track of my flight timings |
Avoid being late for my flight |
|
Inexperienced planner |
Know what did I miss out from my travel plan |
Be reminded and plan for it |
|
New User |
Have a quick built-in help guide |
Get started on using the application quickly |
|
Traveller |
Be able to print my itinerary |
Bring it around in my travels if my laptop is not easily accessible |
|
Command Line enthusiast |
Press |
Be more efficient |
|
User who likes customization |
Change my application into different colour themes |
Make my application’s GUI visually appealing to me |
|
Budget traveller |
Set an individual budget for each day |
Stay within my budget |
|
User |
Have a calendar planner in the application |
Have reference to the dates of the year |
{More to be added}
Appendix C: Use Cases
(Contributed by Joshua Wee)
Trip Planner
UC01: Set trip - Sets a trip in the application System: E.T. Actor: User Preconditions: There should be no other trip existing Guarantees: - A new trip will be added to the trip list upon successful command. MSS: 1. User set a trip by providing details 2. E.T. sets the current trip 3. E.T. displays the set trip on dashboard Use case ends. Extensions: 1a. Incomplete details are given. 1a1. E.T. shows an error message. Use case resumes at step 3. 2a. The trip list is empty. 2a1. E.T. shows an empty page. Use case resumes at step 3. UC02: Check trip readiness System: E.T. Actor: User Preconditions: A trip must be existing. Guarantees: - E.T. informs the user of incomplete preparations. MSS: 1. User request for a preparation check 2. E.T. creates a popup that shows the list of things that needs to be completed Use case ends.
Packing List
UC03: Add item to Packing list System: E.T. Actor: User Preconditions: A trip must be existing. Guarantees: - A new packing list would be created upon successful command. MSS: 1. User requests to create a new trip. 2. User navigates to the packing list tab. 3. E.T. shows the packing list. 4. User adds an item to the packing list. 5. E.T. shows the updated packing list. Use case ends. Extensions: 3a. The packing list is empty. 3a1. E.T. shows an empty list. Use case resumes at step 4. 4a. Incomplete details are given. 4a1. E.T. shows an error message. Use case resumes at step 4.
Scheduling
UC04: Schedule an activity System: E.T. Actor: User Preconditions: A trip must be existing. Guarantees: - A new schedule entry would be created upon successful command. MSS: 1. Users navigates to the schedule tab 2. E.T. displays the current existing schedule entries 3. Users create a new schedule entry. 4. E.T. adds a scheduled entry to the schedule list. 5. E.T. shows the updated scheduled entries. Use case ends. Extensions: 2a. Incomplete details are given. 2a1. E.T. shows an error message. Use case resumes at step 1. 4a. Incomplete details are given. 4a1. E.T. shows an error message. Use case resumes at step 4.
Fixed Expense Manager
UC05: Add expenses System: E.T. Actor: User Preconditions: A trip must be existing. Guarantees: - Any expense will be added to the trip upon successful command. - Current and future expenses will be flagged if it exceeds the budget set for the trip. MSS: 1. User requests to create a new expense entry. 2. User navigates to the expense manager tab. 3. E.T. shows existing expenses for the current trip. 4. User adds a new expense for the current trip. 5. E.T. shows the updated expenses for the trip. Use case ends. Extensions: 3a. The expense list is empty 3a1. E.T. shows an empty page. Use case resumes at step 4. 4a. Incomplete details are given. 4a1. E.T. shows an error message. Use case ends. 4b. Expenses are entered by the user in the foreign country’s currency when the conversion rate is not set. 4b1. E.T. shows an error message. Use case ends.
Accommodation
UC06: Add accommodation into a trip System: E.T. Actor: User Preconditions: A trip must be existing Guarantees: - Accommodation will be added into a list upon successful command. MSS: 1. User navigates to the accommodation tab. 2. UI shows the accommodation tab and list 3. User requests to create a new accommodation booking. 4. E.T. shows the successful addition to the accommodation list. 5. E.T. shows an updated list of accommodations. Use case ends Extensions: 3a. The is no accommodation booking 3a1. E.T. show an empty list Use case resumes at step 4 4a. Incomplete details are given. 4a1. E.T. shows an error message. Use case ends.
Appendix D: Non Functional Requirements
(Contributed by Charlotte)
-
Application should work on any mainstream OS as long as it has Java 11 or above installed.
-
Application should be able to one month’s worth of trip data without any 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.
-
Application should be easy to use for a new user when following the User Guide.
-
Application should work without requiring an installer.
-
Application should not depend on a remote server.
-
Application should be for a single user i.e. (not a multi-user product).
-
Application should not require an online connection.
Appendix E: Glossary
(Contributed by Joshua Lay)
- E.T.
-
An abbreviation for Easy Travel, the name of the application.
- CRUD
-
In computer programming, create, read, update, and delete are the four basic functions of persistent storage
- Command Line Interface
-
Windows, Linux, Unix, macOS.
- Command Pattern
-
It is a Design Pattern that lets you encapsulate actions within Java classes. Of which, each class has an "execute()" method which is declared in the Command interface the class implements.
- Facade Pattern
-
Facade Pattern is a structural design pattern that provides a simplified (but limited) interface to a complex system of classes, library or framework. While decreasing the overall complexity of the application, it also helps to move unwanted dependencies to one place.
- Generics
-
Java’s type system to allow "a type or method to operate on objects of various types while providing compile-time type safety".
- Graphical User Interface
-
A visual display shown on the screen.
- JavaFX
-
is a software platform for creating and delivering desktop applications, as well as rich Internet applications (RIAs) that can run across a wide variety of devices.
- JavaScript Object Notation
-
A lightweight data-interchange format which is easily readable and writable.
- Mainstream OS
-
Windows, Linux, Unix, macOS
- Object-Oriented Programming
-
A type of computer programming (software design) in which programmers define the data type of a data structure, and also the types of operations (functions) that can be applied to the data structure.
- Prefix
-
The term that comes before each parameter in the command. For example, the prefix in
country/COUNTRY
iscountry/
. - Prefix Name
-
The word that comes before
/
in the prefix. For example, the prefix name incountry/COUNTRY
iscountry
. - Stream
-
A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result.
Appendix F: Instructions for Manual Testing
(Contributed by Joshua Lay)
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. |
F.1. Launch and Shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder
-
Double-click the jar file Expected: Shows the GUI with a set of schedules. The window size may not be optimum.
-
-
Saving window preferences
-
Resize the window to an optimum size. Move the window to a different location. Close the window.
-
Re-launch the app by double-clicking the jar file. Expected: The most recent window size and location is retained.
-
F.2. Adding/Setting
F.2.1. Adding Activities
-
Add a new activity to E.T.
-
Prerequisites: Arguments are valid and compulsory parameters are provided. The Activity added must be within the time frame of the trip. No duplicate Activity in the Trip.
-
Test case:
addactivity title/Osaka Castle View duration/1 location/Osaka tag/expensive tag/sightseeing
-
Expected: Adds an activity with title of
Osaka Castle View
, with duration of1
hour, a location ofOsaka
and tags ofexpensive
andsightseeing
.
-
-
Test case
addactivity title/Osaka Castle
-
Expected: No activity is added. Error details shown in feedback display.
-
-
Other incorrect add commands to try:
addactivity duration/1
,addactivity location/Singapore
,addactivity tag/testing
-
Expected: Similar to previous test case.
-
-
F.2.2. Setting Trip
-
Sets a new trip to Easy Travel
-
Prerequisites: Arguments are valid and compulsory parameters are provided. A Trip must not be set
-
Test case:
settrip title/Graduation Trip budget/5000 exchangerate/1.03 startdate/28-09-2020 enddate/05-10-2020
-
Expected: Sets a trip with title
Graduation Trip
, with budget of5000
, exchange rate of1.03
, startdate of28-09-2020
and enddate of05-10-2020
.
-
-
Test case
settrip title/Graduation Trip
-
Expected: No Trip is set. Error details shown in the feedback display.
-
-
Other incorrect set commands to try:
settrip budget/5000
,settrip exchangerate/1.03
,settrip startdate/28-09-2020
,settrip enddate/05-10-2020
-
Expected: Similar to point 3.
-
-
F.2.3. Adding Accommodation
-
Adds a new accommodation to Easy Travel
-
Prerequisites: Arguments are valid, compulsory parameters are provided. The Accommodation added must be within the time frame of the trip. No Duplicate Accommodation in the list
-
Test case:
addacc name/JW Marriott Hotel loc/KL startday/3 endday/4 remark/Check-in at 3pm.
-
Expected: Adds an accommodation with name of
JW Marriott Hotel
location ofKL
, startday of3
, endday of4
and remark ofCheck-in at 3pm
.
-
-
Test case
addacc name/JW Marriott Hotel
-
Expected: No Accommodation is set. Error details shown in the feedback display.
-
-
Other incorrect set commands to try:
addacc loc/KL
,addacc startday/2
,addacc endday/4
,addacc remark/Check-in at 3pm.
-
Expected: Similar to point 3
-
-
F.2.4. Adding Transportation
-
Adds a new transportation to Easy Travel
-
Prerequisites: Arguments are valid, compulsory parameters are provided. The Transportation added must be within the time frame of the trip. No Duplicate Transportation in the list.
-
Test case:
addtransport mode/plane startloc/Singapore endloc/Japan starttime/04-10-2020 17:00 endtime/06-10-2020 00:00
-
Expected: Adds an transportation with mode
plane
, startloc asSingapore
, endloc asJapan
, starttime as04-10-2020 17:00
and endtime as06-10-2020 00:00
.
-
-
Test case
addtransport mode/plane
-
Expected: No Transportation is set. Error details shown in the feedback display.
-
-
Other incorrect set commands to try:
addtransport startloc/Singapore
,addtransport endloc/Japan
,addtransport starttime/20-03-2020 17:00
,addtransport endtime/21-03-2020 00:00
-
Expected: Similar to point 3
-
-
F.2.5. Adding Item in Packing List
-
Adds a new Item to Easy Travel
-
Prerequisites: Arguments are valid and compulsory parameters are provided. No Duplicate Items are in the list
-
Test case:
additem name/Tshirts quantity/5 category/clothes
-
Expected: Adds an item with name of
Tshirts
quantity of5
, category ofclothes
.
-
-
Test case
additem name/Tshirts
-
Expected: No Item is set. Error details shown in the feedback display.
-
-
Other incorrect set commands to try:
addacc loc/KL
,additem quantity/5
,addacc category/basics
-
Expected: Similar to point 3
-
-
F.2.6. Adding Preset in Packing List
-
Adds a new Preset to Easy Travel
-
Prerequisites: Arguments are valid and compulsory parameters are provided.
-
Test case:
addpreset swimming
-
Expected: Adds a new preset of
swimming
.
-
-
Test case
addpreset Tshirts
-
Expected: No preset is set. Error details shown in the feedback display.
-
-
F.2.7. Adding Fixed Expense in Fixed Expense List
-
Adds a new Fixed Expense to Easy Travel
-
Prerequisites: Arguments are valid and compulsory parameters are provided. No Duplicate Fixed Expense must exist in the list
-
Test case:
addexpense amount/1500 currency/sgd description/Plane Tickets category/transport
-
Expected: Adds a fixed expense with amount of
1500
currency ofsgd
, description ofPlane Tickets
and category oftransport
.
-
-
Test case
addexpense amount/1500
-
Expected: No Fixed Expense is set. Error details shown in the feedback display.
-
-
Other incorrect set commands to try:
addexpense currency/sgd
,addexpense description/Plane Tickets
,addexpense category/transport
-
Expected: Similar to point 3
-
-
F.3. Editing
F.3.1. Editing Activity
-
Edits a current Activity in Easy Travel
-
Prerequisites: Arguments are valid, compulsory parameters are provided and activity must exist in the activity list. The Activity edited must be within the time frame of the trip. No duplicate Activity in the list.
-
Test case:
editactivity 1 title/Shopping duration/2
-
Expected: Edits an activity in index
1
in the displayed activity list with title ofShopping
, currency ofsgd
, description ofSQ Flight
and category oftransport
.
-
-
Other incorrect set commands to try:
editactivity 1000000000 title/Shopping
Expected: No Activity is edited. Error details shown in feedback display.
-
F.3.2. Editing Fixed Expense
-
Edits a current Fixed Expense in Easy Travel
-
Prerequisites: Arguments are valid, compulsory parameters are provided and fixed expense must exist in the fixed expense List. No Duplicate Fixed Expense in the list.
-
Test case:
editexpense 1 amount/3000 currency/sgd description/SQ Flight category/transport
-
Expected: Edits a fixed expense in index
1
of the fixed expense list with amount of3000
, currency ofsgd
, description ofSQ Flight
and category oftransport
.
-
-
Other incorrect set commands to try:
editexpense 1 category testing
-
Expected: No Fixed Expense is edited. Error details shown in feedback display.
-
-
Appendix G: Effort
Creating Easy Travel was fairly difficult and required much effort from all the team members. We communicated a lot as a team. However, it was difficult because of quarantine measures imposed by the government during this period due to the COVID-19 situation. Nonetheless, we persevered through, and thanks to technology, we were still able to communicate through regular online meetings. Through our consistent communication, we were able to come up with our product, Easy Travel. In addition, we managed to accumulate 32,000 lines of code combined. This showcases our hard work and contributed to into producing Easy Travel.
G.1. Major Enhancement
Easy Travel has many enhancement from AB3. This following points will highlight some of the major enhancement that Easy Travel has.
-
From just keeping track of contacts in AB3, Easy Travel is a major upgrade as it is a all-in-one application that allows the user to keep track of different aspects of planning for a trip. These aspects includes activity, transport bookings, packing list, etc.
-
Furthermore, Easy Travel’s has additional features that complements the list management features. Notably, the status, automated tab switching, sorting, and schedule features. These features meant that our app varies greatly from what AB3 has to offer in terms of user experience. We designed these features primarily with the user’s needs in mind to provide the user with a platform that would ease the pain of planning for an overseas trip.
G.2. Challenges
(Contributed by Catherine)
Throughout the development of Easy Travel, we faced many challenges. The following points will describe these challenges what how did we deal with them.
Challenge 1:
The first challenge we faced was the large increase in the number of entities to code and manage.
-
While AB3 deals with only one (
Person
) model object, Easy Travel deals with multiple (Trip
,Activity
,TransportBooking
,AccommodationBooking
,FixedExpense
,PackingListItem
andDayScheduleEntry
) model objects. Thus, even though we were able to refactor some aspects ofPerson
intoTrip
, we had to create the rest from scratch. -
Moreover, The
Ui
of AB3 only contains one panel (ListPanel
). On the other hand, Easy Travel has 7 panels (ScheduleTabPanel
,ActivityTabPanel
,AccommodationTabPanel
,TransportationTabPanel
,PackingListTabPanel
,FixedExpenseTabPanel
,HelpTabPanel
). This is a big change from AB3’sUI
. Additionally,FixedExpenseTabPanel
contains aPieChart
, which gives the user a better visual of their expenses breakdown. -
Furthermore, we have multiple new windows, the
StatusWindow
andListPresetWindow
. -
The copious amount of entities meant that a larger amount of time would be necessary to code and implement these entities.
How we solve it:
To overcome this challenge, our team placed heavy emphasis on team communication and efficient division of workload such that we can complete our part in the shortest time possible. In the end, we were able to overcome this challenge due to good team spirit and member contributions. Our effort can be seen from the 32,000 lines of code that we have completed in less than two months.
Challenge 2:
Initially, we wanted to allow the user to edit the dates of the trip, once the trip is set. However, if we allowed the user to do so, there will be complications for the Schedule, Accommodation Bookings and Transportation Bookings feature. This is because all three features depend on the start and end date set by the trip. Hence, if we allowed the user to edit the dates of the trip, it could result in complicated code and bugs.
How we solve it:
We decided to prevent the user from editing the start and end dates of the trip. If the user wants to edit the trip dates, he/she has to delete the trip and start again with the new dates which as warned in the User Guide. We felt that this decision was justified because we have limited time to complete our project and we want to work on more meaning features instead of this obscure problem.
G.3. Conclusion
Overall, we managed to achieve our goal, which was to create an application that can help ease the pain of planning for a trip. We created an all-in-one trip manager, a user interface that is neat and organised, and implemented user-focused features.