PROJECT: RestOrRant


About RestOrRant

RestOrRant is a command line application that is morphed from an addressbook application. This is a Software Engineering project that required us to use their code as a base and we decided to morph it into a restaurant management system. This application enables restaurant front-end operators to:

  • Manage the occupancy of the tables in their restaurant

  • Keep track of the orders for each table

  • Refer to the menu with ease

  • Tabulate statistics of the restaurant

RestOrRant has 4 different modes: RestaurantMode, TableMode, MenuMode and StatisticsMode. These modes are meant to handle the 4 features mentioned above.

The part of RestOrRant that I implemented is the tables feature which takes place in only the RestaurantMode. Also, I handled the API and implementation of the Logic component. More details about these features will be elaborated below including documentation of it in the user and developer guide.

Please take note some of the symbols that will be commonly used in this document:

This symbol indicates important information.

addTable : A grey highlight (called a markup) indicates that this is a command that can be input into the command line and executed by the application.

Table : A grey highlight with blue text represents a component, a class or an object in the architecture of the application.

Summary of contributions

In this section, all of my contributions will be listed in detail including my code and documentations.

Within the table feature, you will find many commands implemented to create and manipulate the tables. These include:

  1. Adding Tables: added the ability to add tables to RestOrRant

    • What it does: It adds a table to RestOrRant with the specified number of seats at the table. This table is also stored in Storage component and displayed on the User Interface.

    • Justification: This command is a fundamental feature to allow the user to begin using RestOrRant.

    • Highlights: This command is configured to take in multiple arguments as well. This allows the users to add multiple tables at once thus making it more convenient to set up the application.

  2. Changing the occupancy: added *the ability to change the number of customers seated at a table

    • What it does: It updates the table in RestOrRant with the new occupancy of the table to reflect the current state of the physical restaurant.

    • Justification: This command is important in allowing the user to keep track of the exact number of customers at each table.

    • Highlights: Many restrictions and checks were put in place to ensure the integrity of the tables in RestOrRant are kept intact. An example would be ensuring that the number of customers seated at the table cannot be more than the number of seats at the table.

  3. Changing the number of seats: added the ability to edit the number of seats at a table after it has been created

    • What it does: It updates the table in RestOrRant with the new number of seats.

    • Justification: In the event that more chairs are pulled to a table or a table as has been replaced by one of different size, this command would enable the user to update RestOrRant to match its current physical state.

    • Highlights: This command has additional restrictions on top of those in changing the occupancy as we allowed the changing of number of seats even when the table is occupied. Hence, we had to ensure that the number of seats at the table cannot be changed to be less than the number of customers already seated at the table.

  4. Clearing all tables: added the ability to delete all tables

    • What it does: It removes all tables from RestOrRant.

    • Justification: In the event that the restaurant is being renovated or tables are re-numbered, this command would allow the user to quickly remove all tables so that they can create new tables with the correct table number and number of seats.

    • Highlights: This command has a safety mechanism to only be executed when the restaurant has no customers at all.

  5. Checking for space: added the ability to search for available tables

    • What it does: It checks RestOrRant for the next available table for a given number of customers.

    • Justification: Often users would have to physically check the restaurant or eyeball RestOrRant for available tables. In the event that there are large numbers of tables, that would be very inefficient. Hence, this command is menat to alleviate that problem by automating that process to quickly find the best available table.

    • Highlights: This command searches for the best fit table by looking for the table with the least number of seats to accommodate the customers. This allows the most efficient allocation of customers and most efficient use of space in the restaurant.

  6. Minor enhancement: implemented the RestaurantMode to only accept commands for the table features only and morphed the Logic component to be compatible with RestOrRant’s features.

  7. Other contributions:

    • Project management:

      • Encourage discussion during group meetings to ensure decisions considers all aspects

      • Enforced standardised coding styles throughout the project

    • Enhancements to existing features:

      • Updated the GUI color scheme (Pull requests #92, #131, #187)

      • Wrote tests for table features (Pull requests #111, #121, #187)

    • Documentation:

      • Wrote up the READme for the project

    • Community:

      • PRs reviewed with non-trivial review comments (Pull requests #62, #69)

Contributions to the User Guide

This section shows the updates that I made to the RestOrRant User Guide for table features to ensure that it accurately documents the current features in the application.

In the User Guide, I wrote about the usages of the commands that can be used in `RestaurantMode.

Restaurant Mode

In Restaurant Mode, which is the default mode, you can perform table-related operations and view the order items across all tables.

RMUi

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

  • Order Panel: This panel shows you the list of items ordered by all tables in RestOrRant, arranged in chronological order. This means that items that were ordered first appears at the top of the list. It also indicates the quantity left to serve for each item, and the background turns dark when the item is fully served.

  • Table Panel: This panel gives you an overview of all tables in RestOrRant with their table numbers and their respective occupancies.

The light coloured tables represent unoccupied tables.
The slightly darker coloured tables represent occupied tables.
The very dark coloured tables represent unusable tables.

Here are the commands that you can use in this mode to efficiently manage the tables in your restaurant.

Adding tables : addTable

As you set up RestOrRant to reflect your physical restaurant or add tables in the event that there are new tables in your restaurant, this command allows you to add tables in RestOrRant by specifying the number of seats at each table.

The maximum number of tables that can be added is 400.
  • Format: addTable NUMBER_OF_SEATS [NUMBER_OF_SEATS]…​

  • Shortcut: add

Table number increases sequentially starting from 1.
You can add multiple tables at once. This means all of your tables can be added with a single command!

You will see a success message in the Results Display and the new tables will be displayed in the Table Panel.

For example, RestOrRant initially has 35 tables when you open it for the first time as shown in the image below.

AddTable Before

Suppose you decide to open 10 more tables in your restaurant to accommodate more customers, with the number of seats of the first 5 tables be 2, the number of seats for the next 3 tables be 4, and the number of seats at the last 2 tables be 8.
Simply execute the command addTable 2 2 2 2 2 4 4 4 8 8. You will see the success message of all the tables added and their table occupancies as seen in the image below.

AddTable RD

The Table Panel will also be updated and if you were to scroll down on the Table Panel, you will see Table 36 to Table 45 added as shown in the image below.

AddTable After

Alternatively, you can also add just one table at a time. For example, you can use the command addTable 4 to add one table with 4 seats.

Editing the available seats : editSeats

In the event that there are changes to any table in your restaurant in terms of the number of seats at the table, this command can help you make sure RestOrRant is updated to reflect your physical restaurant.

You can use this command to change the number of seats at a table to 0 to represent an unusable table. This would be useful if a table is broken or you decide to remove a table without re-numbering all the other tables.
  • Format: editSeats TABLE_NUMBER NUMBER_OF_SEATS

The specified table has to exist in RestOrRant and the specified number of seats has to be more than the number of customers already seated at the table.

You will see a success message in the Results Display and the updated table will be displayed in the Table Panel.

For example, Table 2 in RestOrRant is initially occupied as shown below where the table’s status is 2/2.

EditSeats Before

Suppose the customers at this table inform you that 2 other friends are joining them and they would like to pull chairs over.
Now, you can simply execute the command editSeats 2 4 and you will see the success message of the updated table in the Results Display as shown below.

EditSeats RD

Table 2 in the Table Panel will then display the updated table information as shown below.

EditSeats After

Clearing all the tables : clearTables

In the event that you have undergone massive changes in the restaurant, you can use this command to remove all tables in RestOrRant.

This command checks if the restaurant is completely unoccupied before clearing the tables so you don’t have to worry about any accidents.
Clearing all the tables and adding them back using the addTable command is way faster than editing the tables if there are a lot of changes.
This command is irreversible! In the event that you accidentally cleared your tables, you have to use the addTable command to add all the tables back.
  • Format: clearTables

  • Shortcut: clear

You will see a success message in the Results Display and all tables will be removed from the Table Panel.

For example, when all the customers have left the restaurant, all the tables in RestOrRant will be unoccupied as shown below.

ClearTables Before

After you enter the command clearTables, a success message will be displayed and the Table Panel will become completely empty as shown below.

ClearTables After

Getting available tables for customers : spaceFor

To speed up your management of customers, this command can help you look for available tables to accommodate your customers.

This command finds the table with the least number of seats that is able to accommodate the specified customers. It will always choose the table with the smallest table number first.
  • Format: spaceFor NUMBER_OF_CUSTOMERS

You will see a success message in the Results Display and the chosen table will be updated with the specified number of customers.

For example, in the sample layout we provided, the next available table that can fit 3 customers is Table 25, as shown below.

SpaceFor Before

Suppose, 3 customers enter your restaurant and you want to quickly locate an available table for them, you can simply use the spaceFor 3 command. A success message will be displayed if there is an available table for 3 as shown below.

SpaceFor RD

In the Table Panel, you will see that Table 25 will have been updated to the correct occupancy and changed to a slightly darker colour to indicate that it is occupied.

SpaceFor After

Contributions to the Developer Guide

In the Developer Guide, I provided implementation details of the EditPaxCommand and its design considerations which are described in detail below.

Edit pax at a table

Current Implementation

The edit pax mechanism is facilitated by UniqueTableList. It stores all tables currently in ROR and ensures that there are no duplicated tables. Additionally, it implements UniqueTableList#setTable(targetTable, editedTable), which replaces the target table in the list with the new table with the updated TableStatus.

This operation is exposed in the Model interface as Model#setTable(targetTable, editedTable).

Given below is an example usage scenario and how the edit pax mechanism behaves at each step.

Step 1. Suppose the user launches the application for the first time, the sample data has 35 tables and are stored in the UniqueTableList as shown below. Focus your attention on the Table with the orange markup as this will be our target table in this example.

EditPaxStateListDiagram Before

Step 2. Suppose the user decides to have 2 customers sit at table 2 and executes editPax 2 2 command to update Table 2 with 2 customers. The editPax command calls Model#setTable(targeTable, editedTable), causing the ROR to create a new table with the updated TableStatus and replace the current target table in the UniqueTableList. As shown below, the index of the replaced table now points to a new Table which is highlighted orange.

EditPaxStateListDiagram After

The Storage detects the above change in the UniqueTableList and also updates itself.

The following sequence diagram shows how the edit pax operation works:

EditPaxSequenceDiagram
If the table to be edited does not exist in the UniqueTableList, the application returns an error to the user rather than attempting to replace the non existent table.

The following activity diagram summarises what happens when a user executes a new command:

EditPaxActivityDiagram
Design Considerations
Aspect Alternative 1 Alternative 2

Editing the tables in UniqueTableList

Replace the entire table with an updated table.
- Pros: Maintains abstraction of Table and TableStatus and reduce errors from abusing the editability of TableStatus in Table.
- Cons: May have efficiency issues when creating a whole new object whenever part of it needs to be changed.

We decided to choose this option because we realise that if we were to edit the tables directly, we would need a listener for each Table in the UniqueTableList to detect changes, which is not an efficient design. Furthermore, the tables can only be edited one at a time. Hence, the space efficiency issue would not be significant.

Directly edit the TableStatus of the tables.
- Pros: Potentially more efficient as there is no need to create new object and replace items in a list.
- Cons: Breaks abstraction to a certain extent and allows future developers to abuse the object.

Another implementation I provided are details of the SpaceForCommand and its design considerations which are described in detail below.

Getting an available table for customers

Current Implementation

This command’s interaction with the components is very similar to editing pax at a table. The key difference is that it searches for the best fit table automatically instead of having the table specified by the user.

This functionality uses the spaceFor command and is facilitated by the Model#isOccupied(Table) method. This method checks if the specified table has any customers seated at the table. The spaceFor command works like a request and takes in 1 argument specifying the number of customers to be seated in ROR.

SpaceForCommand#execute() is then called which searches through the UniqueTableList for the best fit table. In this case, the best fit Table is the smallest available one that can accommodate the specified number of customers. If there is more than 1 Table that fits those criterions, the Table with the smallest TableNumber is chosen.

public CommandResult execute(Mode mode, Model model, CommandHistory history) throws CommandException {
        requireNonNull(model);
        Table bestFitTable = null;
        int smallestSize = Integer.MAX_VALUE;

        for (Table table : model.getRestOrRant().getTables().getTableList()) {
            int numberOfSeats = Integer.parseInt(table.getTableStatus().getNumberOfSeats());
            if (!table.isOccupied() && numberOfSeats >= size && numberOfSeats < smallestSize) { (1)
                bestFitTable = table;
                smallestSize = numberOfSeats;
            }
            if (smallestSize == size) { (2)
                break;
            }
        }

        if (bestFitTable == null) { (3)
            throw new CommandException(String.format(MESSAGE_NO_AVAILABLE_TABLE, String.valueOf(size)));
        }
        model.setTable(bestFitTable, new Table(bestFitTable.getTableNumber(),
                new TableStatus(String.valueOf(size) + "/" + bestFitTable.getTableStatus().getNumberOfSeats()))); (4)

        return new CommandResult(String.format(MESSAGE_SUCCESS, String.valueOf(size), bestFitTable.getTableNumber()));
}

In the method above, we loop through the tables in the UniqueTableList while checking for the following:

1 It first checks if the table is occupied. If the table is occupied, the if-statement is short circuited. If the table is not occupied, we check if the table is able to accommodate the specified number of customers.
2 This second if statement checks if we have already found the best fit table. If we have, we can break out of the for loop to make this operation more efficient.
3 The last if-statement checks if an available table can be found in the UniqueTableList. If the table is not found, an error message is thrown for the user.

The smallestSize attribute is meant to facilitate the search for the best fit table.

Design Considerations
Aspect Alternative 1 Alternative 2

Choosing the table to allocate to the customers.

Search for the best fit table (table with the least number of seats that can accommodate the customers)
- Pros: Allows the user to allocate tables in the restaurant more efficiently.
- Cons: May have efficiency issues when as it is more likely to go through the all the tables in the UniqueTableList to search for the table.

We decided to choose this option because we realise getting the best fit table would be something that our users prefer as it allows them to run their business more efficiently.

Select the first table that is able to accommodate the specified customers.
- Pros: Potentially more efficient as it is less likely to have to go through the entire UniqueTableList
- Cons: Brings about inefficiencies in the users' front-end operations which is what our application is designed to improve. This makes them less likely to use the command.