Skip to content

Commit

Permalink
Lower the scope of the lib to just EN16931 (#3)
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Nöhles <jan.noehles@easybill.de>
  • Loading branch information
BolZer authored Jun 26, 2024
1 parent d0739a1 commit f676b1d
Show file tree
Hide file tree
Showing 313 changed files with 468 additions and 83,293 deletions.
78 changes: 41 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,64 +3,68 @@
[![Generic badge](https://img.shields.io/badge/License-MIT-blue.svg)]()

## Introduction
`e-invoicing` is a library to generate and read data of the specifications Peppol BIS Billing, XRechnung (UBL & CII)
and ZUGFeRD / factur-x. The library offers the possibility to generate EN16931 conform e-invoices.

### Current supported specification
- Peppol BIS Billing - Version 3.0.15
- XRechnung - Version 3.0.1
- ZUGFeRD / Factur-x - Version 2.2.0 / Version 1.0.06
`e-invoicing` is a library to generate and read data of specifications which comply with the EN16931.

## Usage
```bash
composer require easybill/e-invoicing
```

### Example: Creating ZUGFeRD/factur-x XML
### Example: EN16931 Cross Industry Invoice
The document factory offers handy shortcut functions to assemble a document for every supported specification
with the correct basic structure. $document is now ready to be filled with data related to your business case.

```PHP
use easybill\eInvoicing\DocumentFactory;
use easybill\eInvoicing\Specs\ZUGFeRD\Enums\ZUGFeRDProfileType;

$document = DocumentFactory::createZUGFeRDInvoice(ZUGFeRDProfileType::EN16931);
use easybill\eInvoicing\CII\Documents\CrossIndustryInvoice;
use easybill\eInvoicing\CII\Models\DocumentContextParameter;
use easybill\eInvoicing\CII\Models\ExchangedDocument;
use easybill\eInvoicing\CII\Models\ExchangedDocumentContext;
use easybill\eInvoicing\CII\Models\DateTime;
use easybill\eInvoicing\Transformer;

$document = new CrossIndustryInvoice();
$document->exchangedDocument = new ExchangedDocument();
$document->exchangedDocumentContext = new ExchangedDocumentContext();
$document->exchangedDocumentContext->documentContextParameter = new DocumentContextParameter();
$document->exchangedDocumentContext->documentContextParameter->id = 'urn:cen.eu:en16931:2017';
$document->exchangedDocument->id = '471102';
$document->exchangedDocument->issueDateTime = DateTime::create(102, '20200305');
// etc...
$xml = ZUGFeRDTransformer::create()->transform($invoice)
$xml = Transformer::create()->transformToXml($document)
```

### Example: Reading a known XML file format

If you only want to support a subset of the offered specifications (as an example ZUGFeRD/factur-x) you may use the
builder and reader from the corresponding namespace.
### Example: EN16931 Universal Business Language Invoice
The document factory offers handy shortcut functions to assemble a document for every supported specification
with the correct basic structure. $document is now ready to be filled with data related to your business case.

```PHP
use easybill\eInvoicing\Specs\ZUGFeRD\Reader;
use easybill\eInvoicing\Specs\ZUGFeRD\Transformer;

$xml = file_get_contents($exampleXmlFile);

$document = Reader::create()->transform($xml);

$document->exchangedDocument->name = 'Example Value'

$xml = Transformer::create()->transform($document);
use easybill\eInvoicing\Transformer;
use easybill\eInvoicing\UBL\Documents\UblInvoice;

$document = new UblInvoice();
$document->customizationId = 'urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0';
$document->profileId = 'urn:fdc:peppol.eu:2017:poacc:billing:01:1.0';
$document->id = '123456XX';
$document->issueDate = '2016-04-04';
$document->invoiceTypeCode = 380;
$document->documentCurrencyCode = 'EUR';
$document->buyerReference = '04011000-12345-03';
// etc...
$xml = Transformer::create()->transformToXml($document)
```

### Example: Reading an unknown XML file

There might be the case that you receive some XML which may or may not be supported by this library. `e-invoicing` offers a handy
way to just parse that XML and see if is deserializable to one of the supported formats.
way to just parse that XML and see if is deserializable to UBL or CII.

```PHP
use easybill\eInvoicing\DocumentXmlReader;
use easybill\eInvoicing\Specs\XRechnung\CII\Documents\XRechnungCiiInvoice;
use easybill\eInvoicing\Reader;
use easybill\eInvoicing\CII\Documents\CrossIndustryInvoice;

$xml = file_get_contents($exampleXmlFile);

$readerResult = DocumentXmlReader::create()->read($xml);
$readerResult = Reader::create()->read($xml);

// If the format is supported and valid in its structure the following check will be true
$readerResult->isSuccess()
Expand All @@ -72,8 +76,8 @@ $readerResult->isError()
// Invoking the getDocument method on an error will result in a LogicException
$document = $readerResult->getDocument();

if ($document instanceof XRechnungCiiInvoice) {
// do something with the XRechnungCiiInvoice
if ($document instanceof CrossIndustryInvoice) {
// do something with the CrossIndustryInvoice
}
```

Expand All @@ -82,10 +86,10 @@ You can refer to the [tests](https://github.com/easybill/e-invoicing/tree/main/t
## Considerations

### Limitations
This library does not offer any way to validate the structured data against the rules of the specifications.
Please take a look at the folder [Validators](https://github.com/easybill/e-invoicing/tree/main/tests/Validators) in the tests folder. There you will find ways to validate the documents against the specification
rulesets. ZUGFeRD offers XSD-Schema-Files which you may use directly in your PHP code. For XRechnung and Peppol will take a look at the [docker-compose.yaml](https://github.com/easybill/e-invoicing/blob/main/docker-compose.yaml).
There you will find microservices which offer a validation API.
This library does not offer any way to validate the structured data against the rules of EN16931 or any of the CIUS.
Please take a look at the folder [Validators](https://github.com/easybill/e-invoicing/tree/main/tests/Validators) in the tests folder. There you will find ways to validate the documents against the CIUS specification
rulesets. ZUGFeRD/factur-x offers XSD-Schema-Files which you may use directly in your PHP code. KOSiT offers a dedicated validator to validate your EN16931
document against the XRechnung CIUS specification.

## Issues and contribution
Feel free to create Pull-Requests or Issue if you have trouble with this library or any related resource.
9 changes: 0 additions & 9 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,4 @@ services:
healthcheck:
test: curl --fail http://localhost:8080/health || exit 0
interval: 10s
retries: 6

peppol-validator:
image: 'easybill/peppol-bis-billing-validator:0.2.0'
ports:
- '8081:8080'
healthcheck:
test: curl --fail http://localhost:8081/health || exit 0
interval: 10s
retries: 6
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Documents;
namespace easybill\eInvoicing\CII\Documents;

use easybill\eInvoicing\Specs\ZUGFeRD\Models\ExchangedDocument;
use easybill\eInvoicing\Specs\ZUGFeRD\Models\ExchangedDocumentContext;
use easybill\eInvoicing\Specs\ZUGFeRD\Models\SupplyChainTradeTransaction;
use easybill\eInvoicing\CII\Models\ExchangedDocument;
use easybill\eInvoicing\CII\Models\ExchangedDocumentContext;
use easybill\eInvoicing\CII\Models\SupplyChainTradeTransaction;
use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
use JMS\Serializer\Annotation\XmlElement;
Expand All @@ -19,7 +19,7 @@
#[XmlNamespace(uri: 'urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100', prefix: 'ram')]
#[XmlNamespace(uri: 'http://www.w3.org/2001/XMLSchema', prefix: 'xs')]
#[XmlNamespace(uri: 'urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100', prefix: 'udt')]
final class ZUGFeRDInvoice
final class CrossIndustryInvoice
{
#[Type(ExchangedDocumentContext::class)]
#[XmlElement(namespace: 'urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100')]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation as JMS;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\XRechnung\CII\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
use JMS\Serializer\Annotation\XmlElement;

final class DateTime
final class Date
{
#[Type(DateTimeString::class)]
#[Type(DateString::class)]
#[XmlElement(cdata: false, namespace: 'urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100')]
#[SerializedName('DateTimeString')]
public DateTimeString $dateTimeString;
#[SerializedName('DateString')]
public DateString $dateTimeString;

public static function create(int $format, string $value): self
{
$self = new self();
$self->dateTimeString = DateTimeString::create($format, $value);
$self->dateTimeString = DateString::create($format, $value);
return $self;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\XRechnung\CII\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation as JMS;

final class DateTimeString
final class DateString
{
#[JMS\Type('integer')]
#[JMS\XmlAttribute]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation as JMS;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation\AccessorOrder;
use JMS\Serializer\Annotation\SerializedName;
Expand All @@ -19,7 +19,7 @@ final class DocumentLineDocument
public string $lineId;

/** @var Note[] */
#[Type('array<easybill\eInvoicing\Specs\ZUGFeRD\Models\Note>')]
#[Type('array<easybill\eInvoicing\CII\Models\Note>')]
#[XmlList(entry: 'IncludedNote', inline: true, namespace: 'urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100')]
public array $notes = [];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
Expand Down Expand Up @@ -42,7 +42,7 @@ final class ExchangedDocument
/**
* @var Note[]
*/
#[Type('array<easybill\eInvoicing\Specs\ZUGFeRD\Models\Note>')]
#[Type('array<easybill\eInvoicing\CII\Models\Note>')]
#[XmlList(entry: 'IncludedNote', inline: true, namespace: 'urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100')]
public array $notes = [];
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation\AccessorOrder;
use JMS\Serializer\Annotation\SerializedName;
Expand Down Expand Up @@ -59,7 +59,7 @@ final class HeaderTradeAgreement
public ?ReferencedDocument $contractReferencedDocument = null;

/** @var ReferencedDocument[] */
#[Type('array<easybill\eInvoicing\Specs\ZUGFeRD\Models\ReferencedDocument>')]
#[Type('array<easybill\eInvoicing\CII\Models\ReferencedDocument>')]
#[XmlList(entry: 'AdditionalReferencedDocument', inline: true, namespace: 'urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100')]
public array $additionalReferencedDocuments = [];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace easybill\eInvoicing\Specs\ZUGFeRD\Models;
namespace easybill\eInvoicing\CII\Models;

use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
Expand Down
Loading

0 comments on commit f676b1d

Please sign in to comment.