1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
Metadata-Version: 2.1
Name: a38
Version: 0.1.8
Summary: parse and generate Italian Fattura Elettronica
Home-page: https://github.com/Truelite/python-a38/
Author: Enrico Zini
Author-email: enrico@truelite.it
License: https://www.apache.org/licenses/LICENSE-2.0.html
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Provides-Extra: cacerts
Provides-Extra: formatted_python
Provides-Extra: html
License-File: LICENSE
# Python A38

Library to generate Italian Fattura Elettronica from Python.
This library implements a declarative data model similar to Django models, that
is designed to describe, validate, serialize and parse Italian Fattura
Elettronica data.
Only part of the specification is implemented, with more added as needs will
arise. You are welcome to implement the missing pieces you need and send a pull
request: the idea is to have a good, free (as in freedom) library to make
billing in Italy with Python easier for everyone.
The library can generate various kinds of fatture that pass validation, and can
parse all the example XML files distributed by
[fatturapa.gov.it](https://www.fatturapa.gov.it/it/lafatturapa/esempi/)
## Dependencies
Required: dateutil, pytz, asn1crypto, and the python3 standard library.
Optional:
* yapf for formatting `a38tool python` output
* lxml for rendering to HTML
* the wkhtmltopdf command for rendering to PDF
* requests for downloading CA certificates for signature verification
## `a38tool` script
A simple command line wrapper to the library functions is available as `a38tool`:
```text
$ a38tool --help
usage: a38tool [-h] [--verbose] [--debug]
{json,xml,python,diff,validate,html,pdf,update_capath} ...
Handle fattura elettronica files
positional arguments:
{json,xml,python,diff,validate,html,pdf,update_capath}
actions
json output a fattura in JSON
xml output a fattura in XML
python output a fattura as Python code
diff show the difference between two fatture
validate validate the contents of a fattura
html render a Fattura as HTML using a .xslt stylesheet
pdf render a Fattura as PDF using a .xslt stylesheet
update_capath create/update an openssl CApath with CA certificates
that can be used to validate digital signatures
optional arguments:
-h, --help show this help message and exit
--verbose, -v verbose output
--debug debug output
```
See [a38tool.md](a38tool.md) for more details.
## Example code
```py
import a38
from a38.validation import Validation
import datetime
import sys
cedente_prestatore = a38.CedentePrestatore(
a38.DatiAnagraficiCedentePrestatore(
a38.IdFiscaleIVA("IT", "01234567890"),
codice_fiscale="NTNBLN22C23A123U",
anagrafica=a38.Anagrafica(denominazione="Test User"),
regime_fiscale="RF01",
),
a38.Sede(indirizzo="via Monferrato", numero_civico="1", cap="50100", comune="Firenze", provincia="FI", nazione="IT"),
iscrizione_rea=a38.IscrizioneREA(
ufficio="FI",
numero_rea="123456",
stato_liquidazione="LN",
),
contatti=a38.Contatti(email="local_part@pec_domain.it"),
)
cessionario_committente = a38.CessionarioCommittente(
a38.DatiAnagraficiCessionarioCommittente(
a38.IdFiscaleIVA("IT", "76543210987"),
anagrafica=a38.Anagrafica(denominazione="A Company SRL"),
),
a38.Sede(indirizzo="via Langhe", numero_civico="1", cap="50142", comune="Firenze", provincia="FI", nazione="IT"),
)
bill_number = 1
f = a38.FatturaPrivati12()
f.fattura_elettronica_header.dati_trasmissione.id_trasmittente = a38.IdTrasmittente("IT", "10293847561")
f.fattura_elettronica_header.dati_trasmissione.codice_destinatario = "FUFUFUF"
f.fattura_elettronica_header.cedente_prestatore = cedente_prestatore
f.fattura_elettronica_header.cessionario_committente = cessionario_committente
body = f.fattura_elettronica_body[0]
body.dati_generali.dati_generali_documento = a38.DatiGeneraliDocumento(
tipo_documento="TD01",
divisa="EUR",
data=datetime.date.today(),
numero=bill_number,
causale=["Test billing"],
)
body.dati_beni_servizi.add_dettaglio_linee(
descrizione="Test item", quantita=2, unita_misura="kg",
prezzo_unitario="25.50", aliquota_iva="22.00")
body.dati_beni_servizi.add_dettaglio_linee(
descrizione="Other item", quantita=1, unita_misura="kg",
prezzo_unitario="15.50", aliquota_iva="22.00")
body.dati_beni_servizi.build_dati_riepilogo()
body.build_importo_totale_documento()
res = Validation()
f.validate(res)
if res.warnings:
for w in res.warnings:
print(str(w), file=sys.stderr)
if res.errors:
for e in res.errors:
print(str(e), file=sys.stderr)
filename = "{}{}_{:05d}.xml".format(
f.fattura_elettronica_header.cedente_prestatore.dati_anagrafici.id_fiscale_iva.id_paese,
f.fattura_elettronica_header.cedente_prestatore.dati_anagrafici.id_fiscale_iva.id_codice,
bill_number)
tree = f.build_etree()
with open(filename, "wb") as out:
tree.write(out, encoding="utf-8", xml_declaration=True)
```
# Digital signatures
Digital signatures on Firma Elettronica are
[CAdES](https://en.wikipedia.org/wiki/CAdES_(computing)) signatures.
openssl cal verify the signatures, but not yet generate them. A patch to sign
with CAdES [has been recently merged](https://github.com/openssl/openssl/commit/e85d19c68e7fb3302410bd72d434793e5c0c23a0)
but not yet released as of 2019-02-26.
## Downloading CA certificates
CA certificates for validating digital certificates are
[distributed by the EU in XML format](https://ec.europa.eu/cefdigital/wiki/display/cefdigital/esignature).
See also [the AGID page about it](https://www.agid.gov.it/it/piattaforme/firma-elettronica-qualificata/certificati).
There is a [Trusted List Browser](https://webgate.ec.europa.eu/tl-browser/) but
apparently no way of getting a simple bundle of certificates useable by
openssl.
`a38tool` has basic features to download and parse CA certificate information,
and maintain a CA certificate directory:
```
a38tool update_capath certdir/ --remove-old
```
No particular effort is made to validate the downloaded certificates, besides
the standard HTTPS checks performed by the [requests
library](http://docs.python-requests.org/en/master/).
## Verifying signed `.p7m` files
Once you have a CA certificate directory, verifying signed p7m files is quite
straightforward:
```
openssl cms -verify -in tests/data/test.txt.p7m -inform der -CApath certs/
```
# Useful links
XSLT stylesheets for displaying fatture:
* From [fatturapa.gov.it](https://www.fatturapa.gov.it/),
among the [FatturaPA resources](https://www.fatturapa.gov.it/it/norme-e-regole/documentazione-fattura-elettronica/formato-fatturapa/index.html)
* From [AssoSoftware](http://www.assosoftware.it/allegati/assoinvoice/FoglioStileAssoSoftware.zip)
# Copyright
Copyright 2019-2024 Truelite S.r.l.
This software is released under the Apache License 2.0
|