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
servicearchitecture and command-
What it does: The
servicecommand 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,
ExpensesandExpensewere required to hold the information regarding theRoom’s total expenditure and each individual expenditure respectively. Secondly, a `MenuofExpenseTypeobjects 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, aMoneyclass 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 anXmlAdaptedClassand 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
ExpenseTypeobject 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 theExpensesclass allows us to restrict access to the collection, and only allow certain methods such as adding anExpenseor 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
expensesto eachRoom.-
Pros: Suitable for current architecture. Each
Bookingonly has oneGuest, and eachGuestwill only stay in oneRoom. Makes more sense to assign toRoomsuch that it represents the expenditure of the entireRoomand not oneGuest, since the occupants of theRoomcan only contribute to one singleExpensesobject.Roomis a more natural choice overBookingasBookingis 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
expensesto eachGuest.-
Pros: Can track
expensesof 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
Bookingonly requires the name of oneGuest, regardless of theRoom. Will require a major refactoring of theaddcommand. Complications may also arise if aGuesthas multiple bookings simultaneously and there is a need to track theExpensesover different rooms.
-
-
Alternative 3: Assign
expensesto 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
Bookingshould 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.00are not allowed. -
The
dollarssection can be 0 but cannot have leading 0, i.e. 0.12 is allowed but 01.23 is not allowed. -
The
dollarssection 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
serviceto 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,
Expensesmay become cluttered if there’s too many corrections.
-
-
Alternative 2: Create new commands to edit and delete `Expense`s.
-
Pros: The
Expenseswill 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 `Roomwith thelistcommand in order to select theExpenseto delete or edit. Information on discounts and corrections will also be lost.
-