Skip to content
bert-scriptPublic

About

UBL 2.1 to PEPPOL BIS Billing 3.0 converter and validator REST API

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

PEPPOL BIS Billing 3.0 Converter

REST API service die UBL 2.1 Invoice XML-documenten omzet naar PEPPOL BIS Billing 3.0 formaat en valideert tegen de officiële Schematron-regels.

Wat doet deze service?

PEPPOL BIS Billing 3.0 is een Europese standaard voor elektronische facturering, gebaseerd op UBL 2.1. Deze service:

  • Converteert een generieke UBL 2.1 factuur naar een PEPPOL-conforme factuur
  • Valideert de output tegen de officiële CEN EN16931 en PEPPOL Schematron-regels
  • Rapporteert precies welke velden zijn aangepast en welke validatiefouten er zijn

Wat de conversie doet

Stap Omschrijving
CustomizationID Wordt gezet naar de PEPPOL BIS 3.0 identifier
ProfileID Wordt gezet naar het PEPPOL billing profiel
UBLVersionID Wordt toegevoegd als 2.1 indien ontbrekend
InvoiceTypeCode Wordt gezet naar 380 (commerciële factuur) indien ontbrekend
Verplichte velden Controle op aanwezigheid van leverancier, klant, bedragen, belasting en factuurregels

Quickstart

Vereisten

  • Python 3.11+
  • Of: Docker

Lokaal draaien

# 1. Clone de repository
git clone https://github.com/bert-script/peppol.git
cd peppol

# 2. Maak een virtual environment en installeer dependencies
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

# 3. Download de officiële PEPPOL validatie-artefacten
bash scripts/download_validation_artifacts.sh

# 4. Start de server
uvicorn app.main:app --reload

De API draait nu op http://localhost:8000. Interactieve API-documentatie is beschikbaar op http://localhost:8000/docs.

Met Docker

docker compose up --build

API Endpoints

GET /health

Controleer of de service draait en validatie-artefacten geladen zijn.

curl http://localhost:8000/health
{
  "status": "healthy",
  "validation_artifacts_loaded": true,
  "peppol_rules_version": "3.0.20"
}

POST /convert

Converteer een UBL 2.1 Invoice naar PEPPOL BIS Billing 3.0.

curl -X POST http://localhost:8000/convert \
  -H "Content-Type: application/xml" \
  -d @factuur.xml

Query parameters:

Parameter Default Omschrijving
validate true Valideer de output na conversie

Response:

{
  "success": true,
  "invoice_xml": "<?xml version='1.0' ...?>...",
  "modifications": [
    "CustomizationID: added 'urn:cen.eu:en16931:2017#compliant#...'",
    "ProfileID: added 'urn:fdc:peppol.eu:2017:poacc:billing:01:1.0'"
  ],
  "validation": {
    "valid": true,
    "cen_rules": { "errors": [], "warnings": [] },
    "peppol_rules": { "errors": [], "warnings": [] }
  }
}

POST /validate

Valideer een bestaande PEPPOL-factuur zonder conversie.

curl -X POST http://localhost:8000/validate \
  -H "Content-Type: application/xml" \
  -d @peppol-factuur.xml

Response:

{
  "valid": false,
  "cen_rules": {
    "errors": [
      {
        "rule_id": "BR-01",
        "location": "/Invoice",
        "message": "An Invoice shall have a Specification identifier.",
        "severity": "error"
      }
    ],
    "warnings": []
  },
  "peppol_rules": {
    "errors": [],
    "warnings": []
  }
}

Voorbeeld UBL Invoice

Minimaal voorbeeld van een UBL 2.1 factuur die geconverteerd kan worden:

<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
         xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
         xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
    <cbc:ID>FACTUUR-001</cbc:ID>
    <cbc:IssueDate>2024-01-15</cbc:IssueDate>
    <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
    <cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
    <cac:AccountingSupplierParty>
        <cac:Party>
            <cbc:EndpointID schemeID="0106">12345678</cbc:EndpointID>
            <cac:PartyLegalEntity>
                <cbc:RegistrationName>Mijn Bedrijf BV</cbc:RegistrationName>
            </cac:PartyLegalEntity>
            <cac:PostalAddress>
                <cac:Country>
                    <cbc:IdentificationCode>NL</cbc:IdentificationCode>
                </cac:Country>
            </cac:PostalAddress>
        </cac:Party>
    </cac:AccountingSupplierParty>
    <cac:AccountingCustomerParty>
        <cac:Party>
            <cbc:EndpointID schemeID="0106">87654321</cbc:EndpointID>
            <cac:PartyLegalEntity>
                <cbc:RegistrationName>Klant BV</cbc:RegistrationName>
            </cac:PartyLegalEntity>
            <cac:PostalAddress>
                <cac:Country>
                    <cbc:IdentificationCode>NL</cbc:IdentificationCode>
                </cac:Country>
            </cac:PostalAddress>
        </cac:Party>
    </cac:AccountingCustomerParty>
    <cac:TaxTotal>
        <cbc:TaxAmount currencyID="EUR">21.00</cbc:TaxAmount>
        <cac:TaxSubtotal>
            <cbc:TaxableAmount currencyID="EUR">100.00</cbc:TaxableAmount>
            <cbc:TaxAmount currencyID="EUR">21.00</cbc:TaxAmount>
            <cac:TaxCategory>
                <cbc:ID>S</cbc:ID>
                <cbc:Percent>21</cbc:Percent>
                <cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme>
            </cac:TaxCategory>
        </cac:TaxSubtotal>
    </cac:TaxTotal>
    <cac:LegalMonetaryTotal>
        <cbc:LineExtensionAmount currencyID="EUR">100.00</cbc:LineExtensionAmount>
        <cbc:TaxExclusiveAmount currencyID="EUR">100.00</cbc:TaxExclusiveAmount>
        <cbc:TaxInclusiveAmount currencyID="EUR">121.00</cbc:TaxInclusiveAmount>
        <cbc:PayableAmount currencyID="EUR">121.00</cbc:PayableAmount>
    </cac:LegalMonetaryTotal>
    <cac:InvoiceLine>
        <cbc:ID>1</cbc:ID>
        <cbc:InvoicedQuantity unitCode="EA">1</cbc:InvoicedQuantity>
        <cbc:LineExtensionAmount currencyID="EUR">100.00</cbc:LineExtensionAmount>
        <cac:Item>
            <cbc:Name>Consultancy</cbc:Name>
            <cac:ClassifiedTaxCategory>
                <cbc:ID>S</cbc:ID>
                <cbc:Percent>21</cbc:Percent>
                <cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme>
            </cac:ClassifiedTaxCategory>
        </cac:Item>
        <cac:Price>
            <cbc:PriceAmount currencyID="EUR">100.00</cbc:PriceAmount>
        </cac:Price>
    </cac:InvoiceLine>
</Invoice>

Projectstructuur

peppol/
├── app/
│   ├── main.py              # FastAPI app met lifespan
│   ├── config.py             # Configuratie via environment variables
│   ├── routers/              # API endpoints
│   ├── services/
│   │   ├── converter.py      # UBL → PEPPOL conversielogica
│   │   └── validator.py      # Schematron validatie via XSLT
│   ├── models/               # Pydantic response models
│   └── utils/                # XML helpers, SVRL parser
├── tests/                    # Pytest tests
├── scripts/
│   └── download_validation_artifacts.sh
├── Dockerfile
└── docker-compose.yml

Tests

source .venv/bin/activate
pytest -v

Validatie-artefacten

De service gebruikt de officiële pre-compiled XSLT-bestanden van OpenPEPPOL:

  • CEN-EN16931-UBL.xslt — Europese Norm EN16931 bedrijfsregels
  • PEPPOL-EN16931-UBL.xslt — PEPPOL-specifieke regels bovenop EN16931

Deze worden gedownload via scripts/download_validation_artifacts.sh en niet meegecommit in git.

Licentie

MIT

About

UBL 2.1 to PEPPOL BIS Billing 3.0 converter and validator REST API

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages