This is a simple POS system built to simplify the act of serving food/drinks.
The usual procedure for this would be that a waiter
- Walks around
- Takes an order
- Walks to the kitchen
- Passes the order
- Waits while it's prepared
- Takes the food/drinks
- Walks to the client
- Delivers the food/drinks
- Cashes up
Using this system, the ordering procedure would be
A waiter
- Walks around
- Takes an order with his smartphone
- Cashes up
The order is automatically received in the kitchen
Another waiter
- Takes food/drinks
- Walks to the client
- Delivers the food/drinks
In contrast to the traditional service, the delay between ordering and passing the order the the kitchen as well as unnecessary waiting has been eliminated completely.
- The software does not require an internet connection an can be run on e.g. a raspberry pi
- Both kitchen and waiter need have access to the server via network (e.g. by using a hotspot or a connecting everything to a router)
- The server can be started with
gunicorn --bind 0.0.0.0:80 run:app
- Waiters can connect to the server with their smartphones via
http://<ip>/service
- The kitchen can connect to the server with a desktop computer via
http://<ip>/bar
- A desktop computer or tablet with large screen for the kitchen
- A smartphone for each cashier with a browser installed
- A device where the server can run on (can be the same as for the kitchen) with
>=python3.10
installed - Some kind of network to connect everything
Clone the repository:
git clone https://github.com/Ultimator14/mini_pos.git
cd mini_pos
Install dependencies:
poetry install
Enter the poetry virtual environment:
poetry shell
Development (Werkzeug server):
python run.py
Production (Gunicorn server):
sudo sysctl -w net.ipv4.ip_unprivileged_port_start=80 # allow binding to port 80 without root
gunicorn --bind 0.0.0.0:80 --workers=4 run:app # run the app
sudo sysctl -w net.ipv4.ip_unprivileged_port_start=1024 # reset sysctl config change
Configuration is done in the config.json
file. The file is mandatory. The software does not start without it.
Some configuration options are
Config option | Description | Format |
---|---|---|
product/available | List of available products (name, price, category) | List[str Name, float price, int category] |
product/categories | Category names | List[int category, str name] |
table/size | Size for the table grid in service | int x, int y |
table/names | Table positions, sizes and names | List[int x, int y, int xlen, int ylen, str name] |
ui/auto_close | Automatically complete an order when all products are marked as completed | bool true/false |
ui/show_completed | Show the last n completed orders in /bar | int n |
ui/show_category_names | Show category names between products of different category in service | bool true/false |
ui/fold_categories | Fold categories by default in service | bool true/false |
ui/timeout | Timeout in seconds to mark orders yellow/red | int timeout_warn, int timeout_crit |
An additional space is added between adjacent products with different category in service. If show_category_names
is enabled, the space is filled with the corresponding category name.
Categories 0-14 have a distinct color scheme
- Products in category 1-7 have a light colored background per default and become heavily colored upon selection. The category separators are not colored
- Products in category 8-14 have a white background per default and become light colored upon selection. The category separators are colored heavily
- All other products have a white background per default and are colored green upon selection. The category separators are not colored
Colors can be added or edited directly in service_table.css
Table positions can be customized. Tables must have a start position x,y
, a horizontal and vertical length xlen, ylen
and a name.
Overlapping tables are not supported and will produce a warning.
Tables outside the grid are not supported and will produce an error.
It's not safe to alter configuration options and restarting the server without reloading the pages on the client side.
Make sure, that waiters reload the page after a config change and server restart happened.
Example:
Removing, adding or swapping products in the configuration could cause a wrong product to be ordered when the server is restarted.
Products are numbered by their position in the configuration file.
When a table is opened in service, the product numbers are fetched from the server.
When the server is restarted and the product numbers changed somehow, frontend and backend are not synced anymore.
This could cause wrong products in the next order.
Scenario:
- Waiter opens
/service/A1
, products areProd1
(1),Prod2
(2),Prod3
(3) - Product
Prod1
is removed from server config - Server is restarted
- Products in server are now
Prod2
(1),Prod3
(2) - Waiter orders
Prod2
identified by number 2 - Server receives number 2 and maps it to product
Prod3
The analysis script provides an overview about sold products, revenue as well as some more statistics.
For the script to work, the dependencies from the analysis group must be installed. Afterwards the analysis can be started with the analyze.py
script.
The results are saved as analysis.pdf
.
Install analysis dependencies:
poetry install --with analysis
Enter the poetry virtual environment:
poetry shell
Start analysis:
python analyze.py
Note: When it's desired to show the plots in a window, uncomment the last line plt.show()
in the analyze.py
script.
However the command plot.show()
will probably not work. This is because PyQt5 is not included in the dependency list. Which again is because poetry is cross-platform but PyQt5 only supports some specific architectures. To still be able to show plots inside the poetry virtualenv, use pip install pyqt5
(if there exists a wheel for your arch). Alternatively install PyQt5 on your system and use the virtualenvs.options.system-site-packages
config option for poetry to allow the virtualenv to access it.