File: PKG-INFO

package info (click to toggle)
python-a38 0.1.8-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 440 kB
  • sloc: python: 4,065; xml: 174; makefile: 80; sh: 14
file content (214 lines) | stat: -rw-r--r-- 7,227 bytes parent folder | download | duplicates (4)
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

![full workflow](https://github.com/Truelite/python-a38/actions/workflows/py.yml/badge.svg)

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