# Editor eFactura Editor static în browser pentru fișiere XML eFactura (UBL 2.1) conforme cu standardul ANAF. ## Demo - GitHub Pages: https://romfast.github.io/efactura-generator/ ## Scop Aplicația este intenționat **statică** (HTML + CSS + JavaScript, fără build, fără backend obligatoriu) astfel încât să poată fi găzduită direct pe GitHub Pages sau pe orice server web simplu. Cazurile principale de utilizare: - **Corecții minore** într-un XML eFactura existent (date factură, furnizor, client, articole, TVA). - **Generare factură storno** pornind de la o factură existentă, prin butonul „Stornează”. Nu este un sistem complet de facturare — lucrează cu câte un singur XML, încărcat și salvat local. ![Factura 1](screenshot1.jpg) ![Factura 2](screenshot2.jpg) ![Factura 3](screenshot3.jpg) ## Funcționalități ### Încărcare XML - Încărcare fișier XML local prin butonul „Alege Fișier XML”. - Încărcare automată dintr-un fișier temporar prin parametru URL (`index.html?xml=`), folosit împreună cu `receiver.php` pentru integrare cu sisteme externe. ### Detalii factură - Număr factură, data emiterii, data scadentă (cu calendar Pikaday și format `dd.mm.yyyy`). - Monedă document și monedă TVA opțională (cu generarea automată a celui de-al doilea tag `TaxTotal` când monedele diferă). - Câmp text adițional (notă) cu limită de 900 de caractere și împărțire automată. ### Furnizor și client - Nume, cod TVA, număr de înregistrare, adresă, oraș, județ, țară, telefon, persoană de contact, email. - Selector de țară conform ISO 3166-1 și selector de județ conform codurilor `RO-XX`. - Tratare specială pentru București și pentru furnizori neplătitori de TVA (cod fiscal fără atributul `RO`). ### Articole factură - Adăugare, editare și ștergere articole. - Cantitate, preț, cotă TVA, unitate de măsură (EA, XPP, H87, KGM, MTR, LTR, MTQ). - Reduceri pe linie cu cod și motiv reducere. - Coduri de identificare articole multiple per linie: cod vânzător, cod cumpărător, cod de bare, CPV, NC8, cod vamal. ### TVA - Tipuri TVA suportate: `S` (Standard), `AE` (Taxare Inversă), `O` (Neplătitor TVA), `Z` (Cotă 0%), `E` (Neimpozabil). - Coduri de scutire `VATEX-EU-*` cu motiv corespunzător, completate automat în funcție de tipul TVA și editabile manual. - Defalcare TVA cu mai multe cote, editabilă inline (bază impozabilă și valoare TVA). ### Reduceri și taxe la nivel de factură - Adăugare/editare/ștergere reduceri și taxe suplimentare la nivel de document. - Coduri motiv pentru reduceri (95, 41, 42, 60, 62 etc.) și pentru taxe (TV, FC, ZZZ). ### Totaluri - Recalculare automată: subtotal, total reduceri, total taxe, valoare netă, TVA, total. - Editare inline a totalurilor (click pe valoare) cu păstrarea totalurilor originale din XML-ul încărcat. - Buton „Recalculează Totaluri” pentru regenerare din articole. ### Storno - Buton „Stornează” care convertește factura curentă într-o factură storno (cantități și valori negative) gata de salvat. ### Salvare și printare - Buton „Salvează XML” care generează și descarcă un XML UBL conform. - Vizualizare printabilă în două formate (standard și compact) prin șabloanele din `templates/`. ### Formatare - Numere, cantități și sume formatate conform locale-ului browserului, cu conversie automată la punct decimal pentru XML. ## Instalare și utilizare ### Opțiunea 1: Server web static Copiați toate fișierele pe serverul web păstrând structura directoarelor și accesați `index.html` prin URL-ul serverului. Funcționează pe orice server static (Apache, nginx, GitHub Pages etc.). ### Opțiunea 2: Dezvoltare locală cu Node.js ```bash node js/server.js ``` Apoi deschideți http://localhost:3000 Serverul Node este minimal (fără dependințe) și servește doar fișierele statice. ### Opțiunea 3: Script `start.sh` (Node + PHP simultan) Pentru testare vizuală manuală cu receiver-ul PHP activ: ```bash ./start.sh ``` Pornește în paralel: - Node static server pe `http://localhost:3000` (frontend, fără PHP — simulează GitHub Pages) - PHP built-in server pe `http://localhost:8000` (servește atât frontend cât și `receiver.php`, `test-config.php`) **Pentru testarea funcționalităților ANAF (lookup CIF, validare, PDF) deschideți `http://localhost:8000/` — frontend-ul apelează `./receiver.php` pe același origin, deci pe `:3000` (Node nu execută PHP) veți primi 404.** Folosiți `:3000` doar pentru a verifica comportamentul fără PHP. Dacă porturile sunt deja ocupate, scriptul oprește procesele existente înainte de pornire. `Ctrl+C` oprește ambele servere. Loguri în `logs/dev-node.log` și `logs/dev-php.log`. Override porturi: `NODE_PORT=4000 PHP_PORT=9000 ./start.sh`. ### Opțiunea 4: Docker (local sau CI) Imaginea include Apache + PHP 8.2 cu `mod_rewrite` și `mod_headers`, identic cu un hosting de producție. **Build și run:** ```bash docker build -t efactura-generator . docker run --rm -p 8080:80 efactura-generator ``` Apoi deschideți http://localhost:8080 **Cu PHP receiver activ** (opțional — doar dacă integrați cu un sistem extern): ```bash # Copiați și editați config.json înainte de build cp config.json config.local.json # Editați config.local.json: api_key, allowed_ips docker build -t efactura-generator . docker run --rm -p 8080:80 \ -v "$(pwd)/config.local.json:/var/www/html/config.json:ro" \ efactura-generator ``` **Testare rapidă (fără PHP):** ```bash # Nici o dependință — server Node minimal, doar fișiere statice node js/server.js # http://localhost:3000 ``` > **Notă:** Directorul `temp/` din container este volatil — se șterge la `docker run --rm`. Dacă vreți persistență, montați un volum: `-v "$(pwd)/temp:/var/www/html/temp"`. ### Opțiunea 5: Integrare cu sistem extern (PHP) Pentru a primi un XML dintr-o aplicație externă și a-l deschide direct în editor: 1. Configurați `config.json` (cheie API, IP-uri permise, durată de viață fișiere temporare). 2. Sistemul extern face POST cu conținutul XML către `receiver.php`, transmițând antetul `X-Api-Key`. 3. `receiver.php` validează XML-ul și namespace-urile UBL, salvează în `temp/` și returnează numele fișierului. 4. Utilizatorul este redirecționat către `index.html?xml=`, care încarcă XML-ul automat. 5. Fișierul temporar este șters după încărcare; fișierele mai vechi decât `temp_file_lifetime` ore sunt curățate automat. Pentru diagnosticare există pagina `test-config.php`. ## Structura proiectului ``` efactura-generator/ ├── index.html # Pagina principală ├── styles/main.css ├── js/ │ ├── script.js # Logica completă: parsare/generare XML, formular, totaluri │ ├── formatter.js # Formatare numere/sume/cantități │ ├── print.js # Generare vizualizare printabilă │ └── server.js # Server static minimal pentru dezvoltare locală ├── templates/ │ ├── print.html # Șablon printare standard │ └── print-compact.html # Șablon printare compact ├── receiver.php # Endpoint opțional pentru încărcare XML din sisteme externe ├── test-config.php # Pagina de diagnosticare pentru receiver ├── config.json # Configurație receiver (API key, IP-uri permise) └── .htaccess.template # Configurație Apache pentru hosting în producție ``` ## Licență [AGPL-3.0-or-later](LICENSE.md) Dacă folosiți acest software, chiar și ca serviciu web, trebuie să: 1. Menționați proiectul original. 2. Partajați toate modificările făcute. 3. Folosiți aceeași licență AGPL-3. ## Linkuri - [Istoric modificări](CHANGELOG.md) - [De făcut](TODO.md) - [www.romfast.ro](https://www.romfast.ro)