Electronic document

I’m working on interfacing Tryton with Chorus (platform to send electronic invoice for French administration).

This platform supports many format like UBL, UN/CEFACT, CPP etc. I choose to implement UN/CEFACT (because it is the basis for Factur-X ) Indeed UBL and UN/CEFACT are very similar and they both rely on standard code from UNECE (which is also the author of UN/CEFACT).

Now, the hard part is to create a module structure for those modules. We should keep in mind that electronic invoice is only one kind of electronic document, those standard implements Shipment, Quotation, Purchase Request etc. For the same Tryton document, we may need to generate different electronic documents, for example to send to different parties or systems.
Also each norm has many revisions and we may need to support many at the same time for compatibility. That’s why I think we should follow the same design as the account_payment_sepa module with one template per version.

To avoid the multiplication of modules, I think we should have a single module per format which will implement all the different kind of documents. Those will be registered in function of the installed modules (thanks to issue7178).

So my proposal is to use “edocument” as general prefix. I find it to be not too long (compared to electronic_document) and it is pretty clear what it covers.
So we will have for example those modules:

- edocument_unece: define common code from UNECE
- edocument_uncefact: implement UN/CEFACT documents
- edocument_ubl: implement UBL documents

Inside the module we will have:

edocument_uncefact/
    template/
        16B/
            CrossIndustryInvoice.xml
            CrossIndustryOrder.xml
            CrossIndustryQuotationProposal.xml
        16B-CII/
            CrossIndustryInvoice.xml

edocument_ubl/
    template/
        2.0/
            Invoice.xml
        2.1/
            CreditNote.xml
            Invoice.xml
            Order.xml

The generation and processing of the document will be managed by a simple Model, this will prevent to pollute to much the document Model. For example for UN/CEFACT CrossIndustryInvoice:

class Invoice(Model):
    __name__ = 'edocument.uncefact.invoice'

    def __init__(self, invoice):
        self.invoice = invoice

    def get(self, template='16B-CII/CrossIndustryInvoice.xml'):
        …

    @classmethod
    def process(cls, document):
        …
1 Like

This is good news as we use Chorus…

There are numerous aspects, for example: for invoices, there are 1) ‘simple’ invoices and 2) monthly invoices based upon advancement in construction projects (projet de décompte mensuel or situation) plus the final invoice (projet de décompte final)…

Also, there is not only XML based exchange, but as well the possibility to exchange PDF format invoices (potentially with PAdES or XAdES digital signature)

To note, there is also recuperation of invoices for project managers (architects and such)
for approval (or not) and relaying to the customer…
Actually, prime contractors and co-contractors representatives (mandataires de groupements) do the same for their subcontractors and/or partner contractors.

I’m just starting to know tryton, and the reason was because I’m building my ubl invoice system. Include e documents on native way, will be a very promising feature in these times. Great job Cedric.

In general looks good to me.

Why not e_doc_ubl?
It’s shorter and stats more clearly that “e” is an abbreviation.
I think the abbreviation doc for document is common in computer
and business context.

2.0 is the protocol/language version?

It is not really a shorter contest :wink:
But we used email and not e_mail for notification_email so it seems more consistent to also use edocument.

I find doc is being used for documentation not document.

It is the version of the document format.

Shouldn’t we use something below Model?
What you really want is probably just PoolBase, no ?

I do not need anything from lower classes.

But also the WarningErrorMixin.
And it seems wrong to register in the model pool something that is not a subclass of Model.

below as in lower level not as in subclass.

Probably yes.

It could be a fourth component of the pool.
For me a model contains fields and have a functional meaning.

Here I have the impression we are confronted to a kind of concept that reuse our special inheritance system but that is used in a more technical way.

Nothing in the implementation requires to have fields.

Of course it’s not mandatory, I am talking about semantic here (yet there is at least the id field).

And if you look at the implementation of __setup__ it is declaring RPC methods related to fields and it duplicates the fields. This for me is an indication that a Model is made to contain fields (but if you want you can keep it empty of course).

I do not think it is the meaning of Model that is wrong but what current base Model contains.
We had to put the id and __setup__ because they must be shared between ModelView and ModelStorage.
So it will be cleaner to break Model into two (by adding maybe a ModelField)

OK we’re talking about the same things but using different words.

For what it’s worth, there is a new invoice document supported by Chorus
PDF/A-3 with syntax format CII16b, aka Factur-X

This has been adopted by CEN/TC 434 - Electronic Invoicing as the European Standard
EN 16931-1:2017

Electronic invoicing - Part 1: Semantic data model of the core elements of an electronic invoice

Our friends over at Akretion have come up with an implementation (for Odoo).

and