nullInvoice è un microservizio Spring Boot per la generazione e gestione automatizzata delle fatture con modelli HTML completamente personalizzabili, progettato per l'integrazione con webstore e piattaforme SaaS.
Le aziende usano nullInvoice per gestire la generazione delle fatture dopo che le vendite sono state completate. I fornitori vengono configurati una sola volta tramite la UI web, poi la sua applicazione chiama la REST API per generare fatture conformi on-demand.
Come funziona:
- Configurazione: Configuri i fornitori nella UI con dati aziendali, locale, valuta, aliquote fiscali, branding personalizzato e modelli di fattura
- Autenticazione: Generi chiavi API dalla Dashboard amministratore per un accesso sicuro alla REST API
- Integrazione: Il suo webstore/SaaS effettua chiamate API autenticate a
/api/v1/invoices/generateusando l'ID del fornitore - Generazione: Le fatture vengono create da modelli HTML completamente personalizzabili e restituite come JSON o PDF con metadati negli header
- Consegna: La sua applicazione riceve la fattura e può inoltrarla ai clienti o conservarla per archivio
┌─────────────────┐
│ Cliente │
│ completa │
│ l'acquisto │
└────────┬────────┘
│
▼
┌─────────────────────────────────────────┐
│ La sua piattaforma Webstore/SaaS │
│ ───────────────────────────────────── │
│ 1. Elabora il pagamento │
│ 2. Emette ricevuta digitale │
│ (obbligatoria) │
│ 3. Il cliente richiede fattura? ────┐ │
└──────────────────────────────────────┼──┘
│
│ Chiamata API
▼
┌──────────────────────────────┐
│ Servizio nullInvoice │
│ ────────────────────────── │
│ POST /api/v1/invoices/ │
│ generate │
│ │
│ - Valida ID fornitore │
│ - Applica modello │
│ - Salva snapshot HTML │
│ - Genera PDF │
│ - Restituisce la fattura │
└──────────────┬───────────────┘
│
│ Risposta (JSON o PDF)
▼
┌──────────────────────────────────────────┐
│ La sua piattaforma Webstore/SaaS │
│ ────────────────────────────────────── │
│ - Riceve metadati JSON O file PDF │
│ - Salva il numero fattura per archivio │
│ - Invia il PDF al cliente via email │
└──────────────────────────────────────────┘
Modelli completamente personalizzabili
- Le fatture si basano su modelli HTML definiti dall'utente con CSS inline
- I modelli supportano oltre 30 placeholder per dati di fornitore, cliente e finanziari
- I modelli predefiniti per fornitore consentono branding diverso per unità di business
Immutabilità dei documenti
- Ogni fattura memorizza uno snapshot dell'HTML parsato al momento della generazione
- Le modifiche ai modelli non influenzano le fatture già generate
- Le fatture possono essere rigenerate in modo coerente dallo snapshot salvato
- Le autorizzazioni del database impediscono l'eliminazione dei record delle fatture (compliance finanziaria)
Pronto per multi-tenant
- Configuri più fornitori con impostazioni indipendenti (locale, valuta, numerazione, branding)
- I chiamanti API specificano l'ID del fornitore per generare fatture per diverse entità aziendali
Consegna flessibile
- Restituisce i metadati della fattura come JSON per archiviazione (
response_type: number) - Restituisce il PDF direttamente con metadati negli header per consegna immediata (
response_type: pdf) - Recupero PDF successivo tramite
/api/v1/invoices/{invoiceNumber}/pdf
Documentazione OpenAPI
- Documentazione API interattiva disponibile su
/swagger - Specifica OpenAPI JSON su
/openapi - Esempi completi di request/response e funzionalità try-it-out
nullInvoice include autenticazione integrata (login UI basato su sessione + autenticazione con chiave API per gli endpoint REST). Anche se offre sicurezza di default, l'applicazione è comunque destinata a deployment in reti interne/private.
Deploy consigliato:
- Dietro un firewall o VPN
- All'interno di una rete privata accessibile solo dalle sue applicazioni fidate
- Con HTTPS/TLS abilitato per tutte le connessioni
- Dietro un reverse proxy con rate limiting configurato
Per i deploy in produzione sono necessarie misure di sicurezza aggiuntive:
- Abilitare HTTPS/TLS
- Configurare il rate limiting a livello di reverse proxy
- Usare password amministratore robuste
- Ruotare regolarmente le chiavi API
- Conservare le chiavi API in un sistema sicuro di gestione segreti (HashiCorp Vault, AWS Secrets Manager, ecc.)
Veda la sezione Sicurezza e best practice per una checklist completa di produzione.
nullInvoice è una pipeline di generazione fatture progettata per creare, archiviare e consegnare documenti di fattura. Non:
- Traccia pagamenti o stati di pagamento oltre i flag base "unpaid/issued"
- Gestisce crediti o debiti
- Genera report finanziari o bilanci
- Si integra con sistemi contabili (registri, giornali, ecc.)
- Gestisce contabilità, riconciliazioni o dichiarazioni fiscali
Per una gestione finanziaria completa, integri nullInvoice con un sistema contabile dedicato. Usi questo servizio per generare i documenti di fattura, poi li importi nel suo software contabile per tracciamento e compliance.
- Java 21, Spring Boot 3.5.3
- MariaDB + JPA
- Thymeleaf (UI)
- OpenHTMLToPDF (PDFBox)
- OpenAPI su
/openapi, Swagger UI su/swagger
Per deployment Docker (consigliato):
- Docker
- Docker Compose
Per sviluppo locale:
- Java 21 (JDK - Eclipse Temurin o OpenJDK)
- Maven 3.9+
- MariaDB 10.5+ (o MySQL 8.0+)
- Binario standalone di Tailwind CSS (per build CSS - da GitHub releases)
Creare il database:
CREATE DATABASE nullinvoice CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;Creare un utente applicazione dedicato con permessi limitati:
CREATE USER 'nullinvoice'@'localhost' IDENTIFIED BY 'your_secure_password';
-- Conceda i permessi per operazioni normali e migrazioni dello schema
GRANT SELECT, INSERT, UPDATE ON nullinvoice.* TO 'nullinvoice'@'localhost';
GRANT CREATE, ALTER, INDEX, REFERENCES ON nullinvoice.* TO 'nullinvoice'@'localhost';
FLUSH PRIVILEGES;Per accesso remoto, regoli l'host:
CREATE USER 'nullinvoice'@'%' IDENTIFIED BY 'your_secure_password';
GRANT SELECT, INSERT, UPDATE ON nullinvoice.* TO 'nullinvoice'@'%';
GRANT CREATE, ALTER, INDEX, REFERENCES ON nullinvoice.* TO 'nullinvoice'@'%';
FLUSH PRIVILEGES;Importante: perché questi permessi limitati?
Le fatture sono documenti finanziari immutabili che non devono mai essere eliminate dopo la creazione. L'utente dell'applicazione è intenzionalmente limitato e non può:
DELETE- non può eliminare recordDROP- non può eliminare tabelle o databaseTRUNCATE- non può svuotare tabelleGRANT- non può concedere permessi ad altri
Questo garantisce l'integrità dei dati e la conformità ai requisiti di conservazione dei record finanziari. Il permesso UPDATE è concesso per i cambi di stato (es. segnare fatture come pagate) e soft delete sui record delle parti.
- Lo schema del database è gestito da migrazioni Flyway
- Schema iniziale:
nullInvoice/src/main/resources/db/migration/V1__initial_schema.sql - Lo schema viene creato/aggiornato automaticamente all'avvio dell'applicazione
- La modalità DDL di Hibernate è impostata su
none(Flyway gestisce tutti i cambi di schema)
Un file di configurazione di esempio è fornito in .env.example. Lo copi in .env e adatti i valori per il suo ambiente.
Variabili d'ambiente (valori predefiniti tra parentesi):
TZ- RICHIESTO fuso orario di sistema (Europe/Sofia)APP_PORT(8080)DB_HOST(localhost)DB_PORT(3306)DB_USER(nullinvoice)DB_PASSWORD(vuoto)DB_NAME(nullinvoice)DB_PARAMS- RICHIESTO parametri JDBC aggiunti all'URL di connessione
DEVE impostare il fuso orario in DUE punti:
TZvariabile d'ambiente - imposta il fuso orario di sistema/applicazioneserverTimezoneparametro inDB_PARAMS- imposta il fuso orario della connessione al database
Entrambi i valori DEVONO corrispondere al fuso orario del server database per interpretare e salvare correttamente date e orari.
Esempio di configurazione:
TZ=Europe/Sofia
DB_PARAMS=?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Europe/SofiaFusi orari comuni: UTC, Europe/London, America/New_York, Asia/Tokyo. Veda la lista completa.
Fusi orari non allineati causeranno date e timestamp errati nelle fatture.
Al primo avvio, l'applicazione reindirizza a /setup per creare l'account amministratore iniziale. Questo è obbligatorio prima di accedere a qualsiasi altra funzionalità.
Per reimpostare e creare un nuovo account amministratore (recupero di emergenza):
- Arresti l'applicazione
- Trunchi le tabelle
userseapi_keysnel database - Riavvii l'applicazione
- Completi nuovamente il flusso
/setup
Raccomandazioni di sicurezza:
- Usi una password forte per l'account amministratore
- Imposti un suggerimento password (opzionale ma consigliato)
- Generi chiavi API separate per diversi ambienti (dev, staging, prod)
- Revochi le chiavi API inutilizzate
Architettura di autenticazione:
- Accesso UI: Autenticazione basata su sessione con form login
- Accesso API: Autenticazione Bearer token stateless (chiavi API)
- Password: BCrypt con 10 round
- Chiavi API: Formato UUID, hashate con BCrypt, mostrate una sola volta alla generazione
Durata della sessione:
Di default, le sessioni UI scadono dopo 30 minuti di inattività (default di Spring Boot/Tomcat). Gli utenti verranno automaticamente disconnessi e reindirizzati alla pagina di login.
Per personalizzare la durata della sessione, aggiunga il seguente codice a nullInvoice/src/main/resources/application.yml:
server:
servlet:
session:
timeout: 60m # Opzioni: 15m, 30m, 1h, 2h, ecc.Valori di timeout comuni:
15m- 15 minuti (sicurezza più rigorosa)30m- 30 minuti (predefinito)1h- 1 ora (comodità per utenti attivi)8h- 8 ore (esteso per sessioni lunghe)
Checklist per la produzione:
- Abilitare HTTPS/TLS per tutte le connessioni
- Usare password amministratore robuste
- Generare chiavi API separate per ogni applicazione/ambiente
- Deploy dietro firewall o VPN
- Configurare il rate limiting a livello di reverse proxy
- Configurare logging e monitoraggio
- Rivedere regolarmente l'uso delle chiavi API (timestamp dell'ultimo utilizzo)
- Revocare immediatamente chiavi API inutilizzate o compromesse
- Conservare le chiavi API nelle variabili d'ambiente, mai nel codice
- Usare un sistema sicuro di gestione segreti (HashiCorp Vault, AWS Secrets Manager, ecc.)
Protezione CSRF:
- Abilitata per tutti i form UI
- Disabilitata per gli endpoint API (auth Bearer stateless)
Sicurezza al primo avvio:
- L'applicazione è inutilizzabile finché non viene creato un account amministratore tramite
/setup - La pagina di setup è accessibile solo quando non esiste un amministratore
- Dopo il setup è richiesto il login per tutte le funzionalità
Immagini Docker ufficiali: Sono disponibili immagini precompilate su Docker Hub. Cerchi l'immagine ufficiale di nullInvoice per saltare il build.
Build senza cache:
docker compose build --no-cacheAvvii lo stack:
docker compose up -dArresti lo stack:
docker compose down-
Si assicuri di avere un'istanza MariaDB in esecuzione e crei il database. Veda Configurazione database
-
Build di Tailwind CSS (necessario prima del primo avvio):
./build-tailwind.sh
-
Build del progetto con Maven:
cd nullInvoice mvn clean package -
Avvii l'applicazione:
java -jar target/nullinvoice-0.0.1-SNAPSHOT.jar
Il progetto è stato costruito con NetBeans e può essere aperto come progetto Maven con il plugin Spring Boot.
Impostare le variabili d'ambiente in NetBeans:
Opzione 1 - Tramite IDE:
- Clic destro sul progetto >> Properties
- Navigare in Actions >> Run
- Impostare le variabili d'ambiente:
APP_PORT,DB_NAME,DB_USER,DB_PASSWORD
Opzione 2 - Modifica diretta:
- Modifichi
nbactions.xmlnella root del progetto
Al primo accesso verrà reindirizzato a /setup per creare l'account amministratore iniziale:
- Apra
http://localhost:8080(o l'URL configurato) - Verrà reindirizzato automaticamente a
/setup - Crei un account amministratore con nome utente, password e suggerimento opzionale
- Dopo il setup verrà reindirizzato a
/login
Accedi:
- Acceda alla pagina di login su
/login - Usi le credenziali amministratore che ha creato
- Il suggerimento password è disponibile tramite l'icona info (se configurato)
Dashboard amministratore: Dopo il login, acceda alla dashboard amministratore dal menu utente:
- Cambiare la password amministratore
- Generare chiavi API per l'accesso alla REST API
- Revocare chiavi API
- Visualizzare l'uso delle chiavi API (timestamp dell'ultimo utilizzo)
Prerequisiti:
- Configurazione iniziale completata (account amministratore creato)
- Login con credenziali amministratore
Prima di poter generare fatture via API, deve configurare almeno un fornitore tramite la UI web. I fornitori definiscono dati aziendali, locale, valuta, aliquote fiscali, branding personalizzato (tramite modelli) e numerazione fatture per la generazione.
-
Effettui il login nella UI web su
http://localhost:8080(o la porta configurata) -
Vada a Fornitori
-
Crei un nuovo fornitore con i dati aziendali
-
Configuri locale, valuta e impostazioni fiscali
-
Imposti le preferenze di numerazione fatture (prefisso, padding)
-
Annoti l'ID fornitore per l'integrazione API
-
Generi una chiave API da Amministratore > Chiavi API per l'accesso alla REST API
Per esempi di configurazione del fornitore, veda example-images - en-us per un esempio USA o non UE; e eu-de per un esempio UE.
Una volta configurato, può impostare un modello XHTML e usare l'ID fornitore (mostrato nel menu Modifica fornitore) per effettuare chiamate a /api/v1/invoices/generate.
- Gestire fornitori e clienti con soft delete e controlli di unicità.
- Creare e gestire modelli di fattura con branding personalizzato, con un predefinito globale e predefiniti per fornitore.
- Generare fatture con snapshot HTML salvati nel record della fattura.
- Renderizzare fatture in PDF su richiesta.
- Cercare e ordinare fatture per numero, data, cliente, fornitore e stato.
- Gestire lo stato della fattura come
unpaidoissued(pagata/finale).
- I valori di stato sono
unpaideissued.issuedè considerato pagata e finale. - La creazione di una fattura via API produce sempre lo stato
issuede l'API non accetta override dello stato. - La creazione via UI può contrassegnare una fattura come
unpaidsolo quando è impostata una data di scadenza. - Le fatture non pagate possono essere contrassegnate come
issueddalla pagina dettagli fattura. - Le fatture emesse non possono essere riportate a
unpaid.
/invoices/newcrea fatture usando il fornitore selezionato dal cookie (se presente).- Il toggle per
unpaidè disabilitato finché non viene fornita una data di scadenza. /invoicessupporta il filtro per fornitore (dropdown) e la ricerca per numero, data o cliente. La ricerca per data accetta ISO (YYYY-MM-DD) odd.MM.yyyy.- L'elenco fatture include l'ordinamento per stato; l'ordinamento per stato alterna
unpaideissued. /invoices/{invoiceNumber}mostra stato, totali, anteprima HTML salvata e offre un'azione unidirezionale "Segna come pagata" per le fatture non pagate.
- Fornitori: configuri prima i dati del fornitore. Il profilo fornitore guida locale, valuta, numerazione fatture e aliquota fiscale predefinita.
- Modelli: crei un modello per il branding personalizzato e imposti un predefinito. Usi un predefinito globale o uno specifico per fornitore per sovrascrivere la scelta globale.
- Clienti (opzionale): può aggiungere clienti manualmente, ma la generazione fatture crea/aggiorna anche i clienti dai dati inseriti.
- Selezioni il fornitore attivo: scelga un fornitore predefinito nella UI, che imposta un cookie usato durante la creazione delle fatture.
- ID fornitore per API: apra un fornitore in modalità modifica e usi l'ID mostrato nell'angolo in alto a sinistra della pagina.
- Fatture: elenchi, cerchi e filtri le fatture; apra una fattura per rivedere i dettagli e contrassegnare le fatture non pagate come emesse/pagate.
- Generare fattura: inserisca i dati del cliente o cerchi un cliente esistente, aggiunga voci e imposti l'imposta per voce. Se una voce omette l'imposta, si applica l'aliquota predefinita del fornitore.
- Sconti e note: inserisca uno sconto fisso o usi il calcolatore % di sconto; aggiunga note e generi la fattura per vedere la pagina di riepilogo.
La generazione delle fatture usa un lock di scrittura pessimista sul record del fornitore per evitare race condition nel calcolo del prossimo numero fattura. Questo blocca richieste concorrenti per lo stesso fornitore fino all'assegnazione del numero.
Autenticazione richiesta: Tutti gli endpoint API richiedono:
- Bearer token nell'header
Authorization(consigliato per le integrazioni) - Sessione attiva (se è loggato tramite UI web)
Generi una chiave API dalla dashboard amministratore e la includa nell'header Authorization:
curl -H "Authorization: Bearer YOUR_API_KEY_HERE" \
http://localhost:8080/api/v1/invoicesSe è loggato tramite la UI web, la sua sessione viene usata automaticamente per le richieste API.
Generare una chiave API:
- Effettui il login nella UI web
- Navighi a Amministratore (menu utente)
- Scorra alla sezione "Chiavi API"
- Inserisca una descrizione opzionale e clicchi "Genera chiave"
- Copi immediatamente la chiave - non verrà mostrata di nuovo
- La chiave viene mostrata nel formato
Authorization: Bearer {key}
Note sulla sicurezza:
- Le chiavi API sono hashate nel database (BCrypt)
- Le chiavi possono essere revocate in qualsiasi momento dalla dashboard amministratore
- Per ogni chiave è tracciato il timestamp dell'ultimo utilizzo
- Generi chiavi separate per diverse applicazioni/ambienti
POST /api/v1/invoices/generate
Autenticazione richiesta - includa il Bearer token nell'header Authorization.
- Richiede
supplier_ideclient. response_typesupportanumber(predefinito) opdf.number: restituisce JSON solo con metadati della fatturapdf: restituisce il PDF direttamente con metadati negli header di risposta
- Lo stato è sempre
issuedper le fatture generate via API.
Esempio di richiesta (cliente esistente per id):
curl -X POST http://localhost:8080/api/v1/invoices/generate \
-H "Authorization: Bearer YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"response_type": "number",
"supplier_id": 1,
"client": { "id": 42 },
"items": [
{ "description": "Consulting", "quantity": 1, "unit_price": 1000, "tax_rate": 0.2 }
],
"issue_date": "2026-01-16",
"due_date": "2026-01-30",
"currency_code": "EUR",
"notes": "Thank you"
}'Esempio di richiesta (nuovi dati cliente):
curl -X POST http://localhost:8080/api/v1/invoices/generate \
-H "Authorization: Bearer YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"response_type": "number",
"supplier_id": 1,
"client": {
"name": "Client Co",
"addressLine1": "2 Side St",
"city": "Burgas",
"country": "BG",
"taxId": "123",
"vatId": "BG123"
},
"items": [
{ "description": "Consulting", "quantity": 1, "unit_price": 1000, "tax_rate": 0.2 }
]
}'Esempio di risposta (response_type: number):
{
"status": "issued",
"message": "invoice generated",
"invoiceNumber": "INV-000001",
"issueDate": "2026-01-16"
}Esempio di richiesta (response_type: pdf per download diretto del PDF):
curl -X POST http://localhost:8080/api/v1/invoices/generate \
-H "Authorization: Bearer YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"response_type": "pdf",
"supplier_id": 1,
"client": {
"name": "Client Co",
"addressLine1": "2 Side St",
"city": "Plovdiv",
"country": "BG",
"taxId": "123",
"vatId": "BG123"
},
"items": [
{ "description": "Consulting", "quantity": 1, "unit_price": 1000, "tax_rate": 0.2 }
]
}' \
-o invoice.pdf -iEsempio di risposta (response_type: pdf):
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="INV-000001.pdf"
X-Invoice-Number: INV-000001
X-Invoice-Status: issued
X-Invoice-Issue-Date: 2026-01-16
[PDF binary data]
La risposta PDF include i metadati della fattura negli header di risposta personalizzati (X-Invoice-Number, X-Invoice-Status, X-Invoice-Issue-Date), consentendo alla sua applicazione di salvare i dettagli della fattura mentre riceve il PDF direttamente.
GET /api/v1/invoices
Autenticazione richiesta - includa il Bearer token nell'header Authorization.
- Filtro opzionale:
status=unpaidostatus=issued
Esempio di richiesta:
curl -H "Authorization: Bearer YOUR_API_KEY_HERE" \
http://localhost:8080/api/v1/invoices?status=unpaidEsempio di risposta (filtrato):
[
{ "invoiceNumber": "INV-000002", "status": "unpaid" }
]Autenticazione richiesta - includa il Bearer token nell'header Authorization.
Recupero metadati fattura:
curl -H "Authorization: Bearer YOUR_API_KEY_HERE" \
http://localhost:8080/api/v1/invoices/INV-000001Download PDF fattura:
curl -H "Authorization: Bearer YOUR_API_KEY_HERE" \
http://localhost:8080/api/v1/invoices/INV-000001/pdf \
-o invoice.pdfAutenticazione richiesta - includa il Bearer token nell'header Authorization.
GET /api/v1/parties/client?taxId=...&vatId=...(richiede uno tra taxId/vatId)GET /api/v1/parties/clients/search?q=...(minimo 2 caratteri)GET /api/v1/parties/suppliers
Esempio:
curl -H "Authorization: Bearer YOUR_API_KEY_HERE" \
http://localhost:8080/api/v1/parties/suppliersGET /api/v1/health(nessuna autenticazione richiesta)
- I modelli si trovano in
invoice_templatese devono includere contenuto HTML. - La generazione delle fatture richiede un modello predefinito effettivo (specifico per fornitore o globale).
- I fornitori possono sovrascrivere il predefinito globale con un modello specifico.
- Le fatture generate memorizzano uno snapshot HTML per un re-render coerente.
- I PDF vengono renderizzati dallo snapshot HTML salvato quando disponibile.
I modelli devono essere in formato XHTML per un rendering PDF corretto:
- Includere la dichiarazione XML:
<?xml version="1.0" encoding="UTF-8"?> - Usare il namespace XHTML:
<html xmlns="http://www.w3.org/1999/xhtml"> - Tutto il CSS deve essere inline dentro un tag
<style>nella sezione<head> - I fogli di stile esterni non sono supportati per la generazione PDF
Sono disponibili modelli di esempio nella directory templates/ in 6 lingue (EN, BG, IT, ES, DE, RU).
I modelli usano variabili {{placeholder}}. Se un placeholder è omesso dal modello, quei dati non verranno renderizzati nella fattura finale. Il servizio non valida quali placeholder siano presenti o mancanti.
Placeholder supportati:
{{invoiceNumber}}{{issueDate}}{{dueDateRow}}(riga<div>completa o vuota){{supplierName}}{{supplierAddressLine1}}{{supplierAddressLine2Row}}(riga<div>completa o vuota){{supplierCityRegionPostal}}{{supplierCountry}}{{supplierTaxIdRow}}(riga<div>completa o vuota){{supplierVatIdRow}}(riga<div>completa o vuota){{supplierEmailRow}}(riga<div>completa o vuota){{supplierPhoneRow}}(riga<div>completa o vuota){{clientName}}{{clientAddressLine1}}{{clientAddressLine2Row}}(riga<div>completa o vuota){{clientCityRegionPostal}}{{clientCountry}}{{clientTaxIdRow}}(riga<div>completa o vuota){{clientVatIdRow}}(riga<div>completa o vuota){{clientEmailRow}}(riga<div>completa o vuota){{clientPhoneRow}}(riga<div>completa o vuota){{itemsRows}}(righe<tr>renderizzate){{subtotal}}{{discountTotal}}{{taxTotal}}{{total}}{{notesSection}}(sezione<div>completa o vuota)
I PDF sono renderizzati con OpenHTMLToPDF. L'applicazione include la famiglia di font DejaVu, che supporta latino, cirillico, greco e altri caratteri Unicode.
Usare i font inclusi:
body {
font-family: "DejaVu Sans", sans-serif;
}Usare font web personalizzati:
I modelli possono caricare font esterni tramite @font-face nella sezione <style> inline. Si assicuri che il font web supporti la lingua del modello (es. cirillico per russo/bulgaro, greco, ecc.). I font DejaVu inclusi fungono da fallback se il font web non si carica.
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: url('https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Me5WZLCzYlKw.ttf') format('truetype');
}
body {
font-family: 'Roboto', 'DejaVu Sans', sans-serif;
}Font inclusi disponibili:
| Font Family | Weights | Styles |
|---|---|---|
DejaVu Sans |
200 (extra-light), 400 (normal), 700 (bold) | normal, oblique |
DejaVu Sans Condensed |
400 (normal), 700 (bold) | normal, oblique |
DejaVu Sans Mono |
400 (normal), 700 (bold) | normal, oblique |
DejaVu Serif |
400 (normal), 700 (bold) | normal, italic |
DejaVu Serif Condensed |
400 (normal), 700 (bold) | normal, italic |
- Fornitori e clienti condividono la tabella
partiese sono distinti darole. - Il soft delete nasconde le parti dagli elenchi preservando la cronologia delle fatture.
- Le impostazioni del fornitore possono sovrascrivere locale, valuta, formato data, prefisso fattura e padding delle cifre.
default_tax_ratedel fornitore si applica alle voci che omettono l'aliquota.
- I numeri di fattura sono per fornitore e usano
max(invoice_number_int) + 1. - Il prefisso opzionale e il padding delle cifre sono applicati dalle impostazioni del fornitore.
- I codici valuta sono validati contro ISO 4217.
È incluso uno script per stress test dell'API di generazione fatture con richieste concorrenti.
Uso:
API_KEY=your_api_key ./integration-tests/gen-test.sh [SUPPLIER_ID] [COUNT] [BASE_URL]Oppure passi la chiave API come quarto argomento:
./integration-tests/gen-test.sh [SUPPLIER_ID] [COUNT] [BASE_URL] [API_KEY]Parametri:
SUPPLIER_ID- ID fornitore per fatture di test (predefinito: 1)COUNT- numero di richieste concorrenti da generare (predefinito: 20)BASE_URL- URL base dell'applicazione (predefinito: http://localhost:8080)API_KEY- la sua chiave API (richiesta, può essere impostata come variabile d'ambiente)
Esempio:
API_KEY=abc123-your-key ./integration-tests/gen-test.sh 1 50 http://localhost:8080Questo invia richieste concorrenti di generazione fatture per testare il lock pessimista e le prestazioni complessive dell'API sotto carico.
La UI usa Tailwind CSS, che deve essere ricostruito quando vengono apportate modifiche al CSS.
-
Scarichi il binario standalone di Tailwind CSS da GitHub releases
-
Inserisca il binario nella directory
twbin/(es.twbin/tailwindcss-linux-x64) -
Esegua lo script di build:
./build-tailwind.sh
Questo ricostruisce nullInvoice/src/main/resources/static/css/tailwind.css dal file sorgente tailwind-src.css.
Per sviluppo rapido senza rebuild, decommenti lo script CDN in nullInvoice/src/main/resources/templates/fragments/head.html:
<script src="https://cdn.tailwindcss.com"></script>Ricordi di ricostruire Tailwind CSS prima del deploy in produzione.
nullInvoice/src/main/java- codice applicativonullInvoice/src/main/resources/templates- modelli UI (Thymeleaf)nullInvoice/src/main/resources/static- asset JS/CSSnullInvoice/src/main/resources/db/migration- migrazioni Flywaytemplates/- modelli di fattura di esempio in 6 lingue (EN, BG, IT, ES, DE, RU)integration-tests/- script di test di carico per la generazione fatturebuild-tailwind.sh- script di comodo per buildare Tailwind CSStwbin/- binario standalone di Tailwind CSS (scaricare separatamente)
Documentazione API interattiva:
- Specifica OpenAPI JSON:
/openapi - Swagger UI:
/swagger
Accesso alla Swagger UI:
- Effettui il login nella UI web
- Clicchi sul menu utente > "Documentazione API"
- Oppure navighi direttamente su
/swagger(richiede login)
Testare gli endpoint in Swagger:
- Clicchi il pulsante "Authorize" (icona lucchetto) in alto a destra
- Inserisca la sua chiave API (generata da Amministratore > Chiavi API, se necessario)
- Clicchi "Authorize"
- Tutte le richieste includeranno automaticamente il Bearer token
- Usi "Try it out" per testare gli endpoint in modo interattivo
Nota: Swagger UI richiede autenticazione ed è disponibile solo per amministratori loggati.
Lingue UI supportate: L'applicazione è completamente internazionalizzata con message bundle:
- Inglese (EN) ✅
- Bulgaro (BG) ✅
- Tedesco (DE) ✅
- Spagnolo (ES) ✅
- Italiano (IT) ✅
- Russo (RU) ✅
Traduzioni README: Questo README.md è disponibile anche in:
Traduzione automatica fornita da Google Gemini.
Modelli di fattura: Modelli di esempio inclusi per tutte le 6 lingue sopra (nella directory templates/)
Supporto tecnico per lingue aggiuntive: L'applicazione può generare fatture in qualsiasi lingua con un adeguato supporto di font:
- Arabo (EAU, Arabia Saudita, ecc.) - supporto RTL tramite CSS, servono modelli e traduzioni UI
- Asia orientale (cinese, giapponese, coreano) - font Unicode supportati, servono modelli e traduzioni UI
- Ebraico - supporto RTL tramite CSS, servono modelli e traduzioni UI
- Qualsiasi altra lingua basata su Unicode
Accogliamo contributi per:
- 🌍 Traduzioni UI (
messages_{lang}.propertiesinnullInvoice/src/main/resources/) - 📄 Modelli di fattura di esempio per la sua lingua/regione (
templates/{lang}/) - 🎨 Raccomandazioni di font per un rendering PDF ottimale nella sua lingua
- 📝 Miglioramenti e traduzioni della documentazione
La famiglia di font DejaVu inclusa supporta ampia copertura Unicode. Per lingue che richiedono font specifici, usi @font-face nei modelli di fattura per caricare webfont con fallback a DejaVu.
Questo progetto è rilasciato sotto Elastic License 2.0 - veda il file LICENSE per i dettagli.
Copyright 2026 nullata
- Font Awesome Free:
nullInvoice/src/main/resources/static/fontawesome-free-7.1.0-web/LICENSE.txt - DejaVu Fonts:
nullInvoice/src/main/resources/fonts/LICENSE.txt