Bureau6 min de lecture
Construire une caisse de restaurant qui suit le rythme du service
Une caisse de bureau pour restaurants et bars : tables, additions séparées, tickets cuisine et bar, et une journée de caisse qui se clôture proprement.
Écrit par Balekage Gael
Un soir de rush, un restaurant ne pardonne pas un logiciel lent. Les serveurs doivent prendre une commande en quelques secondes, la cuisine doit recevoir le bon ticket immédiatement, et la caisse doit tomber juste à la fermeture.
C'est ce que j'ai voulu construire : une caisse de bureau pour restaurants et bars, avec une interface React dans Electron et une API Express locale avec Prisma.
Pensée pour la salle
L'application est conçue pour un écran tactile au comptoir, avec un clavier à l'écran pour se passer de clavier physique. Pour un serveur, le parcours est le suivant :
- Choisir une table elle passe en occupée et est rattachée à ce serveur.
- Créer la commande et ajouter les articles, par recherche ou en scannant un code-barres.
- Ajouter ou retirer des articles quand la table change d'avis.
- Séparer l'addition quand un groupe veut payer séparément, ou appliquer une remise.
Chaque article retiré est enregistré comme annulation, avec son auteur et l'heure pour que les chiffres de la journée puissent toujours s'expliquer.
Le bon ticket sur la bonne imprimante
Un restaurant n'est pas une seule pièce. Les boissons se préparent au bar, les plats en cuisine. Dans la caisse, chaque produit appartient à un poste (la cuisine, le bar…), et chaque poste a sa propre imprimante thermique réseau.
À l'envoi d'une commande, les articles sont regroupés par poste et chaque groupe s'imprime sur l'imprimante de son poste :
const { ThermalPrinter, PrinterTypes } = require("node-thermal-printer");
// Un ticket par poste : les plats en cuisine, les boissons au bar.
for (const { printer, items } of groupByStation(order.items)) {
const ticket = new ThermalPrinter({
type: PrinterTypes.EPSON,
interface: `tcp://${printer.ip}:${printer.port}`,
});
ticket.println(`Table ${order.table.number}`);
items.forEach((item) => ticket.println(`${item.quantity} x ${item.name}`));
ticket.cut();
await ticket.execute();
}
Le cuisinier ne voit que ce qu'il doit préparer, et rien ne se perd entre le comptoir et la cuisine.
La journée du caissier
Le caissier dispose de son propre écran, centré sur l'argent :
- Encaisser une commande et enregistrer le mode de paiement.
- Factures signées pour les clients de confiance qui paient plus tard, afin que la dette soit suivie et non oubliée.
- Dépenses payées depuis la caisse pendant la journée.
- Clôturer la journée avec un récapitulatif des ventes, pour que la caisse et le système concordent avant de partir.
Un serveur dans l'arrière-salle
L'API tourne sur un ordinateur du restaurant en tant que service Windows : elle démarre avec la machine et fonctionne en arrière-plan. Les postes de caisse s'y connectent via le réseau local, ce qui garde la caisse rapide et opérationnelle même quand internet ne l'est pas. Les données sont stockées dans PostgreSQL ou MySQL, au choix lors de l'installation.
Ce que j'en retiens
- La vitesse est une fonctionnalité. Chaque tap en trop se ressent un soir de rush.
- Chaque modification doit laisser une trace. Annulations, remises et factures signées rendent les chiffres de la journée fiables.
- Les imprimantes font partie du produit. Envoyer le bon ticket au bon poste compte autant que les écrans.