Skip to content

Commit

Permalink
complete proof-of-concept
Browse files Browse the repository at this point in the history
- sample XML -> JSON -> JSON schema -> random JSON -> random XML
- validate XML and JSON
  • Loading branch information
Paolo Greppi committed Jul 1, 2018
1 parent eaf2b17 commit 91fb9c9
Show file tree
Hide file tree
Showing 53 changed files with 11,744 additions and 1,326 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
update.sh
.directory
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
BSD 3-Clause License

Copyright (c) 2018, simevo
Copyright (c) 2018, Paolo Greppi <paolo.greppi@simevo.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
all:
cp fatturaPA_1.2_schema.json www/.
cp fatturaPA_1.2.hbs www/.
cp samples/IT01234567890_FPA01.json www/.
mkdir -p www/js
cp node_modules/@json-editor/json-editor/dist/jsoneditor.min.js www/js/.
cp node_modules/handlebars/dist/handlebars.min.js www/js/.
137 changes: 103 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,75 +1,146 @@
# Rappresentazione JSON per le fatture elettroniche

**Proof-of-concept** per una rappresentazione in formato JSON di fatture elettroniche.
**Proof-of-concept** per una rappresentazione in formato JSON delle fatture elettroniche secondo la normativa italiana ("fatturaPA").

## Rationale
## Scopo

Le fatture elettroniche vengono trasmesse ed archiviate in formato **XML**.

La documentazione tecnica del **formato XML** delle fatture elettroniche è disponibile al seguente url: http://www.fatturapa.gov.it/export/fatturazione/it/normativa/f-2.htm
La documentazione tecnica di riferimento del **formato XML** delle fatture elettroniche è disponibile al seguente url: http://www.fatturapa.gov.it/export/fatturazione/it/normativa/f-2.htm

Tuttavia per lo sviluppo di front-end per la creazione di fatture è più comodo manipolare i dati in formato **JSON**, e convertire ad XML al termine delle fasi che richiedono l'interazione con l'utente.
Poiché per lo sviluppo di API ed SDK è più comodo manipolare i dati in formato **JSON**, questo proof-of-concept mira a valutare la fattibilità di:
- **convertire** XML <-> JSON
- **validare** JSON
- **generare** di file fattura JSON e XML **randomizzati** a scopo di test e fuzzy-test
- **rapid prototyping** di visualizzatori ed editor
- persistenza in **database** SQL e No-SQL.

## Proof-of-concept
## Prerequisiti

```
sudo apt install make nodejs yarnpkg python libxml2-utils
yarnpkg install
```

## Procedura

La procedura seguita per il proof-of-concept è rappresentata nel seguente flow-chart (in blu i files tratti dal sito `fatturapa.gov.it`, in rosso quelli generati in questo progetto):

![Flow-chart](flowchart.png "Flow-chart del proof-of-concept")

Innanzitutto lo [schema XML (*XSD**)](https://en.wikipedia.org/wiki/XML_Schema_(W3C)) della fattura elettronica tratto dal sito `fatturapa.gov.it` ([`Schema_del_file_xml_FatturaPA_versione_1.2.xsd`](Schema_del_file_xml_FatturaPA_versione_1.2.xsd)) è stato trasformato in una versione ([`Schema_del_file_xml_FatturaPA_versione_1.2_cleanup.xsd`](Schema_del_file_xml_FatturaPA_versione_1.2_cleanup.xsd)) normalizzata (fromdos, xmllint, 2-space indent) e che importa una [copia locale dello schema `xmldsig`](xmldsig-core-schema.xsd):
```
- <xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd" />
+ <xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd"/>
```

Quindi i files XML di esempio tratti dal sito `fatturapa.gov.it` sono stati validati con questo schema così modificato (script [`bin/validate_samples.sh`](bin/validate_samples.sh)).

Le fatture in formato JSON possono essere validate per mezzo di un **JSON schema** (vedi [paragrafo Riferimenti](#riferimenti)), anche se quest'ultimo è più limitato dello schema XML, alcuni vincoli dovranno essere validati dall'applicazione, ad esempio:

- limitazioni ai **set di caratteri ammessi**: ad esempio il campo `FatturaElettronica.FatturaElettronicaHeader.DatiTrasmissione.ProgressivoInvio` secondo lo schema XML è vincolato al tipo `String10Type` così definito:
```
<xs:simpleType name="String10Type">
<xs:restriction base="xs:normalizedString">
<xs:pattern value="(\p{IsBasicLatin}{1,10})"/>
</xs:restriction>
</xs:simpleType>
```
che accetta da 1 a 10 caratteri del [blocco Unicode Basic Latin](https://www.w3.org/TR/xsd-unicode-blocknames/), mentre lo schema JSON accetta qualunque stringa di lunghezza compresa tra 1 e 10 caratteri:
```
"ProgressivoInvio": {
"type": "string",
"minLength": 1,
"maxLength": 10,
```
- **alternative**: ad esempio il tipo `AnagraficaType` usato per i campi:
- `FatturaElettronica.FatturaElettronicaHeader.CedentePrestatore.DatiAnagrafici.Anagrafica`,
- `FatturaElettronica.FatturaElettronicaBody[].DatiTrasporto.DatiAnagraficiVettore.Anagrafica`
- `FatturaElettronica.FatturaElettronicaHeader.RappresentanteFiscale.DatiAnagraficiRappresentante.Anagrafica`
- `FatturaElettronica.FatturaElettronicaHeader.CessionarioCommittente.DatiAnagraficiCessionario.Anagrafica`
- `FatturaElettronica.FatturaElettronicaHeader.TerzoIntermediarioOSoggettoEmittente.DatiAnagraficiTerzoIntermediario.Anagrafica`
contiene un campo `Denominazione` che è in alternativa a `Nome` + `Cognome`; non vi è modo di esprimere questo tipo di vincolo in JSON schema.
Inizialmente si è tentato di convertire lo schema XSD in uno [schema JSON](http://json-schema.org/) usando la libreria [jgeXml](https://github.com/Mermade/jgeXml):
```
nodejs ./node_modules/jgexml/testxsd2j.js Schema_del_file_xml_FatturaPA_versione_1.2.xsd > fatturaPA_1.2_schema.json
```
ottenendo però uno schema non utilizzabile.
Successivamente i files XML di esempio sono stati convertiti a JSON per mezzo della libreria [node-xml2json](https://github.com/buglabs/node-xml2json) con i comandi:
```
./bin/xml2json.js IT01234567890_FPR01.xml | grep -v 'xmlns:' | grep -v 'xsi:' | sed 's/p:FatturaElettronica/FatturaElettronica/g' > IT01234567890_FPR01.json
./bin/xml2json.js IT01234567890_FPR02.xml | grep -v 'xmlns:' | grep -v 'xsi:' | sed 's/p:FatturaElettronica/FatturaElettronica/g' > IT01234567890_FPR02.json
./bin/xml2json.js IT01234567890_FPR03.xml | grep -v 'xmlns:' | grep -v 'xsi:' | sed 's/p:FatturaElettronica/FatturaElettronica/g' > IT01234567890_FPR03.json
./bin/xml2json.js IT01234567890_FPA01.xml | grep -v 'xmlns:' | grep -v 'xsi:' | sed 's/p:FatturaElettronica/FatturaElettronica/g' > IT01234567890_FPA01.json
./bin/xml2json.js IT01234567890_FPA02.xml | grep -v 'xmlns:' | grep -v 'xsi:' | sed 's/p:FatturaElettronica/FatturaElettronica/g' > IT01234567890_FPA02.json
./bin/xml2json.js IT01234567890_FPA03.xml | grep -v 'xmlns:' | grep -v 'xsi:' | sed 's/p:FatturaElettronica/FatturaElettronica/g' > IT01234567890_FPA03.json
```
Successivamente i files XML di esempio sono stati convertiti a JSON per mezzo della libreria [node-xml2json](https://github.com/buglabs/node-xml2json) (script [`bin/convert_samples.sh`](bin/convert_samples.sh)).
Questa conversione automatica funziona più o meno, ma c'è un intoppo per quegli elementi che possono ripetersi (es. `FatturaElettronica.FatturaElettronicaBody` e `FatturaElettronica.FatturaElettronicaBody[1].DatiBeniServizi.DettaglioLinee`), nel caso ve ne sia uno solo la conversione genera un JSON dove invece di un `array` ci è un `object` vedi:
Questa conversione automatica funziona più o meno, ma c'è un intoppo per quegli elementi che possono ripetersi (ad esempio `FatturaElettronica.FatturaElettronicaBody` e `FatturaElettronica.FatturaElettronicaBody[1].DatiBeniServizi.DettaglioLinee`), nel caso ve ne sia uno solo la conversione genera un JSON dove invece di un `array` c'è un `object` vedi:
- https://social.msdn.microsoft.com/Forums/windowsapps/en-US/03fe9c57-b7a8-41aa-ade4-652b6b5eafc3/single-element-xml-to-json-array
- http://jersey.576304.n2.nabble.com/Single-Element-Arrays-and-JSON-td5532105.html
Per questi casi occorre wrappare manualmente l'`object` con `[]`.
Si è quindi generato uno schema a partire dai files fattura JSON di esempio, per mezzo del servizio on-line [jsonschema](https://www.jsonschema.net/), che dopo semplificazione (`grep -v '$id'`) e aggiunta di campi `title` e `description` desunti dalle SPECIFICHE TECNICHE OPERATIVE DEL FORMATO DELLA FATTURA DEL SISTEMA DI INTERSCAMBIO ha dato origine allo schema `www/fatturaPA_1.2_schema_semplificato.json`.
Per questi casi occorre wrappare manualmente l'`object` con `[]`, vedi punto 1 del [paragrafo **TODO**](#todo).
Si è quindi generato uno schema a partire dai files fattura JSON di esempio, per mezzo del servizio on-line [jsonschema.net](https://www.jsonschema.net/), che dopo semplificazione (`grep -v '$id'`) e aggiustamento manuale aggiunta di campi `title` e `description` desunti dalle SPECIFICHE TECNICHE OPERATIVE DEL FORMATO DELLA FATTURA DEL SISTEMA DI INTERSCAMBIO ha dato origine allo schema [`fatturaPA_1.2_schema.json`](fatturaPA_1.2_schema.json).
Tutti i files di esempio JSON sono validati dallo schema (script [`bin/validate_samples_json.sh`](bin/validate_samples_json.sh)).
La generazione di files XML random a scopo di test è possibile con alcuni strumenti commerciali, ad esempio:
- https://msdn.microsoft.com/en-us/library/aa302296.aspx "Generating XML Documents from XML Schemas" Priya Lakshminarayanan, Microsoft Corporation - August 2004
- https://msdn.microsoft.com/en-us/library/dd489258.aspx "How to: Create an XML Document Based on an XSD Schema Visual Studio 2015"
- https://msdn.microsoft.com/en-us/library/cc716766.aspx "XML Schema Explorer"
In questo proof-of-concept si è scelto di generare dei files JSON random partendo dallo schema JSON per mezzo di [json-schema-faker](https://github.com/json-schema-faker/json-schema-faker), e di riconvertirli a XML per mezzo del template [handlebars](http://handlebarsjs.com/) [`fatturaPA_1.2.hbs`](fatturaPA_1.2.hbs) (script [`bin/generate_random.sh`](bin/generate_random.sh)).
Tutti i files di esempio JSON sono validati dallo schema come si può verificare con:
Il template handlebars è stato validato riconvertendo ad XML i files di esempio (script [`bin/reconvert_samples.sh`](bin/reconvert_samples.sh)).
Al momento tuttavia i files XML così ottenuti non passano la validazione con lo schema XML, con degli errori del tipo:
```
bin/validate.js
random/00.xml:21: element Nome: Schemas validity error : Element 'Nome': This element is not expected. Expected is one of ( Titolo, CodEORI ).
random/00.xml:23: element RegimeFiscale: Schemas validity error : Element 'RegimeFiscale': [facet 'enumeration'] The value 'RF33' is not an element of the set {'RF01', 'RF02', 'RF03', 'RF04', 'RF05', 'RF06', 'RF07', 'RF08', 'RF09', 'RF10', 'RF11', 'RF12', 'RF13', 'RF14', 'RF15', 'RF16', 'RF17', 'RF19', 'RF18'}.
random/00.xml:23: element RegimeFiscale: Schemas validity error : Element 'RegimeFiscale': 'RF33' is not a valid value of the atomic type '{http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2}RegimeFiscaleType'.
random/00.xml:50: element TipoDocumento: Schemas validity error : Element 'TipoDocumento': [facet 'enumeration'] The value 'TD24' is not an element of the set {'TD01', 'TD02', 'TD03', 'TD04', 'TD05', 'TD06'}.
random/00.xml:50: element TipoDocumento: Schemas validity error : Element 'TipoDocumento': 'TD24' is not a valid value of the atomic type '{http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2}TipoDocumentoType'.
random/00.xml:52: element Data: Schemas validity error : Element 'Data': '6591-35-44' is not a valid value of the atomic type '{http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2}DataFatturaType'.
random/00.xml:107: element TipoDocumento: Schemas validity error : Element 'TipoDocumento': [facet 'enumeration'] The value 'TD74' is not an element of the set {'TD01', 'TD02', 'TD03', 'TD04', 'TD05', 'TD06'}.
random/00.xml:107: element TipoDocumento: Schemas validity error : Element 'TipoDocumento': 'TD74' is not a valid value of the atomic type '{http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2}TipoDocumentoType'.
random/00.xml:109: element Data: Schemas validity error : Element 'Data': '5281-04-38' is not a valid value of the atomic type '{http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2}DataFatturaType'.
random/00.xml:160: element TipoDocumento: Schemas validity error : Element 'TipoDocumento': [facet 'enumeration'] The value 'TD85' is not an element of the set {'TD01', 'TD02', 'TD03', 'TD04', 'TD05', 'TD06'}.
random/00.xml:160: element TipoDocumento: Schemas validity error : Element 'TipoDocumento': 'TD85' is not a valid value of the atomic type '{http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2}TipoDocumentoType'.
random/00.xml:162: element Data: Schemas validity error : Element 'Data': '8927-46-70' is not a valid value of the atomic type '{http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2}DataFatturaType'.
random/00.xml fails to validate
```
causati dalla eccessiva randomizzazione, vedi punto 2 del [paragrafo **TODO**](#todo).
## Demo
Con lo schema semplificato così ottenuto e [JSON Editor](https://github.com/json-editor/json-editor) è possibile generare automaticamente un editor:
Con lo schema così ottenuto e [JSON Editor](https://github.com/json-editor/json-editor) è possibile generare automaticamente un editor basico.
Per lanciare il demo:
```
yarn install
make
python -m SimpleHTTPServer
```
visitare http://localhost:8000/www/index.html
quindi visitare http://localhost:8000/www/index.html
## TODO
- completare lo schema
0. Completare lo schema JSON
1. implementare la conversione automatica da fattura formato XML a formato JSON; dovrebbe essere possibile configurando xml2json con l'[opzione `arrayNotation`](https://github.com/buglabs/node-xml2json#options-object-for-tojson)
2. configurare `json-schema-faker` [annotando lo schema](https://github.com/json-schema-faker/json-schema-faker#faking-values) in modo che i files JSON dopo conversione a XML passino la validazione
- aggiungere funzioni all'editor usando [le estensioni allo schema JSON specifiche di JSON Editor](https://github.com/json-editor/json-editor#json-schema-support)
3. aggiungere funzioni al demo usando [le estensioni allo schema JSON specifiche di JSON Editor](https://github.com/json-editor/json-editor#json-schema-support) e implementando le funzioni avanzate e lo styling come negli esempi [Advanced Usage](http://rawgithub.com/jdorn/json-editor/master/examples/advanced.html) e [CSS Integration](http://rawgithub.com/jdorn/json-editor/master/examples/css_integration.html)
- testare editor basato su specifici fronr-end frameworks:
4. testare editor basato su specifici front-end frameworks:
- vue.js, es: https://gitlab.com/formschema/native
- vue.js, esempio: https://gitlab.com/formschema/native
- react, es: https://github.com/mozilla-services/react-jsonschema-form
- react, esempio: https://github.com/mozilla-services/react-jsonschema-form
- angular, es: https://github.com/json-schema-form/angular-schema-form
- angular, esempio: https://github.com/json-schema-form/angular-schema-form
- aggiungere funzione di import di un file XML esistente
## Legalese
- unit tests:
- verificare che lo schema JSON valida tutti i files fattura JSON di esempio
- verificare che i files XML generati sono compliant con lo schema XSD
Copyright (c) 2018, Paolo Greppi <[email protected]>
Licenza: BSD 3-Clause, vedi file [`LICENSE`](LICENSE).
## Riferimenti
Expand All @@ -80,5 +151,3 @@ visitare http://localhost:8000/www/index.html
- https://spacetelescope.github.io/understanding-json-schema/reference/index.html
- https://jsonschemalint.com/#/version/draft-06/markup/json

- https://github.com/json-editor/json-editor
Loading

0 comments on commit 91fb9c9

Please sign in to comment.