Simple reservations, queuing and ordering
Locavorus is a proof-of-concept web application for restaurants and other food businesses to manage their reservations, queue and orders. It aims to improve customer service by making various aspects of the service life cycle more efficient. One aspect would be to allow customers to queue or place takeaway orders remotely. The system also automatically allocates the best available table to each customer and notifies them whenever the restaurant is ready.
✅ Customers to be able to join the queue from a front-end interface (in this case, from a browser). They must be notified via SMS and must be able to submit their food orders online.
✅ Customers to be able to submit their reservation and receive email confirmations.
✅ Customers to be able to place takeaway orders with email confirmations.
✅ System to handle reservation and queuing with automatic assignation, ordering and notification.
✅ System to handle takeaway and local orders with logic to prioritise orders.
✅ Simple interface to find restaurants and view details.
✅ Simple interface to manage user accounts and business dashboard.
This project is built with Ruby on Rails and PostgreSQL. Follow the official instructions to download and install them.
Fork, clone or download this repository to your desired directory. Install the necessary Gem files by entering the following code in your terminal in your directory:
bundle install
Run the following code to reset the database and populate it with seed data.
rails db:reset
The project will also require a .env file that contains all the secret variables used in the project. Change the file type of the included .env.sample file to .env and replace the values with your own. You have to start the application with the following command to utilise your secret variables:
foreman run rails s
This project was deployed with Heroku, but you can choose your own server host. To use Heroku, go to https://www.heroku.com, create an account and follow the instructions to deploy your own project.
If you choose to go with Heroku, you will need to connect a Redis add-on in order to utilise ActionCable. Add your Redis url to production in:
/config/cable.yml
- Ruby on Rails
- PostgreSQL
- Embedded Ruby (ERB)
- JavaScript
- CSS
- jQuery
- Materialize
Making a Reservation
Queuing
Takeaway Orders
Dashboard
Orders
Invoices
- User
- Order
- Restaurant
- Reservation
- Menu
- Table
- Invoice (previously 'Transaction')
Customer dining events are represented by the Reservation model. Below is the rough flow of how the status of the diner changes during each event.
The method below is called to determine a table for a potential diner.
Method
-
Find all tables in the restaurant.
-
Find all unavailable tables where the start time of the reservation is before the end time of that table AND the end time of the reservation is after the start time of that table.
-
Remove these unavailable tables from all tables in that restaurant.
-
From the remaining tables, filter out and accept only the tables with capacity greater than or equal to the number of diners.
-
Sort these tables in ascending order of capacity and select the first table in the array to reduce inefficiencies in seating. E.g. Assigning 3 people to an empty table meant for 4 people.
-
Select the table with the smallest possible capacity.
Tables will only be assigned / suggested whenever a diner starts 'queuing' or when an existing diner is 'checked out'.
-
Use table-finding logic to find unoccupied tables (tables with no 'Reservations' that are 'dining') and submit a reservation with
DateTime.now
. -
If there are no available tables, add the user to the queue. User will receive a
Twilio
SMS with the number of people ahead of them and an estimated wait time if requested. -
When a diner checks out, find the most suitable customer from the queue (one that can fit into the table with the priority going to the smallest queue number)and run the table-finding logic again to find future reservations.
-
If there are no future reservations, assign a table to the first 'queuer' who can fit the table and send another
Twilio
SMS to inform the 'queuer' that they can make their way to the restaurant. -
Change status of the customer from queuing to dining.
Orders can be created from four different entry points:
- takeaway
- reservation
- queuing
- in-restaurant
This means that different parameters are passed and checked to determine the correct type of order and to attach the necessary relevant information.
This also determines the order of food preparation by the kitchen. The orders are prioritised by time:
# if takeaway
order.invoice.takeaway_time
# if reservation
order.invoice.reservation.start_time
# if queuing
DateTime.now + est_wait_time
# if local order
order.created_at
Online payment is managed through the easy-to-implement Stripe API.
Kitchen View of Upcoming Tickets
Suggestions for new Reservation Entries
If no available tables are found, repeat the logic with wider time params and suggest other available time-slots to the user.
The following bugs will also have to be fixed.
'date_select' is used in the form_for inputs. This allows invalid dates (eg. 31 February) to be selected. Currently, validation checks in the controller are used, but a more robust method could be used for date inputs in forms.
Our ActionCable only uses one room, which means that while we apply filters so restaurants only see orders that belong to them, they are receiving all restaurants' orders, which can greatly affect performance. A per-restaurant system should be implemented to improve performance and security.
For an unsolvable reason, the orders array is changed by methods applied to a copy of the array, which means that cancelling payment to add an item to the order will fail as the array will now be empty. The previous values are stored, so if the customer pays immediately without adding any items, the order will proceed normally.
We acknowledge 😏 ourselves 😉 for all the hard work that has gone into this project over the past 2 weeks, but more importantly, the people who have helped us along the way.
- Prima Aulia
- Kenneth Goh
- Logo: Max Alexander Ng