Vai al contenuto

Creare ed emettere un documento

Questa guida crea una fattura di vendita con due righe e la emette. Lo stesso flusso vale per gli altri documenti (DDT, note di credito, ordini, preventivi); cambia il TipoDocumento e, per alcuni tipi, l'emissione non è prevista.

In Amica un documento nasce in bozza: finché non è emesso puoi modificarlo liberamente. L'emissione lo rende definitivo e ne produce gli effetti: scritture contabili, scadenze, movimenti di magazzino.

Il flusso completo:

  1. Prepara i riferimenti: cliente, pagamento, causale IVA.
  2. Chiedi una nuova istanza del documento.
  3. Calcola le righe.
  4. Calcola i totali del documento.
  5. Salva la bozza.
  6. Emetti il documento.

Il server non ricalcola importi e totali

Al salvataggio l'API memorizza gli importi così come li ricevi: non ricalcola l'importo delle righe né i totali del documento. Per questo i passi 3 e 4 sono indispensabili. Un documento salvato con i totali a zero viene emesso con scritture contabili e scadenze a zero.

Negli esempi l'azienda è la 1 e le risposte sono abbreviate ai campi rilevanti, senza i metadati $id e $ref che l'API aggiunge agli oggetti (le liste arrivano come {"$id": "1", "$values": [...]}). Gli importi sono quelli di un'esecuzione reale. Servono gli scope read e write e, per le risorse coinvolte, documenti (documenti), comune (anagrafiche), contabilita (pagamenti e causali IVA) e magazzino (calcolo delle righe).

Percentuali e aliquote

In tutta l'API sconti, aliquote e percentuali sono frazioni: un'aliquota del 22% è 0.22, uno sconto del 10% è 0.10, una ritenuta del 20% è 0.20.

1. Prepara anagrafica, pagamento e IVA

Un documento fa riferimento ad altre risorse tramite il loro id. Per una fattura di vendita servono almeno:

Campo Risorsa Note
anagraficaId anagrafica Il cliente. Obbligatorio.
pagamentoId pagamento Obbligatorio per emettere un documento di vendita.
causaleIvaId (su ogni riga) causaleiva Determina l'aliquota della riga.

Cercali con i normali filtri, per esempio:

curl -G 'https://{host}/api/v3/1/anagrafica' \
    --data-urlencode 'Filter=RagioneSociale1 $ct rossi' \
    -H 'Authorization: Bearer <token>'

curl -G 'https://{host}/api/v3/1/causaleiva' \
    --data-urlencode 'Filter=Codice $eq 22' \
    -H 'Authorization: Bearer <token>'

2. Chiedi una nuova istanza

Non costruire il documento da zero: chiedi all'API una nuova istanza del tipo che ti serve, con TipoDocumento (per una fattura immediata FatturaAccompagnatoria).

curl 'https://{host}/api/v3/1/documento/new?TipoDocumento=FatturaAccompagnatoria' \
    -H 'Authorization: Bearer <token>'
{
  "tipoDocumento": "FatturaAccompagnatoria",
  "classeDocumento": "Vendita",
  "stato": "Bozza",
  "data": "2026-10-07T08:24:08.8038146+00:00",
  "numeroParteNumerica": 26,
  "numero": "26",
  "ivaEsclusa": true,
  "valutaId": 1,
  "cambio": 1.0,
  "id": 0
}

L'istanza arriva con il numero successivo della numerazione, la data odierna, lo stato Bozza e le impostazioni dell'azienda, come ivaEsclusa (prezzi al netto dell'IVA). Non viene salvata: è solo il punto di partenza.

Numerazione

Il numero è quello libero al momento della richiesta. Se nel frattempo un altro utente salva un documento con lo stesso numero, il tuo salvataggio riceve un 400 ("Numero documento già esistente"): chiedi una nuova istanza e riprova.

3. Calcola le righe

Ogni riga (BeneServizio) ha bisogno di descrizione, quantità, prezzo, causaleIvaId e dei valori calcolati prezzoScontato e importo. Per ottenerli usa POST beneservizio/compute, che applica sconti e IVA con le regole e gli arrotondamenti dell'azienda:

curl -X POST 'https://{host}/api/v3/1/beneservizio/compute' \
    -H 'Authorization: Bearer <token>' \
    -H 'Content-Type: application/json' \
    --data '{"ivaEsclusa": true, "causaleIvaId": 3, "quantità": 10, "prezzo": 125.00, "sconto1": 0.10}'
{ "prezzo": 125.00, "prezzoIvato": 152.50, "prezzoScontato": 112.50, "importo": 1125.00 }

Passa lo stesso ivaEsclusa del documento. Con ivaEsclusa: false indichi invece il prezzoIvato e il calcolo scorpora l'IVA. Ripeti per ogni riga e riporta i risultati nella riga:

{
  "descrizione": "Consulenza sistemistica",
  "quantità": 10,
  "prezzo": 125.00,
  "sconto1": 0.10,
  "prezzoScontato": 112.50,
  "importo": 1125.00,
  "causaleIvaId": 3
}

Per vendere un articolo di magazzino aggiungi articoloId, codice e magazzinoId: quando la riga ha un codice, il magazzino è obbligatorio.

4. Calcola i totali

Con le righe pronte, POST documento/compute calcola i totali del documento e i riepiloghi IVA. Gli bastano importo, causale IVA e ritenuta di ogni riga, più gli eventuali sconti di testata:

curl -X POST 'https://{host}/api/v3/1/documento/compute' \
    -H 'Authorization: Bearer <token>' \
    -H 'Content-Type: application/json' \
    --data '{
      "righe": [
        {"importo": 1125.00, "causaleIvaId": 3},
        {"importo": 300.00, "causaleIvaId": 3}
      ]
    }'
{
  "totaleMerce": 1425.00,
  "totaleMerceScontata": 1425.00,
  "totaleImponibile": 1425.00,
  "totaleImposta": 313.50,
  "totaleDocumento": 1738.50,
  "nettoAPagare": 1738.50,
  "riepiloghiIva": [
    {
      "causaleIvaId": 3, "causaleIvaCodice": "22", "aliquota": 0.22,
      "imponibileLordo": 1425.00, "imponibile": 1425.00, "imposta": 313.50
    }
  ]
}

Riporta i risultati nel documento:

  • i totali nei campi con lo stesso nome (totaleMerce, totaleImponibile, totaleImposta, totaleDocumento, nettoAPagare, …);
  • i riepiloghi IVA, nell'ordine in cui arrivano, negli slot da 1 a 4: iva1CausaleIvaId, iva1ImponibileLordo, iva1Imponibile, iva1Imposta per il primo, iva2… per il secondo e così via.

Un documento può avere al massimo quattro causali IVA diverse: oltre, il calcolo risponde 400. Ricalcola righe e totali a ogni modifica, prima di salvare.

5. Salva il documento

Ora invia il documento completo, con le righe annidate, in POST documento. Aggiungi una Idempotency-Key: se la rete cade e ripeti la richiesta, non crei una fattura doppia.

curl -X POST 'https://{host}/api/v3/1/documento' \
    -H 'Authorization: Bearer <token>' \
    -H 'Content-Type: application/json' \
    -H 'Idempotency-Key: 6f1d2c3b-8a47-4e2f-9c1d-0b5e7a9f3c21' \
    --data '{
      "tipoDocumento": "FatturaAccompagnatoria",
      "classeDocumento": "Vendita",
      "stato": "Bozza",
      "data": "2026-10-07T08:24:08.8038146+00:00",
      "numeroParteNumerica": 26,
      "numero": "26",
      "ivaEsclusa": true,
      "valutaId": 1,
      "cambio": 1.0,
      "anagraficaId": 418,
      "pagamentoId": 2,
      "righe": [
        {"descrizione": "Consulenza sistemistica", "quantità": 10, "prezzo": 125.00,
         "sconto1": 0.10, "prezzoScontato": 112.50, "importo": 1125.00, "causaleIvaId": 3},
        {"descrizione": "Installazione", "quantità": 1, "prezzo": 300.00,
         "prezzoScontato": 300.00, "importo": 300.00, "causaleIvaId": 3}
      ],
      "totaleMerce": 1425.00, "totaleMerceScontata": 1425.00,
      "totaleImponibile": 1425.00, "totaleImposta": 313.50,
      "totaleDocumento": 1738.50, "nettoAPagare": 1738.50,
      "iva1CausaleIvaId": 3, "iva1ImponibileLordo": 1425.00,
      "iva1Imponibile": 1425.00, "iva1Imposta": 313.50
    }'

La risposta è 201 Created con il documento salvato, il suo id, il concurrencyToken e le righe numerate in posizione. Finché è in bozza puoi modificarlo con PUT documento/{id} seguendo il controllo della concorrenza: rileggi, modifica, ricalcola righe e totali, rispedisci.

Rimanda l'oggetto così come l'hai letto

Un documento letto con expand=Righe contiene riferimenti $ref dalle righe al documento. Se lo rimandi con una PUT, conservali: un client che toglie i campi $ ottiene un 400 di validazione sulle righe.

6. Emetti

curl -X POST 'https://{host}/api/v3/1/documento/9876/emit' \
    -H 'Authorization: Bearer <token>'

L'emissione legge il documento salvato e, a seconda del tipo:

  1. aggiorna i dati del cliente (fatturato, data dell'ultima fattura);
  2. crea la registrazione contabile e le scadenze, in base al pagamento;
  3. per i documenti che movimentano merce, crea il movimento di magazzino e aggiorna le giacenze;
  4. aggiorna gli ordini collegati.

La risposta è il documento con stato Emesso.

Errori di emissione

L'emissione risponde 400 con un Problem Details quando:

Messaggio Causa
Il pagamento è obbligatorio. Documento di vendita senza pagamentoId.
Il documento non ha righe. Nessuna riga salvata.
Documento emesso in precedenza. Il documento è già emesso: non si emette due volte.
… non supporta l'emissione. Il tipo di documento non si emette (ordini e preventivi, per esempio).

Un documento emesso non si modifica: una PUT risponde 400 ("Il documento è già stato emesso."). L'errore è forzabile con validationOverride=true, ma la correzione non tocca registrazioni, scadenze e movimenti già creati.

Cancellare un documento emesso non annulla l'emissione

DELETE documento/{id} elimina il documento, ma la registrazione contabile, le scadenze e i movimenti di magazzino creati dall'emissione restano, scollegati dal documento. Vanno rimossi a parte, così come i dati del cliente aggiornati dall'emissione non tornano indietro.

Documenti da altri documenti

Oltre a partire da zero, puoi riempire un documento con le righe di altri documenti: crea la fattura (passi 2 e 5, anche senza righe), poi importa. Queste operazioni ricalcolano i totali da sole.

Endpoint Importa da
POST documento/{id}/import/ddt DDT (fattura differita)
POST documento/{id}/import/ordine Ordini cliente
POST documento/{id}/import/preventivo Preventivi
POST documento/{id}/import/reso Resi
POST documento/{id}/import/acconto Fatture di acconto da scontare
POST documento/{id}/import/proforma Fatture proforma

Per duplicare un documento esistente usa invece POST documento/{id}/newinstancefromtemplate: restituisce una copia con la data odierna e, per i documenti di vendita, un nuovo numero, da salvare con POST.