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 the entire
service
architecture and command-
What it does: The
service
command allows for the integration of all the hotel’s goods and services into Concierge™. Users will be able to use Concierge™ to charge and keep track of the expenditure of all guests on the hotel’s goods and services. -
Justification: A hotel often provides many different kinds of goods and services, such as room service, restaurants, minibar, swimming pool, etc. Since all of these goods and services belong to the hotel, there should be a centralised system to keep track of all the expenditure on the hotel’s goods and services, such that the expenses can be compiled and presented to the guest conveniently during checkout.
-
Highlights: This functionality required the implementation of several different classes to serve as the architecture. Firstly,
Expenses
andExpense
were required to hold the information regarding theRoom’s total expenditure and each individual expenditure respectively. Secondly, a `Menu
ofExpenseType
objects were required to serve as the main reference of all the items that are sold in the hotel. This serves as the catalogue for the hotel. Finally, aMoney
class was created to handle monetary values. In addition, the information in all of these classes need to be stored in XML, and therefore implementing this required significant effort to convert each class into anXmlAdaptedClass
and to handle all the possible errors that can be introduced by modifying the values in the XML. Testing also required significant effort in adding several new test files and implementing several new utility methods, besides writing tests for all the classes mentioned above.
-
-
Minor enhancement: added a GUI panel that displays the expenditure details of every room.
-
Other contributions:
-
Refactoring:
-
Replaced all instances and variants of "Address Book" with "Concierge".
-
-
Documentation:
-
Community:
-
Tools:
-
Integrated Travis CI to the project.
-
-
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. |
-
Links to relevant sections in User Guide (for viewing on Github)
Provide Room Service: service
Charges a room service to a room
Format: service r/ROOM_NUMBER no/ITEM_NUMBER [c/COST]
ITEM_NUMBER
refers to the number in the menu given to each type of service offered by the hotel.
The default Menu that comes with Concierge™ consists of the following items:
-
RS01 — Room service: Red wine — $50.00
-
RS02 — Room service: Beef steak — $70.00
-
RS03 — Room service: Thai massage — $100.00
-
MB01 — Minibar: Coca cola — $3.00
-
MB02 — Minibar: Sprite — $3.00
-
MB03 — Minibar: Tiger beer — $6.00
-
MB04 — Minibar: Mineral water — $3.00
-
SP01 — Swimming pool: Entry — $5.00
-
XX01 — Adjustment: Discount — $0.00
-
XX02 — Adjustment: Typo — $0.00
|
Negative values can be used in service command. This can be used in cases such as when
a guest uses a voucher, hence allowing the total expenses to be reduced. Negative
values can also be charged if the user wants to remove or edit an existing expense.
The two expense types, XX01 and XX02, were thus created for the purpose of adjustments.
|
Examples:
-
service r/085 no/RS01
Adds an expenditure of the item RS01 to the room’s expenses. -
service r/096 no/RS03 c/12.34
Adds an expenditure of the item RS03 to the room’s expenses and charge $12.34 for it.
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. |
-
Links to relevant sections in Developer Guide (for viewing on Github)
Expense, Expenses and ExpenseType
In Concierge, users will be given the feature of tracking the expenditure of each individual
guest, in order to facilitate checkout charges. Hence, the three classes, Expenses
, Expense
and ExpenseType
have been created for this purpose. In addition, the hotel also has a
Menu
of goods and services available.
Current Implementation
ExpenseType
objects are essentially immutable objects that represent a single item or service
being sold at the hotel. An ExpenseType
object contains information about its menu number,
usual price, and description. The main purpose of this class is for convenience; users may
charge a customer by simply providing the menu number of the item and the cost and description
of the item will be able to be referenced. ExpenseType
information is stored in a Menu
object, which is then stored on the hard disk, since users should have the ability to modify
the menu manually. The Menu
object is internally represented with a HashMap<String, ExpenseType>
,
with the menu number as keys and the ExpenseType
objects as values.
-
Alternative 1: Use a List<ExpenseType> to store the menu. While there may be negligible differences for a small menu, searching for an
ExpenseType
object still takes linear time and there may be significant performance drops for a large menu.
An Expense
object contains information about one individual expenditure by a guest. An
Expense
object encapsulates the cost, ExpenseType
of the item bought, and the date and time
of expenditure.
The Expenses
object is essentially a List<Expense>
. Every room contains an Expenses
object, to represent the collection of all the expenses of the guests in the room.
-
Alternative 1: Use a
List<Expense>
object: Defining theExpenses
class allows us to restrict access to the collection, and only allow certain methods such as adding anExpense
or displaying on screen. -
Alternative 2: Use a
Set<Expense>
object: Having the expenses ordered (e.g. chronologically) will be useful for generating a nice view of all the expenses incurred.
Here is a simple UML describing the roles of these classes.
Design Considerations
Aspect: Immutability of Menu
While it is conceivable that the items sold may change from time to time,
for various reasons such as unpopularity or seasonal products, giving users
the ability to add and remove items from the menu may result in more
problems than benefits. We expect that alterations to the menu will not be
performed frequently, and that the majority of our users, receptionists,
will not be required to add and remove items to the menu. The menu also does
not have to be altered during operational hours. Hence, by making
Menu
immutable, we eliminate the possibility of making accidental or
unwarranted changes to the menu. The only method to modify Menu
would
thus be through the XML file, which we believe is suitable for these
purposes.
Aspect: Immutability of ExpenseType
The ExpenseType
object is meant to hold the default values of the name and
price of each item. In other words, since an Expense
object references an
ExpenseType
object, the Expense
object is allowed to have a cost that
is different from the cost in the corresponding ExpenseType
object, to
account for cases such as the guest having a personalised discount due to
the usage of vouchers or certain credit cards. Thus, ExpenseType does not
need to be modified by users in the application. Nonetheless, it is still
possible to modify the default information through editing the XML file.
Aspect: Assignment of the Expenses object
-
Alternative 1 (current choice): Assign
expenses
to eachRoom
.-
Pros: Suitable for current architecture. Each
Booking
only has oneGuest
, and eachGuest
will only stay in oneRoom
. Makes more sense to assign toRoom
such that it represents the expenditure of the entireRoom
and not oneGuest
, since the occupants of theRoom
can only contribute to one singleExpenses
object.Room
is a more natural choice overBooking
asBooking
is meant to encapsulate booking information such as timing andRoom
. Not much difference in implementation no matter which one of the three classes it is assigned to. -
Cons: May be confusing to implement. Need to ensure that there are no expenses for rooms that have no guests.
-
-
Alternative 2: Assign
expenses
to eachGuest
.-
Pros: Can track
expenses
of eachGuest
, can find out who are the heavy spenders. Can use this information for promotional activities such as vouchers or membership. -
Cons: Not all guests that will stay in the hotel are registered in the guest list, since each
Booking
only requires the name of oneGuest
, regardless of theRoom
. Will require a major refactoring of theadd
command. Complications may also arise if aGuest
has multiple bookings simultaneously and there is a need to track theExpenses
over different rooms.
-
-
Alternative 3: Assign
expenses
to eachBooking
.-
Pros: Can allow tracking of the booker’s expenditure, less confusing to implement than
Room
, can allow for expenses to be recorded before the guest checks in. -
Cons: May violate SRP, since
Booking
should ideally only deal with booking information.
-
Money
Current Implementation
Money
is a class used to store monetary values. This class was created to
enforce the restriction that monetary values should always have at most two
decimal places, which could be inconvenient if using Java data types such
as double
or BigDecimal
. Money
objects can be created by the user
through the service
command (details in the next section).
The Money
class contains two main attributes, dollars
and cents
, both
of which are int`s, since it is unlikely that the cost of any one item will
exceed `Integer.MAX_VALUE
dollars.
The main method of creating Money
objects is through the service
command,
with the Money
class parsing a string to convert into a Money
object.
The method isValidMoneyFormat()
handles the checking of the string format,
and the list of requirements are as follows:
-
Can be negative.
-
Format of the string should be {1 to 10 digits}.{2 digits}, e.g.
12.34
.123
,.50
,12.9
,12345612345.00
are not allowed. -
The
dollars
section can be 0 but cannot have leading 0, i.e. 0.12 is allowed but 01.23 is not allowed. -
The
dollars
section should not exceedInteger.MAX_VALUE
. -
Cannot have characters that are not digits or
.
or-
.
Design Considerations
Aspect: Immutability of Money
Money
does not have to be mutable. Adjustment of Expenses
are to be done
through the service
command. Money
is simply a data type, much like
Double
and Integer
.
ServiceCommand
Current Implementation
The service
command is used for charging expenses to rooms. This
functionality is the main reason that the classes Expenses, Expense,
ExpenseType, Menu and Money were implemented. The format for the service
command is as such:
service r/ROOM_NUMBER no/ITEM_NUMBER [c/COST]
The cost is made optional for the convenience of the user. We expect that
most of the time, the cost of items are more or less fixed. Instead of
having the user type in the same cost all of the time, the field is made
optional. This functionality is enabled by the use of ExpenseType
and
Menu
, which stores the default cost of items. If the cost is not specified,
the default cost of the item will be used.
As in AddressBook4, the ConciergeParser (aka AddressBookParser) will parse
the user input and create a ServiceCommandParser
object to parse a service
command. The ServiceCommandParser
is responsible for checking that the
RoomNumber
and cost (a Money
object) are in the correct format. Note that
the item number is not checked here, since the Menu
object of Concierge
has to be available in order to check that the given item number is a valid
item. Hence, any string will be accepted by the parser. Since ServiceCommand
has access to the Model
and thus the Menu
, the checking is given to
ServiceCommand
instead. A successful parse will then return a
ServiceCommand(RoomNumber roomNumber, String itemNumber, Optional<Money> itemCost)
object.
The following flowchart describes what happens when the execute
method
of a ServiceCommand
is called.
The model.addExpense()
method call was not illustrated in detail in the flowchart,
thus it is illustrated in this sequence diagram.
Design Considerations
Aspect: Deleting and editing Expenses
-
Alternative 1 (current choice): Use
service
to edit `Expense`s.-
Pros: Simply keying in `Expense`s with negative values is easy to implement, and does not stray far from real-life implementations, e.g. receipts often contain cost subtractions for discounts and promotions.
-
Cons: May not be elegant,
Expenses
may become cluttered if there’s too many corrections.
-
-
Alternative 2: Create new commands to edit and delete `Expense`s.
-
Pros: The
Expenses
will contain all the `Expense`s at their correct prices. -
Cons: More effort to implement, difficult to implement, e.g. may need to implement listing out all
Expense`s of a `Room
with thelist
command in order to select theExpense
to delete or edit. Information on discounts and corrections will also be lost.
-