Versioni di mappatura
Come i nomi dei campi di un ERP diventano la nostra fattura, e come cambiano le versioni.
- Nella sandbox
In parole semplici
Una mappatura traduce i nomi dei campi di un ERP nel nostro modello di fattura, ed è così che un errore può indicare il campo nell’export del cliente stesso. Quando i nomi dei campi di un cliente cambiano, aggiungiamo una nuova versione e conserviamo quella vecchia, per poter tornare indietro. Business Central e SAP Business One sono mappati, ciascuno a partire dalla struttura pubblicata dell’ERP e non ancora dall’export di un cliente.
Una mappatura trasforma l’export di un ERP nella nostra fattura canonica. Quando i nomi dei campi di un cliente cambiano, aggiungiamo una nuova versione e spostiamo il puntatore attivo. La vecchia versione resta, quindi il puntatore può tornare indietro.
Cosa esiste oggi
Sono mappati due ERP: Business Central (la fattura di vendita dell’API v2.0) e SAP Business One (una fattura o una nota di credito così come la restituisce il Service Layer). Ciascuno ha una versione attiva, e le versioni precedenti restano.
Nota
Entrambe le mappature sono state scritte a partire dalla struttura pubblicata dell’ERP e provate su export inventati, perché non esiste ancora l’export di un cliente. Un cliente il cui export usa altri nomi riceve una nuova versione. Niente di tutto questo chiede al cliente di modificare l’ERP.
Un export va a POST /validate o a POST /invoices, con connector ed export al posto di document.
Inviare un export
POST /validate accetta connector (business-central o sap-b1) ed export (l’oggetto dell’export) al posto di document; POST /invoices accetta gli stessi due campi. I campi che la mappatura non conosce vengono ignorati. Il report indica quale versione è stata eseguita, in mapping_version. La richiesta è validate-export-ok.json, un export con parti inventate.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/validate" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
--data-binary @validate-export-ok.jsonimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/validate"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("validate-export-ok.json")))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}import { readFile } from 'node:fs/promises';
const response = await fetch('https://api-sandbox-eu.eurinvoice.com/validate', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/json',
},
body: await readFile('validate-export-ok.json'),
});
console.log(response.status);
console.log(await response.text());{
"valid": true,
"route": "DE-XRECHNUNG",
"documents": [
{
"sha256": "3e7f648bdc6c6d6f5ad78cd356b39c3020595bb7f0896b78a8510ec6969db317",
"kind": "xrechnung-ubl",
"content_base64": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgi... (5,900 characters, shortened for these docs)"
}
],
"layers": [
{
"findings": [],
"passed": true,
"layer": "schema"
},
{
"findings": [],
"passed": true,
"layer": "mapping"
},
{
"findings": [],
"passed": true,
"layer": "pre-check"
},
{
"findings": [],
"passed": true,
"layer": "kosit"
}
],
"mapping_version": "v2"
}Provare un’altra versione
mapping_version nella richiesta sceglie una versione per quella chiamata. Il puntatore non si sposta. Per una versione che non esiste, la risposta è 400. La richiesta è validate-export-bad-version.json, lo stesso export con "mapping_version": "v9".
curl -X POST "https://api-sandbox-eu.eurinvoice.com/validate" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
--data-binary @validate-export-bad-version.jsonimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/validate"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("validate-export-bad-version.json")))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}import { readFile } from 'node:fs/promises';
const response = await fetch('https://api-sandbox-eu.eurinvoice.com/validate', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/json',
},
body: await readFile('validate-export-bad-version.json'),
});
console.log(response.status);
console.log(await response.text());{
"detail": "That mapping version does not exist. The live pointer was left unchanged.",
"type": "https://eurinvoice.com/problems/bad-request",
"title": "The request could not be read",
"status": 400
}Trovare il campo nell’ERP
Una segnalazione indica il campo dell’ERP, non il nostro campo canonico. Correggere un’unità che la mappatura non conosce spetta a noi: la aggiungiamo alla tabella delle unità e rilasciamo una nuova versione. La richiesta è validate-export-bad-unit.json, in cui Kiste non è nella tabella.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/validate" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
--data-binary @validate-export-bad-unit.jsonimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/validate"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("validate-export-bad-unit.json")))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}import { readFile } from 'node:fs/promises';
const response = await fetch('https://api-sandbox-eu.eurinvoice.com/validate', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/json',
},
body: await readFile('validate-export-bad-unit.json'),
});
console.log(response.status);
console.log(await response.text());{
"valid": false,
"route": "DE-XRECHNUNG",
"layers": [
{
"findings": [],
"passed": true,
"layer": "schema"
},
{
"findings": [
{
"code": "BR-CL-23",
"field": "salesInvoiceLines[0].unitOfMeasureCode",
"fix_hint": "Add the ERP's unit to the client's unit mapping table (for example 'Std.' to HUR).",
"who_fixes": "us",
"source": "mapping",
"message": "A unit of measure on a line is not recognised. We are adding it to your mapping."
}
],
"passed": false,
"layer": "mapping"
},
{
"findings": [],
"passed": true,
"layer": "pre-check"
}
],
"mapping_version": "v2"
}Completare i dati mancanti spetta al partner. La relativa segnalazione ha who_fixes impostato su erp e indica il campo dell’ERP da completare.
Come si rilascia una modifica
- Copiamo la versione attiva in una nuova versione e la modifichiamo. La vecchia resta.
- Inviamo gli export di esempio del cliente con
mapping_versionimpostato sulla nuova versione, mentre la vecchia resta attiva. - Spostiamo il puntatore attivo sulla nuova versione.
- Se qualcosa non va, lo riportiamo indietro.