No description
  • HTML 44.5%
  • PHP 30%
  • JavaScript 17%
  • CSS 7.8%
  • PowerShell 0.7%
Find a file
Consulking-Ibrahim 7c0dc8a46c feat(admin): fusionner stats dans orders.html — onglets Bootstrap
- orders.html : onglets Commandes / Statistiques (Bootstrap tabs)
- Statistiques chargées en lazy à la 1re ouverture, hash #stats supporté
- jQuery ajouté dans <head> pour le JS stats existant
- Modale confirmation suppression commande (remplace confirm() natif)
- stats.html supprimé
- Lien /admin/stats.html retiré du nav dans les 10 autres pages admin
2026-06-09 01:51:27 +02:00
docs feat: replace Node.js bridge with ESC/POS direct LAN printing 2026-05-16 21:25:27 +02:00
public feat(admin): fusionner stats dans orders.html — onglets Bootstrap 2026-06-09 01:51:27 +02:00
scripts feat: reserve order ID at first cart add for instant display (#N) 2026-06-01 18:51:19 +02:00
sql feat(order): original_ready_time — traçabilité des repoussages d'heure 2026-06-06 16:20:32 +02:00
.htaccess update 2026-03-01 01:46:09 +01:00
CLAUDE.md docs: CLAUDE.md — conventions Claude Code (procédure check git et commit) 2026-06-09 00:24:52 +02:00
menu.pdf Fonctionnel (sauf printers) 2026-03-01 14:40:47 +01:00
menu_extracted.txt Fonctionnel (sauf printers) 2026-03-01 14:40:47 +01:00
pos (1).sql fix: validation et context bar en mode plateforme (Ligne cherche/livrer) 2026-05-29 21:02:25 +02:00
pos.sql config: activer imprimantes réseau + màj dump SQL local 2026-05-18 17:12:46 +02:00
README.md feat: replace Node.js bridge with ESC/POS direct LAN printing 2026-05-16 21:25:27 +02:00

Pizza POS MVP (PHP + MySQL)

1) Install

  1. Create a MySQL database (utf8mb4).

  2. Run:

    • sql/schema.sql
    • sql/seed.sql
  3. Edit DB credentials in: public/api/config.php

2) Run locally

From the project root:

php -S 127.0.0.1:8000 -t public

Open:

2bis) Deploy on OVH under /POS

Target URL: https://domaine.com/POS

  1. Upload this whole folder to OVH in www/POS.
  2. Keep the folder structure unchanged (public/, sql/, docs/, etc.).
  3. Ensure Apache rewrite is enabled on OVH (mod_rewrite).
  4. Keep the root .htaccess from this repo (it routes web requests to public/).
  5. Open:
    • POS: https://domaine.com/POS/
    • Admin: https://domaine.com/POS/admin/prices.html

Notes:

  • API works via config.js and apiUrl(...), so /POS/api/... is handled correctly.
  • sql/, docs/ are not exposed through normal web routes with this setup.

3) What this MVP does

  • Order types: livraison / emporter / sur_place
  • Prices differ by context (pickup vs delivery) via product_prices
  • Pricing modes:
    • normal
    • staff_5 (1 main free, others 5; garlic bread 1st free, 2nd+ = 5; drinks 0.50; desserts 2; extras free)
    • family_6, family_7
    • friends_5, friends_6, friends_7
    • gift_0
  • family/friends can toggle "drinks free"
  • Delivery minimum per commune for TEL + LIVRAISON (override with reason)
  • Customer phone lookup, multiple addresses with "save for next time"
  • Tickets generated (text):
    • Accueil (complete)
    • Pizza (pizza station + garlic bread, with "+ PÂTES : X" and commune)
    • Cuisine (cuisine station, with "+ PIZZAS : Y" and SOLO/+PIZZA tag)

4) Printing

Architecture — ESC/POS direct LAN

Les tickets sont encodés en ESC/POS binaire et envoyés directement à l'imprimante réseau via TCP (fsockopen() sur port 9100). Aucun bridge Node.js, aucun driver Windows, aucune queue d'impression OS.

L'imprimante est une Star IFBD-HI01X (Star Line Mode). Les commandes ESC/POS utilisées sont celles de Star (pas Epson GS V / ESC !).

Flux complet :

1. POS (browser) → POST api/order_create.php
   → Insère commande en DB (transaction)
   → Génère les tickets ESC/POS (build_all_tickets_escpos)
   → Enqueue 1 job/ticket dans print_jobs (base64)
   → Répond {ok, order_id, total, tickets}

2. POS → POST api/bridge_print.php {order_id}
   → Drain les jobs pending de cet order (envoi TCP direct à l'imprimante)
   → Si imprimante KO : jobs restent pending, le worker reprend

3. Cron Windows (toutes les minutes) → GET api/print_worker.php?key=SECRET
   → Traite tous les jobs pending restants (FIFO, max 20 par appel)
   → Retry jusqu'à max_attempts (5 par défaut)

Fichiers clés :

Fichier Rôle
public/api/escpos.php Primitives ESC/POS (commandes, iconv CP858, fsockopen)
public/api/tickets_escpos.php Builders de tickets (accueil, pizzaiolo, cuisine)
public/api/print_queue.php Helpers queue : enqueue, drain, worker, send
public/api/print_worker.php Endpoint worker (auth par secret)
public/api/bridge_print.php Push immédiat via queue
public/api/bridge_status.php Ping TCP imprimante + stats queue
sql/migrations/2026_05_14_print_jobs.sql Migration DB (table print_jobs)
sql/migrations/2026_05_16_drop_bridge_columns.sql Suppression colonnes bridge legacy

Migrations DB (à faire une fois, dans l'ordre)

-- Via phpMyAdmin ou mysql CLI :
SOURCE sql/migrations/2026_05_14_print_jobs.sql;
SOURCE sql/migrations/2026_05_16_drop_bridge_columns.sql;

Configuration imprimante

Depuis la page admin : public/admin/printer_settings.html

  • IP imprimante : adresse IP de l'imprimante réseau (ex: 192.168.1.100)
  • Port : 9100 (défaut Star RAW)
  • Bouton "Status" : ping TCP live + stats queue
  • Bouton "Tester l'impression" : envoie un ticket de test fictif directement à l'imprimante

Cron Windows (Task Scheduler)

Créer une tâche planifiée toutes les minutes :

  • Programme : curl
  • Arguments : "http://localhost/api/print_worker.php?key=VOTRE_SECRET"
    • Remplacer VOTRE_SECRET par la valeur affichée dans la page admin imprimante
    • localhost = XAMPP local

Ou via PowerShell (test manuel) :

curl "http://localhost/api/print_worker.php?key=VOTRE_SECRET"

Réponse attendue :

{"ok":true,"stats":{"processed":2,"ok":2,"failed":0},"limit":20,"ts":"..."}

Monitoring (page admin)

Ouvrir public/admin/printer_settings.html :

  • Bouton "Status" : ping TCP imprimante + stats queue (pending / failed / done)
  • Bouton "Lancer le worker" : déclenche le worker manuellement
  • Bouton "Réessayer les failed" : remet les jobs failed en pending (attempts=0)
  • Worker Secret : affiché en lecture seule, bouton "Régénérer" disponible
  • Réimprimer un ticket : depuis public/admin/orders.html, bouton "Réimprimer"

Debug SQL (lire la queue directement)

-- Jobs en attente ou échoués
SELECT id, order_id, ticket_kind, status, attempts, max_attempts, last_error, created_at
FROM print_jobs
WHERE status IN ('pending','failed')
ORDER BY created_at DESC
LIMIT 50;

-- Stats globales
SELECT status, COUNT(*) AS cnt FROM print_jobs GROUP BY status;

-- Forcer un retry sur tous les failed
UPDATE print_jobs SET status='pending', attempts=0, last_error=NULL WHERE status='failed';

Logique retry

Cas Comportement
Erreur réseau / timeout pending (attempts++) — réessayé par le worker
Imprimante injoignable pending — réessayé par le worker
attempts >= max_attempts Ignoré par le worker (reste failed)
Bouton "Réessayer" admin Remet attempts=0, status=pending
Job legacy (sans escpos_b64) failed immédiat, pas de crash

Note: public/api/config.php existe toujours comme fallback IP/port pour les fresh installs.

Security note

No auth is implemented. Protect /admin and /api/admin before using in production.