PROJECT: RestOrRant


About the project

RestOrRant is a command line application that my team and I had to work on for a Software Engineering project. Given a basic code for an address book, we had the choice of enhancing or morphing it into a desktop application that caters to specific users' needs.

We decided to morph it into RestOrRant (ROR), a restaurant management application for restaurant managers, waiters and cashiers. It is designed for them to perform front-end operations more efficiently like managing tables, handling orders, tracking the availability of menu items and calculating statistical data using the Command Line Interface (CLI).

RestOrRant is split into 4 main features: Tables, Orders, Menu and Statistics. To cater to needs of the user, modes are created to make the application user-friendly. Restaurant Mode, Table Mode, Menu Mode and Statistics Mode are modes meant to handle these 4 features respectively. Each of my teammates are in charge of one feature and mine was Statistics. In the following sections, I will elaborate on my contributions and extract relevant parts from the User Guide and Developer Guide that I wrote for the Statistics feature.+

You may find it useful to refer to the table below for the different symbols and formatting used in this portfolio.

code

Command that can be typed into the command box

Expected result after executing the command

Additional information that is good to know

Important pointers to take note

Summary of contributions

Overall, my role in this project encompasses managing the documentation of the project, keeping track the deadlines and deliverable, enhancing and cleaning up the UI components and Statistics feature. You may refer below for a detailed summary of the coding, documentation and other helpful contributions I have contributed to the team project.

  1. Major enhancements: I add Statistics feature and its relevant commands.

    1. Calling for bill: bill command

      • What it does: It allows users to calculate and record the total bill accumulated from the table’s order.

      • Justification: This feature is necessary to update the restaurant’s revenue, status of the specified table and the quantity of the menu items that were ordered.

      • Highlights: This command is only usable in Table Mode.

    2. Changing the Statistics Mode display: yearly, monthly, daily commands

      • What it does: Changes the display to show yearly, monthly and daily trends of the restaurant’s earnings as well as the popularity of the menu items.

      • Justification: This feature allows the restaurant manager to study the restaurant performance.
        These makes it easier for the manager to make essential back-end and front-end management arrangements to cater to the days and months that receives more customers.
        The popularity of the menu items also helps the manager decide what kind of prior preparations are needed to cater to the popular dishes.

      • Highlights: At most 30 year, months or days along with its revenue are displayed to prevent overflow of data.

    3. Calling for revenue: revenue, revenue y/YEAR, revenue y/YEAR m/MONTH, revenue y/YEAR m/MONTH d/DAY

      • What it does: It allows users to retrieve the required yearly, monthly, daily revenue the user specifies.

      • Justification: This feature allows the restaurant manager to conveniently calculate and obtain the revenue he/she wants. It also eliminates the possibility of human errors when calculating the revenue.

      • Highlights: This command is only usable for day, month, year that are valid and dates that exists in the calendar. In the case where no day, month and year are specified, the current day’s revenue will be returned.

  2. Minor enhancement: Create a Bill Mode that displays a receipt for the user.

  3. Code contributed: Please refer to these links to view my code
    [Project Code Dashboard]

  4. Other contributions:

    • Project management:

      • Ensures that the User Guide and Developer Guide are completed according to what was required.

      • Documents essential discussion pointers during meetings and share them with the team.

      • Use buffers to set deadlines and ensure everyone are informed and on task.

    • Enhancements to existing features:

      • Updated the GUI color scheme

      • Wrote tests for bill and statistics features

    • Documentation:

      • Reorganise the User Guide according to modes: [PR: #123]

    • Community:

      • Reported bugs for other teams in the class [Examples: 1, 2]

Contributions to the User Guide

This section shows the contributions that I have made to the User Guide. I have included information about how the bill and Statistics features work.

Even though bill is used in Table Mode, its implementation is under the Statistics feature.

Calling the bill of an order : bill

Now that all the orders have been served and the customer is ready to pay for the meal, you can call the bill to obtain the customer’s receipt.

Format: bill
Shortcut: b

This command is irreversible. Once the command is executed, the order will be cleared and the table’s occupancy will be reset to allow new customers to use the table. The money earned from the bill will automatically be added to RestOrRant’s revenue statistics.
The bill can only be called when all order items have been served.

You will see a success message in the Results Display and the user interface will change its colour scheme and display.
The customer’s receipt will be displayed in the main panel and the receipt will indicate the price, quantity and name of items ordered, along with the time, date and total amount the customer has to pay.

As seen from the image below, Table 5 has 4 items in the Order Panel. Note that all items have been served.

Bill AllServed

When bill is called, the user interface changes to display the receipt as shown below:

Bill Receipt

When you switch to Restaurant Mode using the restaurantMode command, you will realise that the table has been updated to accomodate new customers.

Bill UpdatedSeats

You may refer to contributions to Developer Guide to have a better understanding of bill command.

Statistics Mode

In Statistics Mode, you can obtain statistics related to your restaurant, such as the popularity of dishes and the revenue of a specified year, month or day.

The user interface for Statistics Mode is shown in the image below.

SMUi

The function of the side and main panels are as follows:

  • Item Panel: This panel shows you the list of menu items sorted by its popularity. This is meant to help you decide what ingredients to order to cater to the demands of the popular dishes.

  • Revenue Panel: This panel displays the revenue from the recent years, months or days, depending on the view that you have selected. This allows you to study trends in your restaurant’s revenue.

By default the Statistics Mode displays revenue up to 30 days in the Revenue Panel unless you execute yearly, monthly or daily commands to change its display. Here are the commands that you can use in this mode to study the statistical data of your restaurant.

Changing the Revenue Panel to daily view : daily

This command helps you to change the Revenue Panel back to its default display of the statistical daily revenue for you to study its trends.

Format: daily
Shortcut: d

You will see a success message in the Results Display and the Revenue Panel changes to display the daily revenue for up to the past 30 days, starting from the most recent record.

Notice that the first revenue is the most recent day recorded. This saves you the trouble of scrolling through the rest of the record.

SM Daily

monthly and yearly commands also work similarly.

Getting the total revenue : revenue

If you want to obtain the revenue earned in a particular year, month or day, you can obtain it with this command.

Format: revenue or revenue y/YEAR or revenue y/YEAR m/MONTH or revenue y/YEAR m/MONTH d/DAY
Shortcut: r

Order of the parameters does not matter.
For example, r y/2019 d/6 m/4 will still return the revenue earned on 6th April 2019.
If no arguments are included, the revenue earned from the current day will be returned by default.
If there are no records of the stated period, it will be returned as $0.00.
Refer to commands to take note of the parameter restrictions of YEAR, MONTH and DAY.

You will see a success message and the revenue of the specified year, month or day in the Results Display.

revenue y/2019 will return the revenue for year 2019 as shown:

Revenue Year

revenue y/2019 m/4 will return the revenue for the month April 2019 as shown:

Revenue Month

revenue y/2019 m/4 d/6 will return the revenue for the day 6th April 2019 as shown:

Revenue Day

Contributions to the Developer Guide

Given below are sections I contributed to the Developer Guide.

_ Since bill command is an essential feature in the application, I choose to present it in the section below._

Classes for Statistics feature in Model

The Statistics feature was implemented with the introduction of a new set of classes to Model. A new Statistics class encapsulates all the methods and classes related to this feature. It also contains a listener that is used to update the storage when any modification is made to the statistics. The Statistics object is stored in RestOrRant and it exposes a read-only interface ReadOnlyStatistics to allow the other components to retrieve statistics-related information while maintaining data integrity.

Statistics contains a RevenueList, which contains a list of all the revenue recorded in the restaurant, represented by Revenue objects. Each Revenue object consists of 3 objects:

  • Year indicates the year which the revenue was earned

  • Month indicates the month which the revenue was earned

  • Day indicates the day which the revenue was earned

YearlyRevenue, MonthlyRevenue and DailyRevenue are classes that extends Revenue to inherit its properties. Hence, they are all uniquely identified by Year, Month and Day. Similarly, Date and Bill also consists and are identified by the above 3 objects.

The Statistics Class Diagram below shows the relationship between the classes.

Statistics ModelClassDiagram
Figure 1. Statistics Class diagram in Model component
Before elaborating on the bill feature, we have to understand the design considerations for statistics storage.

Design Considerations for Statistics Storage

The data stored in Storage (/data/statistics.json) only encompasses Day, Month, Year and Revenue earned on that specific date. These data are stored when the bill command is called.

Aspect Alternative 1 Alternative 2

Storage of statistical data

Stores daily revenue which comprises of day, month, year and revenue.
- Pros: Less storage space used.
- Cons: No record of bill. Impossible to retrieve receipts.

In a restaurant, it is unlikely that a customer will request for a refund after consuming and paying for the meal. Even if there are complaints about the meal, they will demand for a newly cooked dish before calling for the bill. Hence, we did not see the need to store receipts in the storage and chose this design.

Stores bill which comprises of the day, month, year, bill, table number and receipt.
- Pros: Able to retrieve data of bills.
- Cons: More storage space for lists of bills for each day.

Billing an order

Each Bill is unique to a Table. Hence, the bill mechanism can only be executed under Table Mode. The Table and its TableNumber was specified when switching over to Table Mode. The way TableNumber is specified is explained in Orders feature.

Once the bill command is called, it will internally switch to Bill Mode where the receipt of the specified table is displayed. Concurrently, the bill mechanism accesses functions from Tables, Orders, Menu and Statistics to execute the following:

  • Table: Updates specified table’s occupancy to accommodate new customers.

  • Order: Clears the order list that belongs to the specified table.

  • Menu: Saves the quantity of menu items ordered in the Menu storage (/data/menu.json).

  • Statistics: Saves the revenue in the Statistics Storage (/data/statistics.json).

Current Implementation

The main crux of Bill mechanism is implemented in BillCommand. Just like any other commands, BillCommand#execute() overrides Command#execute() which is called in LogicManager. It takes in the current mode, model and command history which will provide the necessary functions it will need to execute the command properly with the following operations:

  • BillCommand#calculateBill() — Creates a bill with a receipt of all menu items ordered and updates the quantity of menu items ordered in Menu#menuItems.

  • BillCommand#createOrUpdateRevenue() — Either saves the bill as a new DailyRevenue or updates an existing Revenue in the Statistics#revenueList.

  • BillCommand#updateStatusOfTable() — Updates the occupancy of the specified table to indicate that it has zero customers and resets the selected table to null.

  • Model#clearOrderItemsFrom() — Clears the order list to prepare for the next customer.

This sequence diagram provides an overview of how the operations above work together to execute bill command.

Bill SequenceDiagram
Figure 2. Sequence diagram for executing the bill command

To give you a better understanding of the sequence diagram, the following is a usage scenario and how the bill mechanism behaves at each step.

Step 1. Let’s assume that the user is in Table Mode 1. This means Table 1 is the selected table. Before the bill command can be executed successfully, BillCommand#execute() conducts 2 checks.

  1. Checks that current table obtained from Model#getSelectedTable() exists.

  2. Checks that all order items in Model#getFilteredOrderItemList() have been served. The status of the order item is determined via Model#getOrderItemStatus().

Step 2. Given that the command passes all checks, the user can successfully run BillCommand#calculateBill() to assign a new calculated bill to the tableToBill attribute. Let’s refer to the function’s sequence diagram below.

Bill CalculateBill
Figure 3. Sequence diagram for calculating the bill

BillCommand#calculateBill() calls both Model#getFilteredOrderItemList() and ReadOnlyRestOrRant#getMenu() to obtain the table’s list of orders and the restaurant’s menu. After which, it iterates through the list of orders to obtain individual OrderItem and executes the following in each iteration:

  • Gets MenuItem by passing the code of the OrderItem into Menu#getItemFromCode().

  • Retrieves the quantity of OrderItem ordered using OrderItem#getQuantityOrdered().

  • Updates the quantity of menu item ordered using ReadOnlyMenu#updateMenuItemQuantity().

  • Creates a receipt that appends the MenuItem#getCode(), MenuItem#getName(), MenuItem#getPrice() and the quantity retrieved previously.

  • Adds the price of each MenuItem multiplied by the quantity ordered to the total bill.

After iterating through the list of orders, receipt appends the final calculation of the total bill and the function returns a new Bill that contains the updated tableNumber, totalBill and receipt. This new Bill will be assigned to the bill attribute and passed into Model#setRecentBill() to update the Model’s recent bill (This step is needed when changing the user interface to Bill Mode).

Now that bill is updated, it is passed into BillCommand#createOrUpdateRevenue() to store the calculated bill in Statistics#revenueList. Refer to the function’s sequence diagram below.

Bill CreateOrUpdateRevenue
Figure 4. Sequence diagram for creating or updating revenue in the Statistics revenue list

As shown above, BillCommand#createOrUpdateRevenue() creates a DailyRevenue with the bill’s year, month and day. It checks if the newly created DailyRevenue exists in the revenueList via Model#hasRevenue(). If it is true that DailyRevenue exists, the function iterates through the Model#getFilteredRevenueList() and searches for a an existing Revenue that has the same year, month and day as the DailyRevenue. Once the Revenue is found, Revenue#addToRevenue() is used to add the total bill of the DailyRevenue into Revenue. Otherwise, the DailyRevenue is added into the revenueList via Model#addRevenue().

Now, that the necessary data are updated in the internal list of Menu and Statistics, BillCommand#execute() calls BillCommand#updateStatusOfTable() and Model#clearOrderItemsFrom() to make the table available for new customers.

Bill UpdateStatusOfTable
Figure 5. Sequence diagram for updating the status of the table

BillCommand#updateStatusOfTable() updates the table status by creating a new Table with an updated TableStatus and replace the existing Table with the new one. After the table is updated, the program sets the selected table to null to indicate that the table is no longer in use.

Once these essential functions are executed, BillCommand#execute() moves on to indicate that the Tables, Orders, Menu and Statistics data have been modified via Model#updateTables(), Model#updateOrders(), Model#updateMenu(), Model#updateStatistics(). After which it returns the CommandResult to LogicManager#excute() where the it will check if the Tables, Orders, Menu and Statistics data have been modified and updates the storage accordingly. The same CommandResult is returned to MainWindow#executeCommand() where the user interface switches to Bill Mode to display the receipt of the recent Bill.

Internally the program switches to Bill Mode. However, this mode is shown to the user as Table Mode to avoid confusion.
Design Considerations
Aspect Alternative 1 Alternative 2

Design calculateBill()

Iterates through the FilteredOrderItemList once to append the receipt, update quantity ordered of the items in Menu and calculate the bill.
- Pros: Efficient as it only iterates through the list once.
- Cons: The code can be further break into different functions.

We chose this design to prioritize efficiency in this use case. Since bill command is only called when the customer is ready to pay and leave the restaurant, it is better for the payment process to be swift.

Create different functions that specifically calculates the bill, creates a bill receipt and update the quantity of menu items ordered.
- Pros: Adheres to a better abstract design of the code.
- Cons: Inefficient due to multiple iteration of the FilteredOrderItemList. Given a long list of order items, this design will be impractical.

I have decided to include a brief description of the following commands' implementation as they make up the main crux of the Statistics Mode.

The following implementation applies for yearly, monthly and daily commands. These commands make adjustments to the user interface to display statistical data trends.

Current Implementation

The execution of these commands is similar to changing the mode. The only difference is that isYearly, isMonthly and isDaily boolean variables are used in MainWindow#executeCommand(). These boolean variables are passed into MainWindow#handleChangeMode() where it will determine which display to switch to. You may refer to the activity diagram to understand the cause of actions in the Statistics Mode user interface.

Trend ActivityDiagram
Figure 6. Statistics Mode Display Activity Diagram

Since these commands changes the user interface, a huge portion of their mechanism is dependent on StatisticsFlowPanel. It determines the layout and arrangement of the revenue cards displayed.

Once the revenue observable list and boolean variables are passed into StatisticsFlowPanel, the function checks which boolean variable is true. Lets assume that isDaily is true for daily command. The function enters a while loop that iterates through the revenue list until at most 30 DailyRevenue objects are created and added to a list of DailyRevenue.

The list of DailyRevenue generated is sorted in a reverse chronological order of the date. Hence, even if there are no revenue recorded on a specific date, a DailyRevenue object is still created and added to the list.

After which, the list of DailyRevenue is iterated to generate DailyStatisticsCard for each DailyRevenue. These DailyStatisticsCard are added to the StatisticsFlowPanel#statisticsFlowPane to update the user interface.

Design Considerations
Aspect Alternative 1 Alternative 2

Arrangement of [XXX]StatisticsCard

[XXX]StatisticsCard are arranged in descending order.
- Pros: The most recent card is visible to the user without scrolling.
- Cons: Viewing dates in a descending order might make it difficult to study trends.

[XXX]StatisticsCard are arranged in ascending order.
- Pros: Provides a sense of familiarity as the order is similar to that of a calendar.
- Cons: Users have to scroll to the end to view the latest revenue.

Limit the number of [XXX]StatisticsCard

Maximum [XXX]StatisticsCard shown is 30.
- Pros: Prevents overflow of data. No longer have to scroll through multiple [XXX]StatisticsCard
- Cons: Cannot view revenue from the other dates.

Display all [XXX]StatisticsCard created from stored revenue data.
- Pros: All revenue is available in a single page.
- Cons: Might experience overflow of data in the user interface. User might have to scroll to the revenue

Create additional [XXX]StatisticsCard with $0 revenue

Display all [XXX]StatisticsCard in chronological order.
- Pros: Gives user a bigger picture of the restaurant’s recent earning trends.
- Cons: Takes up space. It might be unnecessary information to the user.

Only display all [XXX]StatisticsCard created from stored revenue data.
- Pros: More revenue figures are presented to the user.
- Cons: Might appear too cluttered making it difficult to study revenue trends.

The current implementation uses the designs in Alternative 1. However, in version 2.0, the application will take the pros of Alternative 2 designs and incorporate them to the current implementation. To help users better study the revenue trends, v2.0 will allow users to call the commands with an argument that indicates the month or year that they want. The display will arrange the DailyStatisticsCard in a calender view with 7 columns for each day. A limit of 31 DailyStatisticsCard will be used to replicate a calendar and prevent overflowing.