Vai al contenuto

API Fatture — Specifica Tecnica

Panoramica

API REST per la sincronizzazione di metadati delle fatture e per l'archiviazione/lettura degli allegati (PDF e XML elettronici) verso/da Areagate. La testata fattura risiede in ARPFATTU; gli allegati vengono archiviati su S3 e indicizzati in APCOGARIDX.

Endpoint disponibili

Metodo Path Descrizione
GET /v1/fattura Lettura fatture (paginazione)
GET /v1/fattura/up Lettura fatture aggiornate a partire da un sync id
POST /v1/fattura Inserimento/aggiornamento/cancellazione batch fatture (metadati)
GET /v1/fattura/:codice_fattura/xml Scarica l'XML della fattura elettronica
POST /v1/fattura/allegato Upload di un singolo allegato (PDF o XML)

Nota: il POST /allegato e' implementato senza schema Fastify (multipart/form-data) e per questo motivo non risulta attualmente documentato in Swagger. Il contratto e' descritto nella sezione dedicata.


Schema output — GET

FatturaOutput

Campo Tipo Campo DB / Join Note
codice_fattura string trim(a_fat_fattura) Chiave completa fattura (max 20 char, puo' contenere /)
codice_cliente string trim(a_fat_anagrafica) Codice anagrafica interno (area)
codice_host_cliente string join ARPANAGR (rana_codice_host) Codice cliente nel sistema host esterno
tipo string trim(a_fat_tip) Tipo fattura (max 2 char)
anno integer a_fat_ann Anno fattura (4 cifre)
numero integer a_fat_num Numero fattura (max 7 cifre)
data integer a_fat_data (convertito in epoch ms) Data fattura in formato epoch ms
imponibile number a_fat_imponibile Imponibile
iva number a_fat_iva IVA
totale number a_fat_totale Totale
cancellato boolean a_fat_val = 'C' true se la fattura e' cancellata logicamente
sync integer a_fat_id_sincro ID di sincronizzazione

Query string — GET /

Parametro Tipo Obbligatorio Note
limit integer NO Max risultati (default/max: 1000)
page integer NO Pagina (paginazione offset-based)

Il GET / esclude le fatture cancellate (a_fat_val <> 'C').

Query string — GET /up

Parametro Tipo Obbligatorio Note
sync integer SI ID sincronizzazione di partenza

Il GET /up include anche le fatture cancellate (restituite con cancellato = true) e ordina per a_fat_id_sincro crescente.


Schema input — POST /v1/fattura

Il body e' un array di oggetti FatturaInput (max 1000 elementi).

FatturaInput

Campo Tipo Obbligatorio Note
codice_fattura string SI Chiave univoca fattura (max 20 char) — usata per deduplicazione
codice_host_cliente string SI Codice host cliente (max 16 char), risolto via raccordi clienti
tipo string NO Tipo fattura (max 2 char, default "")
anno integer NO Anno fattura (1-9999, default 1)
numero integer NO Numero fattura (+/-7 cifre, default 0)
data integer NO Data fattura in epoch ms (default 0 -> data 0001-01-01)
imponibile number NO Imponibile (default 0)
iva number NO IVA (default 0)
totale number NO Totale (default 0)
cancellato boolean NO Cancellazione logica (default false)

Logica POST

  • Deduplicazione payload: non sono ammessi codice_fattura duplicati nello stesso array (checkDuplicati).
  • Validazione: ogni codice_host_cliente deve risolvere in ARPANAGR. Se non risolvibile -> 400 body/{i}/codice_host_cliente (...) mancante.
  • Categorie di operazioni calcolate confrontando payload con record esistente:
    • Inserimento: record non esistente e non flaggato come cancellato
    • Cancellazione: record esistente non cancellato + payload cancellato=true
    • Modifica: record esistente con almeno un campo cambiato (cliente, tipo, anno, numero, data, imponibile, iva, totale). La modifica rimuove la flag di cancellazione (a_fat_val = '')
    • Skip: record gia' cancellato e payload cancellato=true; record non esistente e payload cancellato=true
  • id_sincro: assegnato progressivamente da getNextIdSincro(sql, id_azi, "ARPFATTU", n) per tutte le operazioni di scrittura in questa chiamata.

GET /v1/fattura/:codice_fattura/xml

Scarica l'XML della fattura elettronica. L'XML e' stato archiviato su S3 tramite il processo gestionale (sottoprogramma COGU06), in cbl/cogu06.cbl caso k-arcott-classe-fatture-clienti / k-arcott-classe-fatture-fornitori.

Path param

Parametro Note
codice_fattura Stesso formato restituito da GET /v1/fattura (con slash). Il client URL-encoda gli slash come %2F. Fastify decodifica il parametro in trasparenza.

Response body (200)

Campo Tipo Note
nome_originale string Nome originale del file caricato (a_arx_nome_originale)
nome_memorizzato string Nome memorizzato su S3 (a_arx_nome_memorizzato)
contenuto string Contenuto XML codificato in base64

Logica

  1. Lookup in ARPFATTU: trim(a_fat_fattura) = codice_fattura + a_fat_val <> 'C'. 404 se non trovata.
  2. Lookup in APCOGARIDX:

    • a_arx_doc_classe IN ('FC', 'FF') (include sia fatture clienti sia fornitori)
    • replace(trim(a_arx_key_oggetto_gest), '/', '') = codice_fattura_senza_slash — il match normalizza gli slash su entrambi i lati perche' la chiave in APCOGARIDX puo' essere con slash (se archiviato dal POST /allegato di questa API) o senza slash (se archiviato dal processo gestionale swn013)
    • a_arx_nome_memorizzato ILIKE '%.xml'
    • a_arx_fl_canc <> 'C'

    404 se XML non trovato. 3. Fetch credenziali AWS (getAwsCredentials(db, id_azi)). 4. Download da S3, Bucket dalle credenziali, Key fatture/{nome_memorizzato}. 5. Encoding contenuto in base64.


POST /v1/fattura/allegato

Upload di un singolo file allegato a una fattura. Accetta sia PDF sia XML, a seconda del campo ext_file. Il file viene archiviato su S3 nella cartella fatture/ e registrato in APCOGARIDX.

Nota: questo endpoint e' implementato senza schema Fastify, quindi non appare in Swagger. La validazione dei campi avviene via zod sul req.fields del multipart.

Request

  • Content-Type: multipart/form-data
  • Campi (tutti in form-data):
    • file: il file binario (PDF o XML) — limite 1 file per richiesta
    • codice_host_cliente (string, SI): codice cliente nel sistema host esterno
    • codice_fattura (string, SI): chiave fattura (max 20 char, puo' contenere /)
    • data (integer, SI): data fattura in epoch ms
    • ext_file (string, NO): estensione del file (default "pdf", es. "xml" per upload XML)

Logica

  1. Verifica presenza del file (req.file({ limits: { files: 1 } })).
  2. Parse via zod dei campi multipart. Errore -> 400 Wrong data provided.
  3. Validazione codice_host_cliente via raccordi clienti (getRaccordiClienti).
  4. Costruzione nome_memorizzato = codice_fattura.replaceAll("/", "").
  5. Upload su S3:
    • Bucket: da credenziali AWS dell'azienda
    • Key: fatture/{nome_memorizzato}.{ext_file}
    • ContentType: dal multipart
    • StorageClass: STANDARD_IA
  6. Insert in APCOGARIDX:
    • a_arx_progressivo: progressivo tramite numericCodeGenerator(12, MAX(a_arx_progressivo))
    • a_arx_doc_classe: "FC" (fisso — anche per fatture fornitori)
    • a_arx_ana_tip / a_arx_ana_cod: derivati da cliente[0] / cliente.slice(1) (dal raccordo)
    • a_arx_key_oggetto_gest: codice_fattura originale (con slash)
    • a_arx_prog_documento: 1
    • a_arx_data_esterno: data dal payload
    • a_arx_nome_originale: filename originale del multipart
    • a_arx_nome_memorizzato: {nome_memorizzato}.{ext_file}
    • a_arx_id_sincro: da getNextIdSincro(sql, id_azi, "APCOGARIDX", 1)

Response

  • 200 OK: { "message": "OK" }
  • 400 Bad Request: "No file provided" / "Wrong data provided" / errori di validazione
  • 500 Internal Server Error: problemi di accesso credenziali S3

Tabelle sorgente

ARPFATTU — testata fatture

PK: (a_fat_azienda, a_fat_fattura). Il campo a_fat_fattura e' char(20) e contiene la chiave completa della fattura (puo' includere /).

Campo Tipo Note
a_fat_azienda char(6) Codice azienda
a_fat_fattura char(20) Chiave completa fattura
a_fat_tip char(2) Tipo fattura
a_fat_ann num(4) Anno
a_fat_num num(7) Numero
a_fat_data date Data fattura
a_fat_imponibile num(12,6) Imponibile
a_fat_iva num(12,6) IVA
a_fat_totale num(12,6) Totale
a_fat_anagrafica char(6) Codice anagrafica (area)
a_fat_val char(1) 'C' se cancellato
a_fat_id_sincro num(15) ID sincronizzazione

APCOGARIDX — indice archivio documentale

Usata per la registrazione degli allegati (sia PDF sia XML) e dei loro metadati.

Campo Note
a_arx_doc_classe "FC" = Fatture clienti, "FF" = Fatture fornitori
a_arx_key_oggetto_gest codice_fattura — puo' essere con slash (POST /allegato API) o senza slash (processo gestionale swn013)
a_arx_nome_originale Filename originale
a_arx_nome_memorizzato Filename memorizzato su S3 (con estensione). POST /allegato API: slash rimossi (es. CL20260000123.pdf). swn013 per XML: slash sostituiti con _ (es. CL_2026_0000123.xml)
a_arx_fl_canc 'C' se cancellato

Storage S3

Le fatture vengono archiviate in una cartella piatta fatture/ (vedi cogu06.cbl:4718-4733):

Key = fatture/{a_arx_nome_memorizzato}

Il nome_memorizzato include l'estensione (.pdf o .xml) ed e' stato generato rimuovendo gli slash dal codice_fattura originale. Le credenziali del bucket vengono recuperate via getAwsCredentials(db, id_azi).


Limiti

Vincolo Valore
Max fatture per risposta GET 1000
Max fatture per body POST 1000
Max allegati per richiesta POST 1
Max size codice_fattura 20 char
Max size codice_host_cliente 16 char

Note implementative

  • Tutte le operazioni POST sono eseguite in una singola transazione (db.begin)
  • Le date in output (data in FatturaOutput) sono convertite da YYYY-MM-DD a epoch ms tramite isoDateToInteger (memoizzato)
  • Le date in input (data in FatturaInput) vengono convertite da epoch ms a YYYY-MM-DD tramite integerToDate (memoizzato); valore 0 -> "0001-01-01"
  • I campi tecnici (a_fat_di_*, a_fat_da_*) sono valorizzati automaticamente con data/ora odierne e costanti WS_OPE / WS_PROG