Skip to content

Latest commit

 

History

History
285 lines (202 loc) · 11.7 KB

README.md

File metadata and controls

285 lines (202 loc) · 11.7 KB

European e-Invoice

Create and import e-invoices with ERPNext.

In particular, this app supports reading and writing electronic invoices according to the UN/CEFACT Cross-Industry-Invoice (CII) standard in the following profiles:

  • BASIC
  • EN 16931
  • EXTENDED
  • XRECHNUNG

All profiles except for "XRECHNUNG" can be embedded in a PDF file, known as ZUGFeRD or Factur-X.

This app cannot read or write UBL invoices. It also does not provide any special way of sending or receiving e-invoices (e.g. Peppol). Instead, it focuses on the conversion between ERPNext's internal data model and the XML format of the above standards.

Installation

You can install this app using the bench CLI:

cd $PATH_TO_YOUR_BENCH
bench get-app https://github.com/alyf-de/eu_einvoice --branch $MAJOR_VERSION
bench install-app eu_einvoice

Please use a branch (MAJOR_VERSION) that matches the major version of ERPNext you are using. For example, version-14 or version-15. If you are a developer contributing new features, you'll want to use the develop branch instead.

Setup

E-invoices rely on common codes that describe the content of the invoice. E.g. "C62" is used for the UOM "One" and "ZZZ" is used for a mutually agreed mode of payment.

Common codes are part of a code list. You'll need to import the code lists and map the codes you need to the corresponding ERPNext entities. Please use the "Import Genericode" button in Code List and paste the URL linked below.

Code List Mapped DocType Default Value
UNTDID 4461 Payment means code  Payment Terms Template, Mode of Payment ZZZ
Codes for Units of Measure Used in International Trade UOM C62
Codes for Passengers, Types of Cargo, Packages and Packaging Materials (optional) UOM C62
Codes for Duty Tax and Fee Categories Item Tax Template, Account, Tax Category, Sales Taxes and Charges Template S
VAT exemption reason code list Item Tax Template, Account, Tax Category, Sales Taxes and Charges Template vatex-eu-ae

For example, let's say your standard Payment Terms Template is "Bank Transfer, 30 days". You'll need to find the suitable Common Code for bank transfers within the Code List "UNTDID.4461". In this case, the code is "58". Then you add a row to the Applies To table, select "Payment Terms Template" as the Link Document Type and "Bank Transfer, 30 days" as the Link Name. If you now create an Invoice with this Payment Terms Template, the eInvoice will contain the code "58" for the payment means, signalling that the payment should done via bank transfer.

The retrieval of codes goes from the most specific to the most general. E.g. for determining the VAT type of a line item, we first look for a code using the specific item's Item Tax Template and Income Account, then fall back to the code for the invoice's Tax Category or Sales Taxes and Charges Template.

Buyer Reference (German: Leitweg-ID)

If you work with government customers or similar large organizations, you might need to specify their Buyer Reference in the eInvoice. This is done by setting the Buyer Reference field in the Sales Invoice. You can already fill this field in the Customer master data or the Sales Order.

Usage

Sales Invoice

During validation of the Sales Invoice, the potential eInvoice is created and validated against the schematron rules for the selected E Invoice Profile, so that you can see any potential problems before submitting it.

To download the XML file (XRechnung), open a Sales Invoice and click on "..." > "Download eInvoice".

When you open the print preview of the Sales Invoice and click on "PDF", the generated PDF file will have the e-invoice XML embedded. An exception is the E Invoice Profile "XRECHNUNG", which is intended to be a plain XML file. In this case, the PDF will not have the XML embedded.

Tip

You can test both XML and PDF+XML files by re-importing them, using the E Invoice Import DocType.

The following fields of the Sales Invoice are currently considered for the eInvoice:

  • Invoice type (credit note, corrected invoice, commercial invoice)
  • Invoice number
  • Invoice date
  • Due date
  • From date
  • To date
  • Language
  • Currency
  • Company
    • Phone No
    • Email
    • Fax
  • Company Name
  • Company Address
    • Address Line 1
    • Address Line 2
    • Postcode
    • City
    • Country
  • Company Contact Person
    • Full Name
    • Email Address (takes precedence over Company > Email)
    • Phone (takes precedence over Company > Phone No)
    • Department
  • Company Tax ID
  • Customer Name
  • Buyer Reference (fetched from Sales Order or Customer)
  • Customer Address
    • Address Line 1
    • Address Line 2
    • Postcode
    • City
    • Country
  • Contact Email
  • Contact Mobile (takes precedence over Contact Person > Phone)
  • Contact Person
    • Full Name
    • Phone
    • Department
  • Customer's Purchase Order
  • Customer's Purchase Order Date
  • Customer's Tax ID
  • Items:
    • Item Name
    • Description
    • Company's Item Code
    • Customer's Item Code
    • Delivery Note number and date
    • Quantity + Unit
    • Rate
    • Net Amount
    • Amount
  • Terms and Conditions Details (converted to markdown)
  • Incoterm and named place
  • Payment Schedule
    • Description
    • Due date
    • Amount
    • Discount Type (must be "Percentage")
    • Discount
    • Discount Date
  • Sales Taxs and Charges
    • The Charge Type "Actual" is used as logistics or service charges.
    • For Charge Type "On Net Total", the taxable amount is calculated as tax_amount / rate * 100, if the rate is available in the tax row or in the corresponding Account [1].
    • The Charge Type "On Item Quantity" is not supported.
  • Total
  • Discount Amount
  • Net Total
  • Total Taxes and Charges
  • Grand Total
  • Total Advance
  • Outstanding Amount

[1] The correct taxable amount is only available starting from ERPNext v16. For earlier versions we currently have to approximate it, which comes with a small error margin.

Purchase Invoice

To import a new eInvoice, create a new E Invoice Import and upload the XML or PDF file.

We extract the E-Invoice Profile and validate the XML against the corresponding schematron rules.

A correct eInvoice will look like this:

Correct eInvoice

A problematic eInvoice will look like this. You can see the validation errors in the Validation Details section:

Problematic eInvoice

It is still possible to import an invoice, even if there are formal validation errors.

Taxes are mapped to "Actual" charges in the Purchase Invoice, so that ERPNext does not try to recalculate them.

You can find XML files for testing in the following repositories:

Add your custom logic

This app provides hooks to add custom logic to the eInvoice creation process:

  • before_einvoice_generation

    Called right before the eInvoice is generated. The hook function receives the Sales Invoice as an argument and can modify it.

  • after_einvoice_generation

    Called right after the eInvoice is generated. The hook function receives the Sales Invoice and the generated eInvoice as arguments.

For example, your myapp/hooks.py could look like this:

doc_events = {
	"Sales Invoice": {
		"before_einvoice_generation": "myapp.einvoice.before_einvoice_generation",
		"after_einvoice_generation": "myapp.einvoice.after_einvoice_generation",
	}
}

And your myapp/einvoice.py like this:

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from drafthorse.models.document import Document
    from erpnext.accounts.doctype.sales_invoice.sales_invoice import SalesInvoice


def before_einvoice_generation(doc: "SalesInvoice", event: str):
    """Modify the Sales Invoice object before generating the eInvoice."""
    doc.customer_name = "Special Customer Name"


def after_einvoice_generation(doc: "SalesInvoice", event: str, einvoice: "Document"):
    """Modify the generated eInvoice after it was created."""
    einvoice.trade.agreement.buyer.name = doc.customer_name

Warning

These methods are also triggered during the validate event of the Sales Invoice. In this case, if you change the Sales Invoice object, these changes will be saved to the database.

Validation

You can upload an XML invoice file to https://www.itb.ec.europa.eu/invoice/upload and validate it as "CII Invoice CML".

Contributing

This app uses pre-commit for code formatting and linting. Please install pre-commit and enable it for this repository:

cd apps/eu_einvoice
pre-commit install

Pre-commit is configured to use the following tools for checking and formatting your code:

  • ruff
  • eslint
  • prettier
  • pyupgrade

CI

This app can use GitHub Actions for CI. The following workflows are configured:

  • CI: Installs this app and runs unit tests on every push to develop branch.
  • Linters: Runs Frappe Semgrep Rules and pip-audit on every pull request.

Dependencies

  • drafthorse by Raphael Michel, released under the Apache License 2.0

    Used to create and parse XML invoices.

  • factur-x by Alexis de Lattre, released unser a BSD License

    Used to extract XML data from PDF files, and to create PDF files with embedded XML.

  • SaxonC by Saxonica

    Used for XSL transformation (validate XML against schematron).

  • lxml by Infrae

    Used for general XML parsing.

  • SchXslt by David Maus

    Used to convert Schematron files to XSL.

Sponsors

Many thanks to the following companies for sponsoring the initial development of this app:

  • aepfel+birnen IT GmbH
  • axessio Hausverwaltung GmbH
  • Burkhard Baumsteigtechnik GmbH & Co. KG
  • DriveCon GmbH
  • ibb testing gmbh
  • itsdave GmbH
  • iXGate UG
  • Kautenburger IT GmbH
  • MERECS Engineering GmbH
  • voidsy GmbH
  • … and many more

Note

We only list companies that have explicitly agreed to have their name published here. If you want to be listed here too, please send us a short note by email.

License

Copyright (C) 2024 ALYF GmbH

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or(at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.