Import XML — Riferimento tecnico
Questa pagina è il complemento avanzato a Import XML FatturaPA. Qui trovi i dettagli implementativi rilevanti per integrazioni, automazione e debug. La guida utente è quella linkata sopra.
Tipi documento supportati
Sezione intitolata “Tipi documento supportati”XIQUIL accetta tutti i TipoDocumento previsti dallo schema FatturaPA v1.2.2.
La tabella elenca i codici più frequenti e il trattamento applicato:
| Codice | Descrizione | Comportamento XIQUIL |
|---|---|---|
TD01 | Fattura | Standard. ImportoTotaleDocumento opzionale, fallback sulla somma righe. |
TD02 | Acconto/Anticipo su fattura | Standard. |
TD03 | Acconto/Anticipo su parcella | Standard. |
TD04 | Nota di credito | Segno negativo applicato automaticamente a imponibile, IVA, sconto e totale (header e voci). Quantità e prezzo unitario delle voci restano positivi. |
TD05 | Nota di debito | Standard, segno positivo. |
TD06 | Parcella | Standard. Tipico per fatture professionisti. |
TD16–TD27 | Reverse charge / autofattura / integrazione | Standard. Il regime IVA (es. N6.x per inversione contabile) viene letto dal DatiRiepilogo e replicato sulle voci. |
Direzione: Uscita vs Entrata
Sezione intitolata “Direzione: Uscita vs Entrata”Determinata da services/import_documento_service.py::detect_xml_direction():
- Confronta
cessionario.p_ivacon i Soggetti dell’utente → match → Uscita (l’utente è il compratore) - Confronta
cedente.p_ivacon i Soggetti → match → Entrata (l’utente è il venditore) - Entrambi match o nessun match → ambiguous, l’utente sceglie nel dialog
La direzione viene propagata nel payload ImportConfirmData.direzione
('uscita' | 'entrata') e seleziona la branch backend
(_create_uscita_from_xml_preview vs _create_entrata_from_xml_preview).
Autorità dei totali FatturaPA
Sezione intitolata “Autorità dei totali FatturaPA”Per una fattura importata, ImportoTotaleDocumento e gli aggregati di
DatiRiepilogo restano autorevoli. La modifica successiva di una riga non
normalizza totale, imponibile o iva dell’owner: il frontend calcola e
mostra invece gli scarti rispetto alle righe come diagnostica non contabile.
Categoria e focus continuano a essere salvati sulle righe e restano modificabili, perché sono classificazioni XIQUIL e non campi fiscali autoritativi dell’XML.
Risoluzione della controparte
Sezione intitolata “Risoluzione della controparte”L’upload prova ad associare cedente o cessionario a una anagrafica esistente
tramite identità fiscale. Se non trova un match ma il preview contiene una
identità utilizzabile, la revisione precompila un controparte_draft e seleziona
l’opzione sintetica di creazione alla conferma. La selezione di un’anagrafica
esistente elimina invece il draft.
Nessuna controparte viene creata durante la raccolta dei dati. Alla conferma
atomica, _resolve_atomic_counterparty usa l’ID scelto oppure crea
l’anagrafica dal preview XML autorevole, includendo i fallback fiscali esteri,
nella stessa transazione del documento e degli allegati.
Duplicati: upload e preflight di fattura
Sezione intitolata “Duplicati: upload e preflight di fattura”XIQUIL applica due controlli complementari:
- All’upload XML, SHA-256 del contenuto e chiave fiscale intercettano i re-upload dello stesso file o dello stesso corpo FatturaPA. Gli import scartati o in errore restano esclusi per consentire il recupero.
- Prima della mutazione, il preflight confronta una identità canonica e indipendente dal formato: numero documento, identità fiscali di cedente e cessionario, data, totale e valuta. I candidati possono essere import in coda, Uscite o Entrate già confermate.
Il confronto produce un punteggio spiegabile e distingue campi coincidenti,
diversi e mancanti. I livelli full, strong e suspect generano un conflitto
HTTP 409 con le azioni eseguibili; un match weak non blocca il salvataggio.
La decisione include identità e revisioni del match, così una situazione
cambiata deve essere valutata di nuovo prima di scrivere.
I percorsi manuali espongono create_separate; la UI offre anche la navigazione
al documento esistente. La decisione viene registrata e quella stessa coppia è
esclusa dai controlli sulle modifiche successive. In revisione import sono
disponibili anche merge_into_staging e merge_attach: foto, PDF e XML della
stessa fattura convergono così sul medesimo owner e ogni sorgente viene
conservata come allegato.
Response di upload:
{ imported: ImportDocumentoSummary[]; duplicates: DuplicateInfo[]; // { filename, reason: 'pending'|'confirmed', existing_codice, existing_data, existing_numero } errors: { filename, error_message }[]; files_received: number;}DatiPagamento: parser e CTA scadenze
Sezione intitolata “DatiPagamento: parser e CTA scadenze”Il parser legge tutta la struttura DatiPagamento (FePagamento + FeDettaglioPagamento)
e la espone nel preview JSON come array pagamenti:
{ "pagamenti": [ { "condizioni_pagamento": "TP01", "dettagli": [ { "modalita_pagamento": "MP05", "data_scadenza_pagamento": "2026-06-30", "importo_pagamento": 1220.00, "iban": "IT60X0542811101000000123456", "istituto_finanziario": "Unicredit" } ] } ]}Il dialog di revisione mostra la card Suggerimento dalla fattura con:
- Codici condizioni pagamento (TP01–TP03) e modalità (MP01–MP23) decodificati in italiano
- Tabella riepilogativa righe (modalità, IBAN, importo, scadenza)
- Bottone CTA “Crea scadenze in attesa”. Il bottone:
- È disabilitato finché non è selezionato l’ambito
- Salta righe senza data o con importo ≤ 0
- Sostituisce il draft locale con una scadenza per ogni riga valida, rinumerata da 1
- L’IBAN della riga viene messo nelle note della scadenza
- Salva documento, scadenze e allegati insieme alla conferma atomica
Niente auto-creazione silenziosa: la scelta di applicare i DatiPagamento è sempre esplicita dell’utente.
Persistenza JSON-safe del preview
Sezione intitolata “Persistenza JSON-safe del preview”Il parser XML può produrre valori Python come Decimal, date e datetime.
Prima di salvare il preview in ImportDocumento.dati_preview JSONB, XIQUIL
normalizza ricorsivamente il payload in tipi JSON-safe: numeri, stringhe ISO,
liste e oggetti plain.
Questa normalizzazione vale solo al confine di persistenza/API: la logica di parsing e calcolo può continuare a usare tipi precisi finché non deve scrivere JSONB o restituire payload serializzati.
DatiBollo: persistenza
Sezione intitolata “DatiBollo: persistenza”Il parser legge entrambi:
DatiGenerali/DatiBollo/BolloVirtuale(boolean: SI/NO)DatiGenerali/DatiBollo/ImportoBollo(decimal)
L’importo viene salvato nel campo bollo di Uscita o Entrata (esistente già
in entrambi i model, NUMERIC(12,2) nullable). Il valore non diventa una
riga IVA: la marca da bollo è classificata contabilmente come voce B14 (oneri
diversi di gestione), non come imposta sul valore aggiunto.
Su TD04 il bollo resta positivo: il credit non rimborsa la marca già pagata.
Rate limit: server-side e protezione client
Sezione intitolata “Rate limit: server-side e protezione client”Il backend impone rate limit configurabile (default 10 req/min per
endpoint upload, slowapi in-memory). Quando viene superato, gli endpoint
ritornano HTTP 429 con header Retry-After.
Il frontend ha doppia protezione per gestire batch reali fino a 200-300 file:
-
Interceptor 429 in
api/client.ts: backoff esponenziale automatico, max 5 tentativi (1s/2s/4s/8s/16s). Se l’headerRetry-Afterè presente, viene preferito alla schedule. Esauriti i tentativi, rilancia un errore con messaggio italiano user-facing. -
Chunking in
uploadXmlFilesBulk/uploadDocumentFilesBulk: per batch >10 file, spezza in chunk di 10 e processa 2 chunk in parallelo. I risultati vengono accumulati in un singoloImportUploadResult. Una callbackonProgressaggiorna la UI con{done, total, inFlight}.
La combinazione chunking + retry idempotente (XML-DEDUP-01: re-upload produce DuplicateInfo, mai duplicati) rende l’import bulk affidabile anche sotto carico.
API endpoints
Sezione intitolata “API endpoints”Tutti sotto /api/import (auth richiesta, feature import con livello ≥
SOLA_LETTURA per GET, ≥ PERSONALE per POST).
| Endpoint | Body | Risposta |
|---|---|---|
POST /upload | multipart files[].xml | ImportUploadResult |
POST /upload-file | multipart files[] (img/pdf) | ImportUploadResult |
GET /pending/review-items | — | ImportReviewItem[] |
GET /pending/count | — | { count: number } |
GET /{id} | — | ImportDocumentoRead (include dati_preview JSON) |
POST /{id}/confirm-atomic | ImportGroupAtomicConfirmData | documento creato e import confermato |
POST /groups/{group_id}/confirm-atomic | ImportGroupAtomicConfirmData | documento e PDF multi-pagina creati |
POST /{id}/reconcile | ImportReconciliationRequest | esito unione/allegato |
POST /{id}/confirm-link-existing | ImportLinkExistingData | allegato collegato all’owner |
DELETE /{id} | — | 204 |
DELETE /pending | query ids opzionale | conteggio import scartati |
Gli endpoint confirm-atomic sono il percorso primario della revisione: owner,
satellite, righe, scadenze draft, allegati e stato import vengono confermati
nella stessa transazione. Il 409 di preflight va risolto tramite la decisione
proposta e, per le azioni di unione, tramite /{id}/reconcile.
Schema parsato
Sezione intitolata “Schema parsato”Il file dati_preview è un JSON con questa shape (campi rilevanti):
{ header: { formato_trasmissione, codice_destinatario, pec_destinatario }, cedente: { denominazione, p_iva, cf, indirizzo, ... }, cessionario: { denominazione, p_iva, cf, indirizzo, ... }, // solo se presente dati_generali: { tipo_documento: string, numero: string, data: string, valuta: string, importo_totale_documento?: number, arrotondamento?: number, bollo_virtuale: boolean, importo_bollo?: number, art73: boolean, }, causali: string[], ritenute: [...], casse_previdenziali: [...], sconti_maggiorazioni: [...], linee: [ { numero_linea, descrizione, quantita, prezzo_unitario, imponibile, iva, totale, aliquota_iva, natura?, ... } ], riepilogo_iva: [...], pagamenti: [{ condizioni_pagamento, dettagli: [...] }], totale_status?: { severity, dichiarato, calcolato, differenza, arrotondamento_dichiarato }, proposed_fornitore: { ... }, // pre-built al momento dell'upload (path Uscita)}Vedi anche
Sezione intitolata “Vedi anche”- Import XML FatturaPA — guida utente
- API Reference — autenticazione, schemi, error model