By: AY1920S2-CS2103T-W13-2      Since: Feb 2020      Licence: MIT

1. Introduction

1.1. Product Description (Hui Ming)

Morpheus is a desktop application that aims to facilitate the administrative work of hotel services as a hotel room management system. The system will also provide statistics and reports, constructed from the analysis of the details in the user-provided database. Most of the user interaction occurs via a CLI (Command Line Interface).

Ui
Figure 1. Morpheus UI

1.2. Purpose (Hui Ming)

This Developer Guide describes the architecture and software design of Morpheus. The intended audience is the developers, designers and software testers who wish to understand, maintain & upgrade the desktop application.

1.3. How to navigate this document

  • This section shows you how to read and understand this document.

    • Any text in markup suggests it is a code snippet.

    • A link like this will take you to the link destination when clicked.

This is a useful tip to help optimize your experience using Morpheus.
This is important information to take note of!

2. Setting up

Refer to the guide here.

3. Design

3.1. Architecture (Sanchari)

OverallArchitecture
Figure 2. Architecture Diagram

The Architecture Diagram given above explains the high-level design of the App.

Morpheus closely follows the Command Pattern design of software.
This is a quick representation of how the Command Pattern works:
Client → Invoker → CommandQueue → ExecuteCommand

In this case, the Application (Client) which creates and adds a command object to the Logic Manager (Invoker). The Invoker then executes the command objects by calling Command#execute().

Given below is a quick overview of the components in the architecture of the software.

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

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

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

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

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

UI: The UI of the App.

  • Presents App data in a GUI.

  • Receives commands from the user.

Logic: The command executor.

  • Parses the commands entered by user.

  • Adds command objects to command queue.

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

  • Executes actions indicated by commands on the data in-memory.

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

Each of the four components

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

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

How the architecture components interact with each other

The Sequence Diagram below shows an overview how the components interact with each other for the scenario where the user issues the command deleteroom.

ArchitectureComponentDiagram
Figure 3. Component interactions for deleteroom command

The sections below give more details of each component.

3.2. UI component (Johnny)

UIDiagram
Figure 4. Structure of the UI Component

API : Ui.java

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

  • Receive command result and change user view accordingly.

Below is diagram for how UI extract command result for changing view.

commandSwitchUi
Figure 5. Command work flow for MainWindow

3.3. Logic component

LogicClassDiagram
Figure 6. Structure of the Logic Component

API : Logic.java

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

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

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

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

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

Given below is the Sequence Diagram for interactions within the Logic component for the execute("deleteroom") API call.

LogicSequenceDiagram
Figure 7. Interactions Inside the Logic Component for the deleteroom Command

3.4. Model component

ModelDiagram
Figure 8. Structure of the Model Component

API : Model.java

The Model,

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

  • stores the Address Book data.

  • stores the Hotel data.

  • stores the BookKeeper data

  • exposes an unmodifiable ObservableList<Person> , ObservableList<Room> , ObservableList<Booking> , ObservableList<AvailableService>, ObservableList<Bill> 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.

  • exposes Hotel’s data.

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

As a more OOP model, we can store a Tag list in Address Book, which Person can reference. This would allow Address Book to only require one Tag object per unique Tag, instead of each Person needing their own Tag object. An example of how such a model may look like is given below.

BetterModelClassDiagram

3.5. Storage component (Sanchari)

StorageDiagram
Figure 9. Structure of the Storage Component

API : Storage.java

The Storage component is responsible for serializing Model and deserializing Json data to facilitate reading and writing into the database.
The Storage component can:

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

  • can save the Address Book data in json format and read it back.

  • can save Hotel data in json format and read it back.

  • can save BookKeeper data in json format and read it back.

3.6. Common classes

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

4. Implementation

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

4.1. Hotel Initialization (Sanchari)

The following steps show how to set up a hotel by adding guests, rooms and services:

4.1.1. AddGuestCommand

Implementation

This command adds a guest into the hotel using their name, guest ID, phone and email.

The following steps show how the add guest feature works:

  1. The addguest command entered by the user is parsed and the different fields are tokenized.

  2. AddGuestCommand#execute(Model model) is invoked which checks for validity of the entered parameter values.

  3. The command is then executed by creating a new Guest object using the parameter values entered and adding the Guest object into the Hotel.

  4. If successful, a CommandResult object is created to show a success message in the feedback box of the ui.

The diagram below shows the class diagram for AddGuestCommand.

AddGuestClass
Figure 10. Class Diagram for AddGuestCommand
Design Considerations
  • Alternative 1 (current choice): Creates a new Guest object in AddGuestCommandParser.

    • Pros: Simpler to test and understand.

    • Cons: Command object should not know details about model i.e. Person.

  • Alternative 2: New Guest object is created and added to hotel in model.

    • Pros: Command has no knowledge of Model and its attributes.

    • Cons: More prone to error.

4.1.2. AddService Command

Implementation

The following steps show how the AddService command is implemented:

  1. The command from user is parsed and undergoes checks for the validity of the SERVICE_ID, COST and DESCRIPTION.

  2. If the parameters are valid, AddServiceCommand#execute(Model model) is invoked, which checks if the service id exists.

  3. If the service id does not exist, a AvailableService object is created and Model#add(AvailableService service) is called to add an available service to hotel.

  4. If successful, a CommandResult object is created to show a success message in the feedback box of the ui.

The diagram below shows the class diagram for AddServiceCommand

AddServiceClass
Figure 11. Class Diagram for AddServiceCommand
Design Considerations
  • Alternative 1 (current choice): Creates a new Service object in AddServiceCommandParser.

    • Pros: Simpler to test and understand.

    • Cons: Command object should not know details about model i.e. Service.

  • Alternative 2: New Service object is created and added to hotel in model.

    • Pros: Command has no knowledge of Model and its attributes.

    • Cons: More prone to error.

4.1.3. AddRoomCommand

Implementation

This command adds a room into the hotel using the room number, tier and the cost of the room.

The following steps show how the add room feature works:

  1. The addroom command entered by the user is parsed and the different fields are tokenized.

  2. AddRoomCommand#execute(model) is invoked which checks for validity of the arguments.

  3. If all arguments are valid, a new Room object is created using the tokenized arguments and it is added into the hotel.

  4. If successful, a CommandResult object is created to show a success message in the feedback box of the ui.

The diagram below shows the class diagram for AddRoomCommand

AddRoomClassDiagram
Figure 12. Class Diagram for AddRoomCommand
Design Considerations
  • Alternative 1 (current choice): Rooms are stored in an ObservableList in Hotel.

    • Pros: Better OOP design.

    • Cons: Harder to test.

  • Alternative 2: Rooms are stored in an ObservableList in Model.

    • Pros: Simpler to test and understand.

    • Cons: Model is at a higher abstraction level and should not have knowledge of individual rooms.

The Diagram below shows the sequence diagram for AddRoomCommand. All Initialization commands above are similar in their interactions with the Section 3.3, “Logic component” and Section 3.4, “Model component”.

AddRoomSequenceDiagram
Figure 13. Sequence Diagram for AddRoomCommand

The Diagram below shows the general activity sequence of the initialization feature.

AddCommandDiagram
Figure 14. Activity Diagram of Hotel Initialization

4.2. Hotel Services (Daniel)

4.2.1. Reserve Command

Implementation

This command makes a reservation under the specified guest’s name for the specified duration.

The following steps show how the Reserve command is implemented.

  1. The command from the user is tokenized and parsed.

  2. If there are no missing tokens, ReserveCommand#execute(Model model) is invoked which checks if guest ID, room ID exists in the database and if there are any clashes with other bookings.

  3. A new Booking object is created and added into the hotel database.

  4. If the above is successfully executed, this will return a CommandResult object to show a success message.

Design Considerations

Below describes ideas that were considered when designing the command.

  • Alternative 1 (current choice): Reservation is stored in 1 list.

    • Pros: Easy to loop through all reservation to make sure there is no clash between them.

    • Cons: Querying the schedule for a specific room require to iterate through all the reservation.

  • Alternative 2: Reservation store for each room.

    • Pros: Each room have their own schedule.

    • Cons: Harder to implement if we want to find an empty room for certain period of time.

ReserveClassDiagram
Figure 15. Class Diagram for ReserveCommand
ReserveSequenceDiagram
Figure 16. Sequence Diagram for ReserveCommand

4.2.2. Checkin Command

This command checks in guest either with a room number, guest’s name, and the end date of the stay. Or by providing the booking ID.

Implementation

The following steps show how the CheckIn command is implemented.

  1. The command is parsed by CheckInCommandParser#parse(String args) into list of pattern there (room number, guest id, end date of the stay or booking id).

  2. If BOOKING_ID exists in the pattern, it will ignore the rest of the pattern and checkin using that booking id instead by creating CheckInByIdCommand

  3. The CheckInByIdCommand will invoke model#findBookingById(String BookigId) which will create a normal CheckInCommand

  4. CheckInCommand will call model#checkIn will be called.

  5. The list in the UI will be updated by calling model#updateFilteredRoomList(Predicate predicate)

  6. The room will be charged by calling model#chargeRoomCost(RoomId roomId, RoomCost roomCost, Stay stay).

  7. If all of the above is successfully executed, this will return a CommandResult object to show success message.

CheckInSequenceDiagram
Figure 17. Sequence Diagram for CheckInCommand
Design Considerations

Below describes ideas that were considered when designing the command.

  • Alternative 1 (current choice): Create a stay object which differentiate between the current stay and reservation.

    • Pros: Could easily get the list of current stay.

    • Cons: Requires more planning since we have to maintain 2 list now (stay and reservation).

  • Alternative 2: Store all stay in a reservation object.

    • Pros: Simple to implement.

    • Cons: Could not differentiate between stay and reservation unless there is another instance in the reservation object.

4.2.3. Checkout Command

This command checks out a guest from the hotel by providing a room number.

Implementation

The folowing steps show how the CheckOut command is implemented.

  1. The command is parsed by CheckOutCommandParser#parse(String args) into list of pattern there (room number).

  2. The CheckOutCommandParser will create CheckOutCommand

  3. CheckOutCommand will call model#checkOut will be called.

  4. The list in the UI will be updated by calling model#updateFilteredRoomList(Predicate predicate)

  5. The room will clean up the previous bill by calling model#deleteBill(RoomId roomId).

  6. If all of the above is successfully executed, this will return a CommandResult object to show success message.

4.2.4. Extend Command

This command extend the booking of a guest by providing room number and end date of the stay.

4.2.5. Implementation

  1. The command is parsed by ExtendCommandParser#parse(String args) into list of pattern there (room number and end date).

  2. The ExtendCommandParser will create ExtendCommand

  3. ExtendCommand will call model#extendRoom to extend the room in the hotel.

  4. ExtendCommand will call model#chargeExtendRoomCost to charge the room according to the room cost and number of extra nights.

  5. If this is successfully executer, this will return a CommandResult object to show success message.

4.3. Search feature (Tuan)

4.3.1. FindGuestCommand

Implementation

Currently this command only support searching for full name or/and id number.

The following steps show how the search guest feature works:

  1. The search command from the user is parsed into a list of pattern contained in the search command.

  2. The command then executes and filters the guest list based on the patterns.

The diagram below show how the search command store its pattern.

FindGuestCommand
Figure 18. Class diagram for FindGuestCommand

The diagram below shows the execution of the command:

SearchWorkflow
Figure 19. Activity Diagram of Search Feature
Design Considerations
  • Alternative 1 (current choice): Store pattern as list of name and id.

    • Pros: Simpler to test and understand.

    • Cons: Difficult to extend the implementation.

  • Alternative 2: Store pattern as a combination of Predicate.

    • Pros: Easy to implement and add more complicated pattern.

    • Cons: Harder to test, more prone to error.

4.3.2. FindRoomCommand

Implementation

Currently this command only support searching of room full name or/and id number, or room number.

The following steps show how the search guest feature works:

  1. The find room command from the user is parsed into a list of pattern contained in the find room command.

  2. The find room command then executes and filters the guest list based on the patterns.

The diagram below show how the findroom command store its pattern.

FindRoomCommand
Figure 20. Class diagram for FindGuestCommand

The diagram below shows the execution of the command:

4.3.3. FindBookingCommand

Implementation

Currently this command only support searching of booking full name or/and id number, or room number.

The following steps show how the search guest feature works:

  1. The find booking command from the user is parsed into a list of pattern contained in the find booking command.

  2. The find booking command then executes and filters the guest list based on the patterns.

The diagram below show how the findbooking command store its pattern.

FindBookingCommand
Figure 21. Class diagram for FindGuestCommand

4.3.4. FindEmptyRoomCommand

Implementation

This command support finding empty rooms

The following steps show how the search feature works:

  1. The find empty room command from the user is parsed into a list of pattern contained in the find booking command.

  2. The find empty room command then executes and filters the guest list based on the patterns.

4.4. Billing System (Hui Ming)

The billing system is designed to aid hotel receptionists in their bookkeeping. It is oversen by the BookKeeper class, which keeps track of all bills in the hotel and facillitates in the manipulation of bills. The bills are kept in a UniqueBillList, which ensures that there are no duplicate bills in the BookKeeper class.

The structure of the billing system is shown in the class diagram below:

BillingClassDiagram
Figure 22. Class Diagram of Billing System

To utilize the billing system, users are provided with the following operations:

  • SetRoomCostCommand — Sets the cost of a room.

  • AddServiceCommand — Creates a chargeable service.

  • ChargeServiceCommand — Charges a guest for a requested service.

  • DeleteChargedServiceCommand — Removes a charged service from the bill of a guest.

  • FetchBillCommand — Fetches the bill of a guest, including the cost of the room.

The following activity diagram summarizes the typical procedure of billing a guest:

BillingActivityDiagram
Figure 23. Activity Diagram of Billing System

4.4.1. SetRoomCost Command (Hui Ming)

This section goes through the implementation and design considerations of the SetRoomCost command.

Implementation

The following steps show how the command is implemented:

  1. The command from the user is parsed and undergoes checks for the validity of the given ROOMNUMBER and COST.

  2. If the parameters are valid, SetRoomCostCommand#execute(Model model) is invoked, which checks if the given room exists.

  3. If the room exists, a RoomCost object is created and Model#setRoomCost(Room room, RoomCost roomCost) is called.

  4. Room##setCost(RoomCost roomcost) is then invoked to set the cost of the room by setting the 'roomCost' attribute of the Room object.

  5. If successful, a CommandResult object is created to show a success message in the feedback box of the ui.

The sequence diagram below illustrates how the SetRoomCost command works with the input setrcost rn/001 c/50:

SetRoomCostSequenceDiagram
Figure 24. Sequence Diagram of SetRooomCost Command
Design Considerations

Below describes ideas that were considered when designing the command.

  • Alternative 1 (current choice): Store the cost of the room as an attribute in the Room object.

    • Pros: Application of OOP concepts.

    • Cons: Requires a deeper understanding of the Logic & Model components in order to implement.

  • Alternative 2: Store the costs of rooms in a separate list (e.g. as a HashMap) in the Hotel component.

    • Pros: Simple to implement.

    • Cons: Might limit the relationship between the rooms and their costs.

4.4.2. AddService Command

The command is also a Hotel Initialization feature and is hence covered above in Section 4.1.2, “AddService Command”.

4.4.3. ChargeService Command (Hui Ming)

This section goes through the implementation and design considerations of the ChargeService command.

Implementation

The following steps show how the command is implemented:

  1. The command from the user is parsed and undergoes checks for the validity of the given PERSONID, ROOMNUMBER and SERVICEID.

  2. If the parameters are valid, ChargeServiceCommand#execute(Model model) is invoked, which checks if the given guest, room and service exist.

  3. If they exist, Model#chargeService(RoomId roomId, AvailableService service) is called which in following calls BookKeeper#chargeServiceToBill(RoomId roomId, AvailableService service).

  4. The bill for the corresponding room is retrieved and Bill#addService(AvailableService service) is then invoked by BookKeeper.

  5. The service is added to stored list of chargeable objects in the bill and its cost is added to the stored total in the bill.

  6. If successful, a CommandResult object is created to show a success message in the feedback box of the ui.

The sequence diagram below illustrates how the ChargeService command works with the input chargeservice i/A000000 rn/001 si/WC:

ChargeServiceSequenceDiagram
Figure 25. Sequence Diagram of ChargeService Command
Design Considerations

Below describes ideas that were considered when designing the command.

  • Alternative 1 (current choice): Store the charged services in an ArrayList and the total cost as a double in the bill.

    • Pros: Implementing the removal of charges services would be more direct and simple.

    • Cons: Have to be careful with the calculation of the total cost.

  • Alternative 2: Create another class to handle the list of charged services.

    • Pros: Calculation of the total cost would be less prone to errors.

    • Cons: Might cause the design of the application be unnecessarily complicated with many classes.

4.4.4. DeleteChargedService Command (Hui Ming)

This section goes through the implementation and design considerations of the DeleteChargedService command.

Implementation

The following steps show how the command is implemented:

  1. The command from the user is parsed and undergoes checks for the validity of the given PERSONID, ROOMNUMBER and SERVICEID.

  2. If the parameters are valid, DeleteChargedServiceCommand#execute(Model model) is invoked, which checks if the given guest, room, service and bill exist.

  3. If they exist, Model#deleteChargedService(RoomId roomId, AvailableService service) is called which in following calls BookKeeper#deleteChargedServiceFromBill(RoomId roomId, AvailableService service).

  4. The bill for the corresponding room is retrieved and Bill#deleteService(AvailableService service) is then invoked by BookKeeper.

  5. The service is removed from the stored list of chargeable objects in the bill and its cost is subtracted from the stored total in the bill.

  6. If successful, a CommandResult object is created to show a success message in the feedback box of the ui.

The sequence diagram below illustrates how the DeleteChargedService command works with the input deletecservice i/A000000 rn/001 si/WC:

DeleteChargedServiceSequenceDiagram
Figure 26. Sequence Diagram of DeleteChargedService Command
Design Considerations

Below describes ideas that were considered when designing the command.

  • Alternative 1 (current choice): Remove any one instance of the service in the list of charged services.

    • Pros: Simple to implement.

    • Cons: Does not make sense logically.

  • Alternative 2: Remove the last instance of the service that was inserted.

    • Pros: Makes sense logically.

    • Cons: Need to keep track of the index, which unnecessarily complicates the program as the output would be the same.

4.4.5. FetchBill Command (Hui Ming)

This section goes through the implementation and design considerations of the FetchBill command.

Implementation

The following steps show how the command is implemented:

  1. The command from the user is parsed and undergoes checks for the validity of the given PERSONID and ROOMNUMBER, if provided.

  2. If the parameter/s are valid, FetchBillCommand#execute(Model model) is invoked, which checks if the given guest, room if ROOMNUMBER is provided, and bill/s exist.

  3. If they exist, different methods are called depending on whether ROOMNUMBER is provided:

    • If ROOMNUMBER is provided:

      1. Model#findBill(RoomId roomId) is called to retrieve the bill for specified room.

      2. Bill#getBillTotal() is next called to get the total cost of expenses.

      3. Model#updateFilteredBillList(Predicate predicate) is then called to update the bill tab to show the bill details of the room.

      4. If successful, a CommandResult object is created to show a success message in the feedback box of the ui.

    • If ROOMNUMBER is not provided:

      1. Model#getGuestBillsTotal(PersonId personId) is called to get the total of all the bills of the guest.

      2. Model#updateFilteredBillList(Predicate predicate) is then called to update the bill tab to show all the bills belonging to the guest.

      3. If successful, a CommandResult object is created to show a success message in the feedback box of the ui.

The sequence diagram below illustrates how the FetchBill command works with the input fetchbill i/A000000 rn/001:

FetchBillSequenceDiagram
Figure 27. Sequence Diagram of FetchBill Command
Design Considerations

Below describes ideas that were considered when designing the command.

  • Alternative 1 (current choice): Allow the user to fetch the bill of a room of all bills of a person with a single command.

    • Pros: Easier on user as they have lesser commands to remember.

    • Cons: More considerations for different scenarios are needed, causing the implementation to be more complicated.

  • Alternative 2: Have two separate commands to fetch the bill of a room and the bills of a person.

    • Pros: Easier to parse the parameters for the command.

    • Cons: User needs to remember more commands.

4.5. Logging

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

  • The logging level can be controlled using the logLevel setting in the configuration file (See Section 4.6, “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

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

Target user profile:

  • has a need to manage a significant number of hotel guests

  • needs to keep track of all guest information: checkins/services/bills

  • prefers to view all guest information in one window

  • prefers typing over mouse input

  • prefer desktop apps over other types

  • can type fast

  • is reasonably comfortable using CLI apps

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

Appendix B: User Stories (Sanchari & Hui Ming)

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

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

* * *

receptionist

see which rooms are empty

check guests into them

* * *

receptionist

get the bill details of guests

show the guests what they purchased

* * *

busy receptionist

type as few things as possible

add in information fast

* * *

receptionist

see which guests are VIPS

treat these guests with extra care

* * *

receptionist

add people into the database

track hotel guests during their stay

* *

receptionist

group people together

see which guests are in the same group/family

* *

receptionist

change the tag of a room to served

know which rooms' requests have been fulfilled

* *

receptionist

keep track of rooms that ordered room service

charge them accordingly

* *

hotel staff

quickly see which rooms have been checked out

go clean the rooms

`* * `

cleaning staff

quickly see rooms with the "clean my room tag"

prioritize cleaning those rooms

* *

receptionist

sort rooms into different categories

search for rooms more easily

* *

receptionist

apply discounts to customers' bills

charge customers according to the hotel’s ongoing promotions

* *

receptionist

keep track of the guests staying in each room

address them by name

* *

receptionist

compare two different rooms

see which room is more suitable for the guest

* *

receptionist

create shortcuts/presets

conveniently carry out routine tasks

* *

receptionist

see basic statistics

show my boss when they request for them

* *

receptionist

see as many information as possible

find out certain details quickly

* *

receptionist

be shown suggested keywords as I type

enter information quickly

* *

receptionist

execute the same command on different rooms

efficiently carry out my job

*

receptionist

see the online bookings that guests have made

efficiently check guests in

Appendix C: Use Cases (Hui Ming)

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

Use cases example:

C.1. Use Case: UC01 - Add a guest

MSS

  1. User requests to add a guest

  2. User supplies guest name, id, phone number, email & tags

  3. Morpheus adds the guest to the application

    Use case ends.

Extensions

  • 2a. The guest already exists in the application.

    • 2a1. Morpheus shows an error message.

      Use case ends.

C.2. Use Case: UC02 - Add a room

MSS

  1. User requests to add a room

  2. User supplies room number, tier and cost

  3. Morpheus adds the room to the application

    Use case ends.

Extensions

  • 2a. The room already exists in the application

    • 2a1. Morpheus shows an error message

      Use case ends.

C.3. Use Case: UC04 - Add a service

MSS

  1. User requests to add a service

  2. User supplies service id, description and cost

  3. Morpheus adds the service to the application

    Use case ends.

Extensions

  • 2a. The service already exists in the application

    • 2a1. Morpheus shows an error message

      Use case ends.

C.4. Use Case: UC05 - Reserve a room

MSS

  1. User requests to reserve a room

  2. User supplies guest id, room number, start and end dates of reservation

  3. Morpheus reserves the room

    Use case ends.

Extensions

  • 2a. The guest does not exist in the application

    • 2a1. Morpheus shows an error message

      Use case ends.

  • 2b. The room does not exist in the application

    • 2b1. Morpheus shows an error message

      Use case ends.

  • 2c. The room is already reserved/occupied

    • 2c1. Morpheus shows an error message

      Use case ends.

C.5. Use Case: UC06 - Check in a guest

MSS

  1. User requests to check in a guest

  2. User supplies guest id, room number end date of check out

  3. Morpheus marks the room as occupied

    Use case ends.

Extensions

  • 2a. The guest does not exist in the application

    • 2a1. Morpheus shows an error message

      Use case ends.

  • 2b. The room does not exist in the application

    • 2b1. Morpheus shows an error message

      Use case ends.

  • 2c. The room is already reserved/occupied

    • 2c1. Morpheus shows an error message

      Use case ends.

C.6. Use Case: UC07 - Check out a guest

MSS

  1. User requests to check out a guest

  2. User supplies room number

  3. Morpheus marks the room as unoccupied

    Use case ends.

Extensions

  • 2a. The room does not exist in the application

    • 2a1. Morpheus shows an error message

      Use case ends.

  • 2b. The room is not occupied

    • 2b1. Morpheus shows an error message

      Use case ends.

C.7. Use Case: UC08 - Extend the stay of a guest

MSS

  1. User requests to extend the stay of a guest

  2. User supplies room number and new date to check out

  3. Morpheus updates the period of time where the room is occupied

    Use case ends.

Extensions

  • 2a. The room does not exist in the application

    • 2a1. Morpheus shows an error message

      Use case ends.

  • 2b. The room is not occupied

    • 2b1. Morpheus shows an error message

      Use case ends.

  • 2c. The room is reserved by another guest

    • 2c1. Morpheus shows an error message

      Use case ends.

C.8. Use Case: UC09 - Charging a guest for a service

MSS

  1. User requests to charge a guest for a service

  2. User supplies guest id, room number and service id

  3. Morpheus charges the service to the bill of the guest

    Use case ends.

Extensions

  • 2a. The guest does not exist in the application

    • 2a1. Morpheus shows an error message

      Use case ends.

  • 2b. The room does not exist in the application

    • 2b1. Morpheus shows an error message

      Use case ends.

  • 2c. The service does not exist in the application

    • 2c1. Morpheus shows an error message

      Use case ends.

  • 2d. The guest is not checked into the specified room

    • 2d1. Morpheus shows an error message

      Use case ends.

C.9. Use Case: UC10 - Fetch the bills of a guest

MSS

  1. User requests to fetch the bill of a guest

  2. User supplies guest id

  3. Morpheus shows the total outstanding payment of the guest and the bill details

    Use case ends.

Extensions

  • 2a. The guest does not exist in the application

    • 2a1. Morpheus shows an error message

      Use case ends.

  • 2b. The guest does not have outstanding bills

    • 2b1. Morpheus shows an error message

      Use case ends.

C.10. Use Case: UC11 - Remove a charged service from a bill

MSS

  1. User requests to remove a charged service from a bill

  2. User supplies guest id, room number and service id

  3. Morpheus removed charged service from the bill of the guest

    Use case ends.

Extensions

  • 2a. The guest does not exist in the application

    • 2a1. Morpheus shows an error message

      Use case ends.

  • 2b. The room does not exist in the application

    • 2b1. Morpheus shows an error message

      Use case ends.

  • 2c. The service does not exist in the application

    • 2c1. Morpheus shows an error message

      Use case ends.

  • 2d. The guest does not have outstanding bills

    • 2d1. Morpheus shows an error message

      Use case ends.

  • 2e. The bill does not have the charged service

    • 2e1. Morpheus shows an error message

      Use case ends.

C.11. Use Case: UC12 - Search for a guest

MSS

  1. User requests to search for a guest

  2. User supplies guest id and/or name

  3. Morpheus shows a list of guests with matching id/names

    Use case ends.

C.12. Use Case: UC13 - Search for a room

MSS

  1. User requests to search for a room

  2. User supplies guest id and/or name and/or room number

  3. Morpheus shows a list of rooms with matching id/names/room bumbers

    Use case ends.

C.13. Use Case: UC14 - Search for a booking

MSS

  1. User requests to search for a guest

  2. User supplies guest id and/or name and/or room number

  3. Morpheus shows a list of bookings with matching id/names/room numbers

    Use case ends.

C.14. Use Case: UC15 - Delete a guest

MSS

  1. User requests to delete a guest

  2. User supplies index of guest or guest id

  3. Morpheus deletes the guest from the application

    Use case ends.

Extensions

  • 2a. The guest does not exist in the application

    • 2a1. Morpheus shows an error message

      Use case ends.

Appendix D: Non Functional Requirements

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

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

  3. Should be able to hold up to 1000 rooms without a noticeable sluggishness in performance for typical usage.

  4. Should be able to handle up to 10000 requests per day.

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

  6. Should not consume more than 200 megabytes of storage (should optimize encoded data).

  7. Should be able to restart without loss of data.

  8. Should be able to store back-ups data in case of breaking down.

Appendix E: Glossary

Mainstream OS

Windows, Linux, Unix, OS-X

Private contact detail

A contact detail that is not meant to be shared with others

Appendix F: Instructions for Manual Testing (Sanchari)

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

  1. Initial launch

    1. Download the jar file and copy into an empty folder

    2. Double-click the jar file
      Expected: Shows the GUI with a set of sample data. The window size may not be optimum.

  2. Saving window preferences

    1. Resize the window to an optimum size. Move the window to a different location. Close the window.

    2. Re-launch the app by double-clicking the jar file.
      Expected: The most recent window size and location is retained.

F.2. Adding a guest

  1. Adding a guest when all guests are listed.

    1. Prerequisites: List all persons using the switch guest command. Multiple guests in the list.

    2. Test case: addguest n/Joey i/J000000 p/12345679 e/joey@email.com t/VIP
      Expected: Guest Joey is added to the list. Details of the added Guest shown in the status message.

    3. Test case: addguest n/Jolene i/J000000 p/12345679 e/jolene@email.com t/VIP
      Expected: Guest Id clashes with an existing guest. No Guest is added. Error details shown in the status message.

    4. Other incorrect addguest commands to try: addguest, addguest i/P000000 p/12345679 e/joey@email.com
      Expected: Similar to previous.

F.3. Adding a room

  1. Adding a room when all rooms are listed.

    1. Prerequisites: List all rooms using the switch room command. Multiple rooms in the list.

    2. Test case: addroom rn/300 ti/GOLD c/300.00
      Expected: Room 300 is added to the list. Details of the added Room shown in the status message.

    3. Test case: addroom rn/300 ti/GOLD c/300.00
      Expected: Room Id clashes with an existing room. No Room is added. Error details shown in the status message.

    4. Test case: addroom rn/400 ti/Gold c/300.00
      Expected: Invalid Tier value. No Room is added. Error details shown in the status message.

    5. Other incorrect addroom commands to try: addroom, addroom rn/500 ti/BRONZE
      Expected: Similar to previous.

F.4. Adding a service

  1. Adding a service when all services are listed.

    1. Prerequisites: List all service using the switch service command. Multiple services in the list.

    2. Test case: addservice si/WC d/Wash clothes c/100.00
      Expected: Service WC is added to the list. Details of the added Service shown in the status message.

    3. Test case: addservice si/WC d/Other service c/100.00
      Expected: Service Id clashes with an existing service. No service is added. Error details shown in the status message.

    4. Test case: addservice si/WC c/100.00
      Expected: Invalid description value. No service is added. Error details shown in the status message.

    5. Other incorrect addservice commands to try: addservice, addservice c/190.00
      Expected: Similar to previous.

F.5. Reserving a room

  1. Adding a booking when all bookings are listed

    1. Prerequisites: List all the bookings by using the switch booking command. Multiple bookings shown.

    2. Test case: reserve i/i000000 rn/001 fd/2020-12-12 td/2020-12-24
      Expected: Room number 001 is reserved by person I000000 from 2020-12-12 to 2020-12-24

    3. Test case: reserve i/B000000 rn/001 fd/2020-12-13 td/2020-12-23
      Expected: There is a clash in booking dates for the same room. Error details shown in the result display box.

    4. Test case: reserve i/Bzagda rn/001 fd/2020-12-13 td/2020-12-23 Expected: No such person found. No booking made. Error details shown in the status message.

    5. Other incorrect reserve commands to try: reserve, reserve i/A000000 , reserve i/i000000 rn/004 fd/2012-12-12 td/2012-12-24

F.6. Checking in and out guests

  1. Dealing with check-ins and check-outs

    1. Prerequisites: List all bookings by using the command switch booking

    2. Test case: checkin i/i000000 rn/001 td/2020-12-24
      Expected: Guest i000000 is checked into room 001

    3. Test case: checkin i/B000000 rn/5602 td/2020-12-23
      Expected: There is no such room. Error message shown in result display box.

    4. Test case: checkout rn/001
      Expected: Guest is checked out of room 001

    5. Test case: checkout rn/009
      Expected: Room 009 has no guests. Error message is shown in the result display box.

    6. Other incorrect checkin/checkout commands to try: checkin, checkin i/A000000 , checkin i/i000000 rn/004 fd/2012-12-12 td/2012-12-24, checkout , checkout rn/000

F.7. Extending the stay of a guest

  1. Dealing with extension of a stay.

    1. Prerequisites: List all the stays by using the switch room command. Stays are shown in the rooms.

    2. Test case: extend rn/101 td/2020-04-20
      Expected: Room number 101 's stay is extended until 2020-04-20

    3. Test case: extend rn/006 td/2020-04-20
      Expected: There is no guest checked into room 006. Stay cannot be extended. Error details shown in the result display box.

    4. Test case: extend rn/001 fd/2012-12-12
      Expected: Invalid date. Date has passed. Stay cannot be extended. Error details shown in the result display box.

    5. Other incorrect extend commands to try: extend, reserve rn/000 , extend td/2012-12-12

F.8. Charging a service

Charging a service to the guest’s tab.
  1. Prerequisites: List all the stays by using the switch room command. Stays are shown in the rooms.

  2. Test case: chargeservice i/A000000 rn/004 si/WC
    Expected: Charges service with the ID WC for room 100 to the guest with ID A000000 's bill.

  3. Test case: chargeservice i/R000000 rn/004 si/WC
    Expected: Guest R000000 is not checked in. No service can be added to his bill. Error details shown in the result display box.

  4. Other incorrect chargeservice commands to try: chargeservice, chargeservice i/R000000 rn/000 si/WC , `chargeservice i/R000000 rn/100 si/DD

F.9. Fetching the bill of a guest

Retrieving the bill of a guest
  1. Prerequisites: List all the stays by using the switch room command. Stays are shown in the rooms.

  2. Test case: fetchbill i/A000000
    Expected: Shows the entire bill, consisting of all costs incurred, for guest with ID G1231231X 's stay up till present moment.

  3. Test case: fetchbill i/R000000
    Expected: Guest R000000 is not checked in. His bill cannot be shown. Error details shown in the result display box.

  4. Other incorrect fetchbill commands to try: fetchbill

F.10. Deleting service from a bill

Deleting a service from a bill
  1. Prerequisites: List all bills by using the switch bill command

  2. Test case: deletecservice i/G1231231X rn/100 si/WC Expected: Removes service with ID WC from guest with ID G1231231X 's bill for room 100

  3. Test case: deletecservice i/B000000 rn/100 si/WC Expected: Guest B000000 does not have the service WC in their bill. Error message shown in the result display box.

  4. Other incorrect deletecservice commands to try: deletecservice , deletecservice i/A000000 rn/000

F.11. Finding a guest

Finding a guest from the list
  1. Prerequisites: List all guests by using the switch guest command. Guests are listed.

  2. Test case: findguest i/A0000000 n/Alice Expected: Shows persons with name: Alice or ID: A1000000

  3. Test case: findguest Expected: Invalid command format. Error message is shown in the result display box.

  4. Other incorrect findguest commands to try: findguest i/ , findguest n/

F.12. Finding a room

Finding a room related to a guest’s reservation/stay
  1. Prerequisites: List all rooms by using the switch room command. Rooms are listed.

  2. Test case: findroom i/A000000 rn/001 n/Tuan Le Expected: Shows rooms booked by Guest with name: Tuan Le and/or ID: A000000

  3. Test case: findroom Expected: Invalid command format. Error message is shown in the result display box.

  4. Other incorrect findroom commands to try: findroom i/ , findroom n/

F.13. Finding a booking

Finding a booking made by a guest
  1. Prerequisites: List all bookings by using the switch room command. Rooms are listed.

  2. Test case: findbooking n/Alice rn/001 Expected: Shows booking of Alice or of room 001.

  3. Test case: findbooking Expected: Invalid command format. Error message is shown in the result display box.

  4. Other incorrect findbooking commands to try: findbooking rn/ , findbooking n/

F.14. Deleting a person

  1. Deleting a Guest while all Guests are listed

    1. Prerequisites: List all guests using the switch guest command. Multiple guests in the list.

    2. Test case: delete 1
      Expected: First Guest is deleted from the list. Details of the deleted Guest shown in the status message.

    3. Test case: delete 0
      Expected: Index is out of bounds. No Guest is deleted. Error details shown in the status message. Status bar remains the same.

    4. Other incorrect delete commands to try: delete, delete x (where x is larger than the list size) Expected: Similar to previous.

F.15. Saving data

  1. Dealing with missing/corrupted data files

    1. Prerequisites: Get access to the data files.

    2. Test case: Delete hotel.json
      Expected: Morpheus will load addressbook and hotel with sample data.

    3. Other tests to try: Delete some '{}' in hotel.json
      Expected: Morpheus will restart with an empty addressbook and hotel.

Appendix G: Effort (Sanchari)

G.1. Overview

Morpheus is an extension from AB3 and is considerably more complex than AB3. We have incorporated several new features which required extending the UI, Storage and Model components of Morpheus. We extended current AB3 features (which only had 1 entity type: AddressBook) to include more entity types such as Hotel and BookKeeper which in turn contained more entities such as Rooms and Bills. We did this so as to be able to create an application that allows seamless management of a hotel’s daily activities. As there were many new things to add on to AB3, the entire team put in their collaborative effort to create the end product.

G.2. Challenges

  • Planning out the structure and architecture of the application

    • A hotel is a complex system of activities, thus we had to hold several meetings to discuss what would be the structure of our application so as to allow management of all the activities in one app.

  • New storage components for the Hotel and BookKeeper

    • As the AddressBook only stored persons, we has to extend the storage system to keep track of the hotel’s data and the finance data in the Hotel and BookKeeper classes respectively. This required thorough understanding of AB3’s storage system.

  • New Commands to aid the job of a hotel receptionist.

    • We had to extend AB3’s current implementation of Logic as a hotel receptionist has to manage many more things than a person list. Hence, through thorough understanding of the Model and Logic component, we implemented a variety of new commands that works with the model to digitize the management of a hotel.

  • User Interface

    • We wanted to show all of the hotel’s activity and data in 1 window. As such, it was necessary to upgrade AB3’s UI to incorporate the hotel’s data. The Ui was improved and edited using JavaFx and CSS. All bugs and errors that were reflected in the Ui were tested and fixed by the team.

G.3. Conclusion

We believe that this was a difficult project to execute as a hotel has many interlinked components working together. However, through the combined effort of the entire team, we believe that we have created an end-product that is able to manage the hotel’s important activities altogether in one application.