# Modalità di emergenza

> Cosa fare con il PEM fuori servizio: motivazioni, registro di emergenza e chiusura di emergenza con i riepiloghi IVA.

Pagina HTML: https://app.billyssw.it/documentazione/emergenza  
Indice della documentazione: https://app.billyssw.it/documentazione/index.md  
Tutta la documentazione in un file: https://app.billyssw.it/documentazione/full.md

## Modalità di emergenza

Cosa fare quando il PEM non può emettere documenti commerciali: annotare le vendite sul registro di emergenza e trasmettere a fine giornata la chiusura di emergenza, con i riepiloghi IVA.

### Quando si usa

Se il PEM entra nello stato di `Fuori servizio`, questo **non** può emettere documenti commerciali. Finché il PEM è fuori servizio, le chiamate `…/fiscale/invio/*` (vendita, annullo, reso, chiusura) rispondono `409`. L'esercente annota i documenti commerciali sul **registro di emergenza dei corrispettivi** fuori dal sistema. A fine giornata ne trasmette gli aggregati con la chiusura di emergenza.

La modalità di emergenza si applica anche quando il tuo gestionale non può connettersi alle API per mancata connessione internet. In questo caso, la comunicazione di `Fuori servizio` può avvenire successivamente al ripristino della connessione.

### Entrare in emergenza

Il tuo software porta il PEM fuori servizio con `PUT …/fiscale/stato`, indicando `stato` `01`, una `motivazione` e le `note`, fino a 255 caratteri. Stato e motivazione sono stringhe di due cifre: `"01"`, non `1`.

Note sempre obbligatorie

Billy richiede le `note` con ogni Fuori servizio, qualunque sia la motivazione, e con la dismissione; senza, risponde `422`.

PUT …/fiscale/stato

```bash
curl -X PUT \
  https://pem-staging.billyssw.it/api/pem/ASVS-241232/fiscale/stato \
  -H "Authorization: Bearer <access_token>" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{ "stato": "01", "motivazione": "01", "note": "Guasto alla rete del punto vendita" }'
```

| Motivazione | Significato |
| --- | --- |
| 01 | Problemi hardware. |
| 02 | Problemi software. |
| 03 | Problemi di comunicazione tra PEM e PEL. |
| 08 | Mancata integrità. |
| 09 | Messa in magazzino: periodo di inattività. |
| 10 | Altro. |

Gli altri codici non si inviano: `04` e `05` riguardano la dismissione, che ha un endpoint dedicato; `06` e `07` li attribuisce il sistema al passaggio In servizio. Al rientro si invia solo `{ "stato": "03" }`, senza motivazione.

Il PEM può anche finire fuori servizio da solo:

-   se un documento non raggiunge il PEL entro 12 ore, con motivazione `03`. Prima di cambiare stato il PEM chiude la giornata e conserva il Journal firmato, che trasmette al rientro in servizio;
-   se la catena degli hash risulta compromessa, con motivazione `08`.

### Chiusura di emergenza

A fine giornata l'esercente riporta i totali del registro di emergenza: un riepilogo per aliquota, natura o ventilazione, più i totali dei pagamenti. È ammessa solo con il PEM `Fuori servizio` ed è riservata all'esercente titolare: un operatore riceve `403`.

POST …/fiscale/emergenza/chiusura

```bash
curl -X POST \
  https://pem-staging.billyssw.it/api/pem/ASVS-241232/fiscale/emergenza/chiusura \
  -H "Authorization: Bearer <access_token>" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotency_key": "3f1c2a9e-8b7d-4c1e-9a2f-5d6e7f8a9b0c",
    "n_doc_commerciali": 12,
    "riepiloghi": [
      { "iva": "22", "importo_parziale": "100.00", "imposta": "22.00" },
      { "iva": "10", "importo_parziale": "50.50", "imposta": "5.05" }
    ],
    "totali": {
      "pagato_contanti": "100.00",
      "pagato_elettronico": "77.55",
      "sconto_a_pagare": "0.00"
    }
  }'
```

200 OK

```json
{
  "success": true,
  "dati": {
    "id_presa_in_carico": "12345",
    "n_doc_commerciali": 12
  }
}
```

#### Regole principali

| Campo | Regola |
| --- | --- |
| idempotency\_key | UUID, obbligatorio, uno per chiusura. Vedi sotto, Idempotenza. |
| n\_doc\_commerciali | Numero di documenti annotati sul registro nella giornata, almeno 1. |
| riepiloghi | Da 1 a 40 righe. Ognuna indica esattamente uno tra iva (4, 5, 10, 22), natura (N1–N6) e ventilazione\_iva (SI). La stessa aliquota o natura non si ripete, salvo con codice\_attivita diversi. |
| riepiloghi\[\].importo\_parziale | Imponibile, al netto dell'IVA (al lordo con ventilazione\_iva). È già al netto di resi, annulli, beni in sospeso e non riscossi, ma comprende gli omaggi. Può essere negativo. |
| riepiloghi\[\].imposta | Obbligatoria se e solo se la riga ha iva. Deve valere importo\_parziale × aliquota, con una tolleranza di ±0,01. |
| riepiloghi\[\].totale\_ammontare\_resi, totale\_ammontare\_annulli, beni\_in\_sospeso, non\_riscosso\_\* | Facoltativi, mai negativi. Li si indica a parte, senza toglierli una seconda volta dall'imponibile. |
| riepiloghi\[\].codice\_attivita | Facoltativo, deve essere uno dei codici Ateco configurati sul PEM. |
| totali | pagato\_contanti, pagato\_elettronico e sconto\_a\_pagare sono obbligatori. ticket (pagato\_ticket, numero\_ticket) è facoltativo: senza opzione buoni pasto è un normale pagamento; con l'opzione attiva nella giornata richiede un riepilogo al 10% il cui lordo copra i ticket, e il riferimento normativo TICKET lo attribuisce il sistema (rif\_normativo non si invia). |

Gli importi sono **stringhe decimali** con al massimo due decimali (`"100.00"`), mai numeri in virgola mobile. Se il registro riporta importi IVA inclusa, scorpora l'IVA prima dell'invio: `imponibile = lordo × 100 / (100 + aliquota)`, arrotondato al centesimo, e l'imposta per differenza. Così imponibile più imposta danno il lordo esatto: ad esempio 122,00 € al 22% diventano `100.00` + `22.00`. Le righe con natura o ventilazione non hanno imposta. L'elenco completo dei campi è nel **riferimento REST**.

Lo stesso calcolo in codice, a partire dalle vendite del registro con aliquota IVA, importi IVA inclusa in centesimi. Lavorare in centesimi interi evita gli errori della virgola mobile.

Riepiloghi per aliquota · PHP

```php
// $vendite: [['iva' => '22', 'lordo' => 12200], ...] — lordo in centesimi
$lordi = [];
foreach ($vendite as $v) {
    $lordi[$v['iva']] = ($lordi[$v['iva']] ?? 0) + $v['lordo'];
}

$euro = fn (int $c): string =>
    ($c < 0 ? '-' : '') . sprintf('%d.%02d', intdiv(abs($c), 100), abs($c) % 100);

$riepiloghi = [];
foreach ($lordi as $iva => $lordo) {
    $imponibile = (int) round($lordo * 100 / (100 + (int) $iva)); // al centesimo
    $riepiloghi[] = [
        'iva'              => (string) $iva,
        'importo_parziale' => $euro($imponibile),
        'imposta'          => $euro($lordo - $imponibile),          // per differenza
    ];
}
```

Riepiloghi per aliquota · Node.js

```javascript
// vendite: [{ iva: '22', lordo: 12200 }, ...] — lordo in centesimi
const lordi = {};
for (const v of vendite) lordi[v.iva] = (lordi[v.iva] ?? 0) + v.lordo;

const euro = (c) =>
  (c < 0 ? '-' : '') + `${Math.trunc(Math.abs(c) / 100)}.${String(Math.abs(c) % 100).padStart(2, '0')}`;
// arrotondamento al centesimo, metà lontano dallo zero anche per i negativi
const arrotonda = (x) => Math.sign(x) * Math.round(Math.abs(x));

const riepiloghi = Object.entries(lordi).map(([iva, lordo]) => {
  const imponibile = arrotonda((lordo * 100) / (100 + Number(iva)));
  return {
    iva,
    importo_parziale: euro(imponibile),
    imposta: euro(lordo - imponibile), // per differenza
  };
});
```

Le righe con natura (`N1`–`N6`) e quelle con ventilazione si costruiscono a parte: `importo_parziale` è il lordo e non c'è `imposta`.

#### Giornata e idempotenza

-   La chiusura vale sempre per la giornata in cui viene inviata, e non c'è un campo data. Inviala lo stesso giorno delle vendite che riepiloga: inviata dopo la mezzanotte, viene registrata sulla giornata nuova e non c'è modo di attribuirla a quella precedente.
-   Una giornata ammette più chiusure di emergenza: ogni `idempotency_key` nuova è una chiusura e una trasmissione distinte, anche con dati identici.
-   Ripetere la chiamata con la stessa chiave è sicuro. Se la chiusura è già trasmessa ricevi lo stesso `id_presa_in_carico` e non parte un nuovo invio. Se l'invio era fallito, il PEM lo ritenta con i dati salvati, compresa la giornata originale.
-   La stessa chiave con dati diversi viene rifiutata con `422` sul campo `idempotency_key`. Per dati nuovi, genera una chiave nuova.

### Seguire la trasmissione

Ogni chiusura di emergenza trasmessa diventa una richiesta di tipo `CORRISPETTIVI`, come quella ordinaria. Si segue con lo scope `fiscale:read`:

-   `GET …/fiscale/richieste?tipo=CORRISPETTIVI` elenca le trasmissioni all'AdE;
-   con l'`id` di quell'elenco, non con l'`id_presa_in_carico`, `richieste/stato/{id}` ne aggiorna lo stato e `richieste/esito/{id}` scarica l'esito XML.
