Overview
Concierge™ is a desktop application simulating a hotel management system used by hotel owners and receptionists. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 10 kLoC.
Summary of contributions
-
Code contributed: [Code Contributed]
-
Major enhancement:
-
Implemented
checkIn
andcheckout
commands-
What it does: Allows the user to check-in a room’s booking that is active, checkout any booking of a room, and update the checked-in guest list and archived guest list to reflect the checked-in/out guests respectively.
-
Justification: This feature is a core feature that supports the daily operations of a hotel, without which the hotel will not be able to function. The checking-in/out of a room’s booking is a very frequent operation in a typical hotel setting. However, it is very cumbersome to execute these operations using the existing
edit
command as it requires many fields to fill in. This feature solves this problem by providing a command-line interface with minimal fields to specify, allowing smooth and fast checking-in/out of rooms. -
Highlights:
-
The validity of a check-in operation requires knowledge of how a hotel manages its policy of allowing guests to check-in. The current implementation was finalized after experimenting with different validity checks on multiple different scenarios. Refer to the User Guide and Developer Guide for more information on these checks.
-
As for the checkout feature, though it was initially intended to execute similar validity checks for checking-out a booking, it has now expanded its scope to double as a delete-booking feature.
-
Before these commands could be implemented, the underlying
Room
architecture had to be written first. Extensive trial-and-error was conducted to decide the better alternative between mutable and immutable data, from which the immutability paradigm emerged the victor, as it was easy to debug and made writing unit, integration, and system tests much easier. As for the data structure of Room, Guests, and Bookings, cyclic references were shunned in favor of one-way references (i.e. Room contains Bookings; each Booking contains a Guest). This was chosen to minimize the risk of data corruption, as it removed the need for maintaining the synchronization of the same data in multiple places.
-
-
-
-
Minor enhancements:
-
Other contributions:
-
Project Management
-
Managed releases
v1.2
-v1.4
(5 releases) on GitHub
-
-
Writing and testing the
Room
package-
Single-handedly wrote and tested the entire
Room
package: #71
-
-
Enhancements to existing features:
-
Documentation
-
User Guide
-
Update with description of usage of CheckIn, Checkout, and Reassign commands
-
Did cosmetic tweaks (icons and format) to existing contents of the User Guide: #238
-
-
Developer Guide
-
-
Tools
-
Added Coveralls, Appveyor, and Codacy support for the team
-
-
Community
-
Opened 40+ pull requests
-
Reviewed 40+ pull requests
-
Some examples of PRs reviewed (with non-trivial review comments), giving praise and encouragement where it is due: #63, #89, #105, #155, #158, #169, #226
-
-
Contributions to the User Guide
Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users. |
Terminology
Some important things that you should know before using Concierge™
-
Room numbers must be a 3-digit number from 001 to 100. For example,
-
001, 050, 074, 100 are valid
-
000, 01, 99, 101 are invalid
-
-
The format used for dates is d/M/y, whereby
-
d - Day can be 1 or 2 digits
-
M - Month can be 1 or 2 digits
-
y - Year can be 2 or 4 digits (if 2 digits, date is assumed to be in the current century)
-
-
A Booking …
-
is Active if the period between its start and end date includes today’s date, inclusively.
-
is Upcoming if its start date is strictly after today’s date.
-
is Expired if its end date is strictly before today’s date.
-
is Outdated if its start date is strictly before today’s date.
-
is Overlapping with another booking if its start date is strictly before the other’s end date AND the other’s start date is strictly before its end date
-
can be uniquely identified by its start date.
-
-
Two guests are…
-
different if they have different names
-
different if they have the same name AND both their phone numbers and emails are different
-
same if they have the same name AND either their phone number or email, or both, are the same
-
-
There are 2 guest lists:
-
Checked-in guest list contains all the guests who are currently checked-in.
-
Archived guest list contains all guests who have ever stayed in the hotel before.
-
Therefore, it is possible for a guest who has made a booking to be in
-
neither lists - guest has yet to check-in and has never stayed in the hotel before
-
checked-in guest list only - guest has checked-in and has never stayed in the hotel before
-
archived guest list only - guest has not checked-in and has stayed in the hotel before
-
both lists - guest has checked-in and has stayed in the hotel before
-
-
This is a |
This is a important icon. You should read the information in these before executing the command, as it will likely affect what you can or cannot do. |
This is a tip icon. You may want to read this if you are new to Concierge™. |
Check-in room: checkin
Checks in the first booking of a room. The guest who made the booking will be added to the checked-in guest list.
Expired and upcoming bookings cannot be checked-in. |
Format: checkin r/ROOM_NUMBER
Examples:
-
checkin r/085
Checks in room 085, marks room 085’s current booking as checked-in, and adds the guest who made the booking to the checked-in guest list.
Checkout room: checkout
Checks out the room’s first (i.e. earliest) booking, or its booking with the specified start date. Also updates the checked-in guest list and archived guest list with the guest who made the booking.
checkout 's intended use is the deletion of any booking.
This means that you can delete a non-checked-in booking using checkout .
|
Format: checkout r/ROOM_NUMBER [from/START_DATE]
Examples:
-
checkout r/085
Checks out room 085 and the room’s first booking. -
checkout r/085 from/01/11/18
Checks out the booking with start date 01/11/18 from room 085.
Reassigning a guest to another room : reassign
Reassigns a booking from one room to another. The room’s expenses will also be ported over to the new room.
You can reassign a booking only if:
|
Format: reassign r/ROOM_NUMBER from/START_DATE nr/NEW_ROOM_NUMBER
Examples:
-
reassign r/085 from/01/11/18 nr/086
Reassigns the booking with start date 01/11/18 in room 085 to room 086.
Contributions to the Developer Guide
Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project. |
Room Check-in/Checkout feature
Current Implementation
The room check-in and checkout features makes use of UniqueRoomList
.
The logic that supports the check-in and checkout operations mainly reside in the Concierge
and Room
classes.
-
UniqueRoomList#checkin(RoomNumber)
— Checks in the first booking of the room identified by the given room number -
UniqueRoomList#checkout(RoomNumber)
— Checks out the first booking of the room identified by the given room number -
UniqueRoomList#checkout(RoomNumber, LocalDate)
— Checks out the room’s booking whose start date matches the given date
Active booking refers to a booking that includes today’s date. First booking refers to the earliest (i.e. first in chronological order). |
A room can be checked out regardless of its checked-in status. Thus, checkout doubles as a command to delete bookings.
|
These operations are exposed in the Model
interface as Model#checkInRoom
and Model#checkoutRoom
respectively.
Given below is an example usage scenario and the flow of the check-in feature.
Assuming there is a booking already added to room 001,
-
The user executes
checkin r/001
when the guest arrives.-
The
checkin
command takes in aRoomNumber
argument and callsModel#checkInRoom
as such:Model.checkInRoom(roomNumber)
-
ModelManager#checkInRoom
(which implements Model) will callVersionedConcierge#checkInRoom
-
VersionedConcierge#checkInRoom
will callUniqueRoomList#getRoom
to get the room using its RoomNumber -
VersionedConcierge#checkInRoom
will callRoom#checkIn
-
Room#checkIn
will-
throw
NoBookingException
if the room has no bookings -
throw
ExpiredBookingException
if the room’s first booking is expired -
throw
InactiveBookingCheckInException
if the room’s first booking is not active -
throw
BookingAlreadyCheckedInException
if the room’s first booking is already checked in -
update the first booking as checked-in if no exceptions were thrown, and replace the room with its updated version that has the first booking checked-in
-
-
VersionedConcierge#checkinRoom
will callVersionedConcierge#addCheckedInGuestIfNotPresent
-
VersionedConcierge#addCheckedInGuestIfNotPresent
will add the guest of the checked-in booking to the checked-in guest list if he/she is not already in it
-
The following sequence diagram shows how CheckInCommand#execute
works, from the Logic up to the Model:
CheckInCommand#execute
.Since the Model simply calls VersionedConcierge#checkInRoom
, the following activity diagram will illustrate how
Concierge#checkInRoom
works:
Concierge#checkInRoom
is executed.Design Considerations
Aspect: Immutability of check-in command
-
Alternative 1 (current choice):
checkIn
a room by creating a new copy of the room with theisCheckedIn
flag of the first booking set to true.-
Pros: Debugging is easy. Consistent with the rest of the application.
-
Cons:
checkIn
method becomes unintuitive, since a new room is returned from the operation, instead of a void method simply setting the instance property.
-
-
Alternative 2:
checkIn
a room by setting theisCheckedIn
flag of the first booking to true.-
Pros: Check-in method is intuitive, and does not return a new room.
-
Cons: Harder to debug. Tests also become troublesome since changes are made to the same referenced room.
-
Aspect: Deletion of bookings
-
Alternative 1 (current choice): Use
checkout
to delete any booking.-
Pros:
checkout
doubles as a delete booking feature, so no need for adeletebooking
command. -
Cons: Not very natural, as
checkout
implies checking out a checked-in booking.
-
-
Alternative 2: Use
checkout
to delete only active booking, and create new commanddeletebooking
to delete expired and upcoming bookings.-
Pros: More natural,
checkout
can only do what its name implies. -
Cons: Need to implement new command and more methods, to support the same deletion operation but with a different name.
-