parent
649f25006f
commit
9168806e34
18
README.rst
18
README.rst
|
@ -1,7 +1,7 @@
|
||||||
Factur-X Python library
|
Factur-X Python library
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
Factur-X is the e-invoicing standard for France and Germany. The Factur-X specifications are available on the `FNFE-MPE website <http://fnfe-mpe.org/factur-x/>`_. The Factur-X standard is also called ZUGFeRD 2.0 in Germany.
|
Factur-X is the e-invoicing standard for France and Germany. The Factur-X specifications are available on the `FNFE-MPE website <http://fnfe-mpe.org/factur-x/>`_ in English and French. The Factur-X standard is also called ZUGFeRD 2.0 in Germany.
|
||||||
|
|
||||||
The main feature of this Python library is to generate Factur-X invoices from a regular PDF invoice and a Factur-X compliant XML file.
|
The main feature of this Python library is to generate Factur-X invoices from a regular PDF invoice and a Factur-X compliant XML file.
|
||||||
|
|
||||||
|
@ -15,11 +15,20 @@ Some of the features provided by this lib also work for ZUGFeRD 1.0 (the ancesto
|
||||||
Installation
|
Installation
|
||||||
============
|
============
|
||||||
|
|
||||||
|
This library works both on python 2.7 and python 3.
|
||||||
|
|
||||||
|
To install it for python 3, run:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
sudo pip3 install --upgrade factur-x
|
||||||
|
|
||||||
|
To install it for python 2.7, run:
|
||||||
|
|
||||||
.. code::
|
.. code::
|
||||||
|
|
||||||
sudo pip install --upgrade factur-x
|
sudo pip install --upgrade factur-x
|
||||||
|
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
@ -56,6 +65,11 @@ Contributors
|
||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
* Version 0.9 dated 2019-01-25
|
||||||
|
|
||||||
|
* Port to python 3 contributed by JoshuaJan (https://github.com/joshuajan)
|
||||||
|
* Fix path to ZUGFeRD 1.0 XSD
|
||||||
|
|
||||||
* Version 0.8 dated 2018-06-10
|
* Version 0.8 dated 2018-06-10
|
||||||
|
|
||||||
* Make pretty_print work for XMP file, for better readability of that file
|
* Make pretty_print work for XMP file, for better readability of that file
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#! /usr/bin/python
|
#! /usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# © 2017 Alexis de Lattre <alexis.delattre@akretion.com>
|
# Copyright 2017-2019 Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
|
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
import sys
|
import sys
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#! /usr/bin/python
|
#! /usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# © 2017 Alexis de Lattre <alexis.delattre@akretion.com>
|
# Copyright 2017-2019 Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
|
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
import sys
|
import sys
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#! /usr/bin/python
|
#! /usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# © 2017 Alexis de Lattre <alexis.delattre@akretion.com>
|
# Copyright 2017-2019 Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
|
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
import sys
|
import sys
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
__version__ = '0.8'
|
__version__ = '0.9'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright 2016-2018, Alexis de Lattre <alexis.delattre@akretion.com>
|
# Copyright 2016-2019, Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,7 +25,6 @@
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
# TODO list:
|
# TODO list:
|
||||||
# - have both python2 and python3 support
|
|
||||||
# - add automated tests (currently, we only have tests at odoo module level)
|
# - add automated tests (currently, we only have tests at odoo module level)
|
||||||
# - keep original metadata by copy of pdf_tailer[/Info] ?
|
# - keep original metadata by copy of pdf_tailer[/Info] ?
|
||||||
|
|
||||||
|
@ -43,6 +42,12 @@ import os.path
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
|
import sys
|
||||||
|
if sys.version_info[0] == 3:
|
||||||
|
unicode = str
|
||||||
|
from io import IOBase
|
||||||
|
file = IOBase
|
||||||
|
|
||||||
|
|
||||||
FORMAT = '%(asctime)s [%(levelname)s] %(message)s'
|
FORMAT = '%(asctime)s [%(levelname)s] %(message)s'
|
||||||
logging.basicConfig(format=FORMAT)
|
logging.basicConfig(format=FORMAT)
|
||||||
|
@ -63,11 +68,6 @@ FACTURX_LEVEL2xmp = {
|
||||||
'en16931': 'EN 16931',
|
'en16931': 'EN 16931',
|
||||||
}
|
}
|
||||||
|
|
||||||
import sys
|
|
||||||
if sys.version_info[0] == 3:
|
|
||||||
unicode = str
|
|
||||||
from io import IOBase
|
|
||||||
file = IOBase
|
|
||||||
|
|
||||||
def check_facturx_xsd(
|
def check_facturx_xsd(
|
||||||
facturx_xml, flavor='autodetect', facturx_level='autodetect'):
|
facturx_xml, flavor='autodetect', facturx_level='autodetect'):
|
||||||
|
@ -84,6 +84,8 @@ def check_facturx_xsd(
|
||||||
:return: True if the XML is valid against the XSD
|
:return: True if the XML is valid against the XSD
|
||||||
raise an error if it is not valid against the XSD
|
raise an error if it is not valid against the XSD
|
||||||
"""
|
"""
|
||||||
|
logger.debug(
|
||||||
|
'check_facturx_xsd with factur-x lib %s', __version__)
|
||||||
if not facturx_xml:
|
if not facturx_xml:
|
||||||
raise ValueError('Missing facturx_xml argument')
|
raise ValueError('Missing facturx_xml argument')
|
||||||
if not isinstance(flavor, (str, unicode)):
|
if not isinstance(flavor, (str, unicode)):
|
||||||
|
@ -151,6 +153,8 @@ def check_facturx_xsd(
|
||||||
|
|
||||||
|
|
||||||
def get_facturx_xml_from_pdf(pdf_invoice, check_xsd=True):
|
def get_facturx_xml_from_pdf(pdf_invoice, check_xsd=True):
|
||||||
|
logger.debug(
|
||||||
|
'get_facturx_xml_from_pdf with factur-x lib %s', __version__)
|
||||||
if not pdf_invoice:
|
if not pdf_invoice:
|
||||||
raise ValueError('Missing pdf_invoice argument')
|
raise ValueError('Missing pdf_invoice argument')
|
||||||
if not isinstance(check_xsd, bool):
|
if not isinstance(check_xsd, bool):
|
||||||
|
@ -684,6 +688,8 @@ def generate_facturx_from_file(
|
||||||
:rtype: bool
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
start_chrono = datetime.now()
|
start_chrono = datetime.now()
|
||||||
|
logger.debug(
|
||||||
|
'generate_facturx_from_file with factur-x lib %s', __version__)
|
||||||
logger.debug('1st arg pdf_invoice type=%s', type(pdf_invoice))
|
logger.debug('1st arg pdf_invoice type=%s', type(pdf_invoice))
|
||||||
logger.debug('2nd arg facturx_xml type=%s', type(facturx_xml))
|
logger.debug('2nd arg facturx_xml type=%s', type(facturx_xml))
|
||||||
logger.debug('optional arg facturx_level=%s', facturx_level)
|
logger.debug('optional arg facturx_level=%s', facturx_level)
|
||||||
|
|
1
setup.py
1
setup.py
|
@ -26,6 +26,7 @@ setup(
|
||||||
'Development Status :: 4 - Beta',
|
'Development Status :: 4 - Beta',
|
||||||
'Intended Audience :: Developers',
|
'Intended Audience :: Developers',
|
||||||
'Programming Language :: Python :: 2.7',
|
'Programming Language :: Python :: 2.7',
|
||||||
|
'Programming Language :: Python :: 3.6',
|
||||||
'License :: OSI Approved :: BSD License',
|
'License :: OSI Approved :: BSD License',
|
||||||
"Operating System :: OS Independent",
|
"Operating System :: OS Independent",
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue