English · Română
POS complet pentru restaurante și fast-food — instalare automată, fiabilitate în exploatare, fără dependențe grele.
TableManager gestionează mesele, bonurile, ospătarii, meniul, discounturile, stornările, plățile (inclusiv plata cu cardul prin terminal bancar) și tipărirea la bucătărie / bar / notă fiscală, plus rapoartele X și închiderea Z.
Aceeași aplicație rulează în două moduri — Restaurant (comandă la masă) și FastFood (vânzare rapidă la tejghea) — alese dintr-o singură setare. Este rescrisă de la zero pe tehnologii moderne și ușoare, cu cozi durabile: nu se pierde nicio comandă și niciun bon.
Versiune 2.2.0 · PHP 8.3 + MSSQL · Fără build step · Windows + Apache · Modul mobil inclus · API de integrare
Versiunea 2.0 aduce API-ul public de integrare pentru aplicații terțe, o actualizare majoră de versiune:
- API REST versionat
/api/v1/pentru export (citire) și import (scriere) de date de către alte aplicații (servere/backend-uri): produse, grupe, mese, bonuri (curente și arhivate după Z), plăți, rapoarte X și un flux incremental de bonuri închise (/events) pentru sincronizare. - Autentificare cu o singură cheie globală (
X-Api-Key), generabilă din Setări → Integrare (se stochează doar SHA‑256), cu opțiuni de restricționare pe IP și limitare a numărului de cereri. - Acces extern exclusiv prin VPN (recomandat SoftEther VPN Azure + SecureNAT, alternativ Tailscale/ZeroTier) — fără expunere pe internet, fără domeniu/certificat/TLS; aplicația rămâne pe HTTP în rețeaua locală.
- Scriere tranzacțională cu suport
Idempotency-Key(reîncercări sigure) și audit al fiecărei cereri (tblApiLog). - Documentație completă pentru integratori:
docs/API-INTEGRARE.md, specificația OpenAPI (docs/openapi.json) și referința HTML (docs/api-reference.html).
- Instalare automată „într-un pas" — un installer dedicat configurează totul pe un Windows 11 curat: Apache, PHP, SQL Server Express, Python, serviciile și scurtăturile.
- Actualizare la un click, cu versionare (versiune + build + commit), backup automat înainte de update și posibilitatea de a ști exact ce versiune rulează pe fiecare stație.
- Nu pierde niciodată o comandă sau un bon — cozi durabile cu reîncercare automată; imprimanta sau serverul pot fi oprite, nimic nu se pierde.
- Funcționează offline și exportă către server de îndată ce revine conexiunea.
- Fiscal + POS bancar + tipărire bucătărie integrate — nu module externe scumpe.
- Un singur produs, două moduri: Restaurant și FastFood.
- Modul mobil inclus (tabletă/telefon), fără costuri suplimentare.
Alegerea se face din Setări → General (TipVanz). Aceeași bază de date, același meniu, aceeași interfață de programare.
- Hartă de mese (80 de locuri), bon deschis pe masă, proprietar pe ospătar.
- Bon de comandă către bucătărie/bar, pe secții, cu numerotare proprie a bonurilor de secție.
- Notă de plată, notă proformă, transfer produse între mese și mod preparare.
- Fără hartă de mese — aplicația pornește direct în ecranul de vânzare.
- Fără bon de secție, fără notă proformă, fără transfer, fără mod preparare (ascunse automat).
- La închidere se emite doar bonul fiscal; totalul și restul apar în panoul de vânzare.
Un singur proiect, două fluxuri — nu două aplicații de întreținut.
- Mese și bonuri — 80 de mese, deschidere/închidere bon, proprietar pe ospătar (un ospătar nu poate intra pe masa altuia).
- Meniu — grupe și produse cu prețuri, culori, fonturi și dimensiuni configurabile; Meniul Zilei.
- Scanare cod — caută după cod de bare sau cod produs.
- Bon de comandă pe secții, cu numerotare proprie a bonurilor de secție (contor dedicat, resetat la raportul Z).
- Mod preparare — text atașat unei linii (ex. „fără ceapă"), care nu afectează totalul.
- Discount pe linie sau pe bon, procentual sau valoric, distribuit corect pe cotele de TVA.
- Trei moduri configurabile: complet (produs/subtotal, procent/valoare, cu popup) · doar procent la subtotal · procent fix la subtotal, aplicat direct.
- Stornare (VD) — anulare a liniilor deja trimise, cu parolă de manager și motiv; cantitățile nu pot fi depășite; liniile netrimise se anulează direct.
- Split pe mai multe forme de plată (numerar, card, tichet etc.), cu rest afișat.
- Setarea plată combinată (DA/NU): la NU, ecranul de închidere afișează doar formele de plată (fără numpad), iar un click pe o formă închide nota integral.
- POS bancar (terminal card) — când nota are plată pe card și
tblSet.PoSbanca = 1, aplicația comunică sincron cu terminalul printr-un driver extern, cu timeout de 190 s, dialog Cancel / Retry / Ignore la refuz (Cancel păstrează nota deschisă, Ignore o închide oricum) și audit al fiecărei încercări (sumă, TRX_ID, status, mesaj) întblPosBancaLog.
- Fișierul de comenzi pentru driverul fiscal, generat pentru FiscalWire (
.inp) sau FiscalNet (separator^), în funcție detblSet.TipCasaMarcat. - CUI (cod fiscal client) — popup cu tastatură dedicată, validat cu cifra de control ANAF și trimis pe bon.
- Coadă durabilă de tipărire — bon de comanda pe secții, nota de plată, nota proformă și rapoarte.
- Destinațiile fizice ale fiecărei secții (Windows raw, rețea :9100, fișier, preview) se configurează din aplicație, cu test de tipărire; modificările se aplică instant (hot-reload).
- Emulator de bon inclus — previzualizare fără hardware.
- Rapoarte X — PLU, Grupe, Secții, Casieri, General și Note (bonurile închise din sesiune, cu detaliul fiecărei note).
- Închidere Z — arhivare și golire atomică a zilei, cu raport General Z plus rapoartele selectate.
- Setări, grupe, produse, secții, mese, ospătari, moduri preparare, parole, cote TVA, imprimante pe secții, forme de plată, antet, notă, conectare server și sincronizare produse — toate editabile direct din aplicație.
- Pagină dedicată pentru tabletă/telefon (
mobile.html) pentru marcarea meselor, independentă de POS-ul desktop, dar folosind aceleași API-uri.
- API public de integrare (
/api/v1/) — aplicații terțe pot exporta (produse, grupe, mese, bonuri curente/arhivate, plăți, rapoarte X) și importa (produse, grupe, mese, ospătari, forme de plată, cote TVA) date, cu autentificare pe cheie (X-Api-Key), idempotență la scriere și audit. Accesul din exterior se face exclusiv prin VPN. Vezidocs/API-INTEGRARE.md. - Export către server — la închiderea fiecărei note se scrie o comandă
EXEC EmitBon_Ext_NOU(Restaurant) /EmitBon_Ext_2(FastFood) într-o coadă durabilă; un serviciu Python o execută pe serverul dintblConectare. Dacă serverul e oprit, comanda se reîncearcă la infinit, cu backoff. - Import produse/grupe la pornire — sincronizare de pe serverul extern prin procedura
dbo.ImportProd. Se pot importa una sau mai multe magazii (tblSet.MagID, ex.1,2); la produsele prezente în mai multe magazii câștigă prima din listă.
- Tranzacții atomice pentru operațiunile critice (închiderea bonului, marcarea, închiderea Z): un bon sau o zi nu poate rămâne pe jumătate procesat(ă).
- Cozi durabile pentru tipărire și export — joburile sunt persistate în baza de date și reîncercate automat, deci o imprimantă offline nu pierde și nu blochează nicio comandă.
- Interogări parametrizate — elimina injectia SQL.
- Parole pe roluri — programare, rapoarte, stornare, discount și ieșire; autentificare pe fiecare ospătar, cu blocare.
- Credențiale în fișier local, ignorat de git.
- Backup automat înainte de fiecare actualizare.
- Installer automat (repo separat
TableManager-Setup): pe un Windows 11 gol configurează Apache + PHP 8.3 + SQL Server 2022 Express + Python 3.12, deploy-ul aplicației, clonarea bazei de date, mediul virtual.venv, serviciile și scurtăturile. Dublu-click peSetup.bat; instalarea este idempotentă. - Pornire kiosc —
Pornire-POS-Kiosk.vbs(fără fereastră DOS) deschide aplicația fullscreen și importă produsele la pornire. - Actualizare din aplicație — butonul Update compară versiunea instalată cu GitHub, face backup și aplică automat.
- Versionare — fiecare stație știe exact ce rulează: fișierul
VERSION(ex.2.2.0) plus build + commit + dată, vizibile în Setări → Servicii, în dialogul Update și programatic prinapi/version.php. Procesul de release (bump de versiune,sync.sh, tag git) este descris în docs/VERSIONARE.md.
- PHP + MSSQL (extensia
sqlsrv) — backend simplu, fără framework. Apel direct de proceduri stocate și tranzacții ACID native pentru operațiuni critice; zero layer de abstractizare care să ascundă comportamentul bazei de date. - JavaScript și CSS pur (fără framework, fără build step) — frontend desktop în
js/pos.js, mobil înjs/mobile.js. Deploy = editezi fișierul și reîncarci pagina. - Aspect scalat pe canvas — design de bază 1024×768, scalat proporțional pe orice ecran, fără CSS fragil de tip vw/vh.
- Serviciu de tipărire Python + ESC/POS —
print-service/randează bonurile și le trimite nativ către imprimante (Windows raw sau rețea :9100); își deține configurarea și o reîncarcă la cald, cu emulator inclus pentru testare. - Rulează pe HTTP — serviciile își deduc singure URL-ul API din numele folderului de instalare, deci funcționează chiar dacă proiectul este redenumit sau instalat în alt folder direct sub
htdocs.
- Apache cu PHP și extensia
php_sqlsrvîncărcată. - Microsoft SQL Server (baza de date configurabilă în
api/db.local.php). - Python 3.12 (Windows) pentru componentele Python (
print-service/,sync-service/,import_server_grp_prod.py) — opțional, doar dacă folosiți una dintre ele. Toate rulează dintr-un mediu virtual comun.venvdin rădăcina proiectului, creat o singură dată cusetup-venv.bat(dependințele —pyodbc,pywin32,pyserial— sunt înrequirements.txt). Este nevoie și de un ODBC Driver for SQL Server instalat. Mediul virtual este obligatoriu: fără el, pornirea kiosc-ului și a serviciilor Python se oprește cu un mesaj care cere rulareasetup-venv.bat. Pe stațiile cu două conturi Windows (unul de service + unul de utilizator POS) Python trebuie instalat pentru toți utilizatorii (implicit înC:\Program Files\Python312), nu per-user:.venveste comun tuturor conturilor, iar un Python per-user este accesibil doar din contul care l-a instalat — altfel pornirea serviciilor se oprește cuNo Python at 'C:\Users\<cont>\...\python.exe'.setup-venv.batrecreează automat un.venvcare nu poate fi folosit de contul curent, dacă găsește o instalare pentru toți utilizatorii.
- Copiați proiectul în directorul servit de Apache (ex.
htdocs/rual). - Reconstruiți baza de date rulând
db/schema.sqlapoidb/seed.sql(detalii în db/README.md). - Configurați conexiunea: copiați
api/db.local.example.phpînapi/db.local.phpși completați serverul, baza, utilizatorul și parola. - (Opțional, dar obligatoriu dacă folosiți componentele Python) Rulați
setup-venv.batdin rădăcina proiectului: creează.venv, instalează dependințele și creează scurtăturile (cele două servicii înStartupșiTableManager POSpe Desktop). - (Opțional) Porniți serviciul de tipărire:
print-service/start-print-service.bat(saustart-print-service-hidden.vbs). Ascultă doar pe127.0.0.1:8756. Destinațiile se configurează din Setări → Imprimante secții, cu butoane de test: fiecare țintă (secție, nota, rapoarte) poate fi pe rețea (IP:port) sau Windows / USB (imprimantă locală cu driver Windows instalat, marcată(USB)dacă e pe port USB). Imprimantele USB sunt accesibile doar pe stația care rulează serviciul de tipărire. - (Opțional) Porniți serviciul de export:
sync-service/start-sync-service.bat(sau varianta-hidden). Ascultă doar pe127.0.0.1:8757și citește serverul/credențialele dintblConectare(ID = 1). - (Opțional) Folosiți
Pornire-POS-Kiosk.vbspentru a deschide aplicația în mod kiosc fullscreen, fără fereastră DOS.
Structura bazei de date și datele de referință sunt publicate în directorul db/:
db/schema.sql— tabelele, indecșii, constrângerile, cheile străine și procedurile stocate.db/seed.sql— date de referință minime plus un meniu demo (fără date reale).
Pașii sunt: rulați db/schema.sql, apoi db/seed.sql, apoi configurați api/db.local.php. Instrucțiuni complete: db/README.md.
Backup planificat al bazei de date MSSQL, independent de aplicație (nu depinde de un browser deschis):
tools/backup-db.ps1— face un backup full (BACKUP DATABASE ... WITH INIT, CHECKSUM), îl verifică (RESTORE VERIFYONLY), șterge backup-urile mai vechi de 14 zile și scrie un log înlogs/backup_db.log. Credențialele sunt citite dinapi/db.local.php(aceeași sursă ca aplicația), iar execuția folosește ADO.NET (System.Data.SqlClient), fără dependențe suplimentare.tools/backup-db-task.xml— task Windows Scheduler care rulează scriptul zilnic la 03:00, ca SYSTEM (fără parolă stocată), cuStartWhenAvailable(rulează și dacă stația era oprită).tools/install-backup-task.bat— montează task-ul (rulează ca Administrator): își deduce folderul proiectului, rescrie calea din XML și apeleazăschtasks /Create.
Implicit, backup-urile se scriu în C:\ABCSoft\Data\backup, cu numele <BazaDeDate>_<yyyyMMdd_HHmmss>.bak. Când SQL Server rulează pe aceeași mașină, scriptul creează folderul și acordă drepturi de scriere contului serviciului SQL; dacă serverul e remote, folderul trebuie să existe deja și să fie scriibil pe acea mașină.
Montare:
tools\install-backup-task.bat :: click dreapta -> Run as administratorsau manual: schtasks /Create /TN "TableManager\Backup DB" /XML "…\tools\backup-db-task.xml" /F.
Rulare manuală / test:
powershell -ExecutionPolicy Bypass -File tools\backup-db.ps1 :: backup acum
powershell -ExecutionPolicy Bypass -File tools\backup-db.ps1 -DryRun :: doar afișează planul
schtasks /Run /TN "TableManager\Backup DB" :: forțează task-ulRestaurare (după oprirea aplicației), în SQL:
RESTORE DATABASE [NumeBaza]
FROM DISK = N'C:\ABCSoft\Data\backup\NumeBaza_20260101_030000.bak'
WITH REPLACE;index.html POS-ul desktop (screens, modale, canvas scalat)
js/pos.js toata logica POS-ului desktop (stare globala POS_STATE)
css/pos.css stilurile POS-ului desktop
mobile.html clientul mobil/tableta (marcare mese)
js/mobile.js logica modulului mobil (stare globala MOBILE_STATE)
css/mobile.css stilurile modulului mobil
VERSION versiunea human (ex. 1.5.0)
docs/img/ capturile de ecran din acest README
api/ endpoints PHP (JSON)
db.php conexiunea MSSQL (+ db.local.php local, ignorat)
order_action.php dispatcher: add_product, close_bill, void_line, apply_discount etc.
menu.php, get_order.php, get_tables.php
rapoarte.php rapoarte X, inchidere Z, printare rapoarte
print_queue.php API-ul cozii durabile de printare
print_common.php helperi comuni (ensurePrintQueueTable, enqueuePrintJob)
send_queue.php API-ul cozii durabile de export catre server (temp_Send_Sql)
send_common.php helperi comuni (ensureSendSqlTable, enqueueBillSendSql)
print_config.php proxy catre serviciul de printare (citire/salvare config, test)
pos_banca.php comunicarea cu terminalul bancar (POS bancar) + audit
version.php versiunea aplicatiei (VERSION + build + commit)
version_common.php helperi pentru versionare (stare, eticheta, log)
exit_app.php inchide browserul POS din parola de inchidere
sync_products.php ruleaza procedura stocata dbo.ImportProd (Sincronizare produse)
... editori de configurare (produse, grupe, mese, tva, kp, fp, etc.)
sql/z_procedure.sql procedura stocata de inchidere Z
print-service/ serviciu Python de printare ESC/POS
server.py, worker.py, escpos.py, emulator.py, targets.py, config.py, config.json
sync-service/ serviciu Python de export catre serverul extern (temp_Send_Sql)
server.py, worker.py, db.py, config.py, config.json
db/ reconstructia bazei de date
schema.sql structura tabelelor + proceduri stocate
seed.sql date de referinta + meniu demo (fara date reale)
Pornire-POS-Kiosk.vbs lansator kiosc ascuns (fara fereastra DOS) + import produse la pornire
Pornire-POS-Kiosk.bat lansator kiosc cu fereastra vizibila (aceeasi logica)
import_server_grp_prod.py import produse/grupe de pe server (dbo.ImportProd)
requirements.txt dependintele Python (pyodbc, pywin32, pyserial) pentru mediul virtual
setup-venv.bat creeaza .venv, instaleaza dependintele si creeaza shortcut-urile (o singura data)
tools/create-shortcuts.vbs creeaza shortcut-urile: serviciile in Startup + POS pe Desktop
tools/backup-db.ps1 backup full al bazei de date (planificat, verificat, cu retentie)
tools/backup-db-task.xml task Windows Scheduler pentru backup (zilnic 03:00, ca SYSTEM)
tools/install-backup-task.bat monteaza task-ul de backup (Run as administrator)
.venv/ mediul virtual Python (creat local, ignorat de git)
dev/sync.sh commit + push catre GitHub + regenereaza snapshot-ul de instalare
La închiderea notei (close_bill), în aceeași tranzacție, se generează fișierul de comenzi pentru casa de marcat și se scrie în coada durabilă de tipărire; serviciul Python îl scrie în spool/fiscal și îl copiază în folderul monitorizat de driverul fiscal (tblSet.CaleFisierComenziECR), de unde casa îl procesează. Dacă folderul nu e disponibil, jobul se reîncearcă cu backoff, deci bonul nu se pierde.
Tipul casei se alege din Setări → Casa Marcat (tblSet.TipCasaMarcat):
- FiscalWire (driver FiscalWire) — fișier
.inp:H,1,______,_,__;antet (fără linieFla final, ca în procedura veche);S,1,______,_,__;NUME;PRET;CANT;1;1;NrTVA;0;0;vânzare (nume majuscule, trunchiat la 32 de caractere, fără completare cu spații; preț cu 2 zecimale; cantitate cu 3 zecimale; storno = cantitate negativă);C,1,______,_,__;1;PROCENT;discount pe linie (procent simplu, ex.5.00= 5%);K,1,______,_,__;RO12345678;cod fiscal client, înainte de prima vânzare;T,1,______,_,__;COD_PLATA;;;;;încasare la o singură formă de plată (fără sumă: FiscalWire calculează singur totalul); la mai multe forme de plată se scrie câte o linie cu suma fiecărei forme (T,1,______,_,__;COD_PLATA;SUMA;;;;), descrescător după cod.
- FiscalNet — fișier
.txtcu separator^:S^NUME^PRET^CANT^buc^GRTVA^1,DV^valoare/MV^valoarepentru discount/majorare,VS^...pentru stornare,ST^subtotal,P^COD_PLATA^SUMAîncasare;CF^RO12345678cod fiscal client, înainte de prima vânzare.
- Fisco, fprwin — în curs de implementare.
Codurile de plată se iau direct din tblFP.FPID (0 = Numerar, 1 = Card, 2 = CEC, 3 = Tichet, 4 = OP, 5 = Voucher): la FiscalWire se scrie FPID, la FiscalNet FPID + 1. Grupa de TVA se rezolvă din tblTVA după cota liniei (tblNoteD.TVAc → tblTVA.Nr_TVA).
Implicit, bonul fiscal nu afișează discountul și nici stornarea (doar cantitățile și prețurile nete). Setarea tblSet.EvidDiscBonFisc = 1 afișează discountul pe fiecare linie de produs (produsul la preț de catalog, urmat de comanda de discount valoric), iar tblSet.EvidStornoBonFisc = 1 afișează separat liniile de storno. Cele două se setează independent, din Setări → Casa Marcat.
Setarea AsteaptaRaspunsCasa (Setări → Casa Marcat, implicit NU): când este DA și tipul casei este FiscalWire sau FiscalNet, la închiderea notei POS-ul scrie fișierul de comenzi direct în tblSet.CaleFisierComenziECR și așteaptă până la AsteptareCasaSec secunde (implicit 30) confirmarea în tblSet.CaleFisierRaspunsECR, înainte de a închide nota:
- FiscalWire: fișierul
.nrb(prima linieOK;Z=..|NR=..|...|BF=..) confirmă bonul;NrBon(NR) șiNrZ(Z) reale sunt trimise mai departe serviciului de export;CANCELEDsau orice linie cu statusErblochează închiderea. - FiscalNet: fișierul de răspuns conține
BONOK=1+NRBON=<nr>la succes,BONOK=0+ERRCODE/ERRINFOla eroare, sauBONOK=-1. - lipsa răspunsului (timeout) înseamnă că nota nu se închide; ecranul de plată revine la starea inițială și se poate reîncerca.
- în orice caz de eșec, POS-ul șterge fișierul de comenzi, ca driverul să nu tipărească ulterior un bon abandonat; înainte de fiecare trimitere se curăță și fișierele
pos_tm_*abandonate. - fiecare eșec se scrie în
logs/fiscal_wait.log.
tools/mock_fiscalwire.py(pornit cutools/mock_fiscalwire.bat, din.venv) simulează driverul FiscalWire: scrie răspunsurile.txt/.nrbîn folderul configurat (moduriok/err/canceled/silent/random) și șterge fișierul de comandă după procesare (se poate păstra cu--keep).tools/mock_fiscalnet.py(cutools/mock_fiscalnet.bat) simulează driverul FiscalNet: scrie răspunsul cu același nume ca al comenzii (moduriok/err/pos/silent/random).
Acest proiect este distribuit sub GNU General Public License v3.0 (GPL-3.0).
Copyright (C) 2026 Florian Liviu Stefanescu.
Textul complet al licenței: LICENSE.
Aplicația este software liber: o poți folosi, studia, modifica și redistribui liber, cu condiția ca orice versiune derivată distribuită să rămână, la rândul ei, sub GPL-3.0 și cu sursa deschisă. Se distribuie fără nicio garanție.
© ABCSoft · https://abcsoft.ro









