Skip to content

Commit

Permalink
Development Improvements (#1)
Browse files Browse the repository at this point in the history
- Rename namespace to easybill
- Fix github workflows
- Add readme
  • Loading branch information
BolZer authored Jun 7, 2024
1 parent a6bdb53 commit ceb7632
Show file tree
Hide file tree
Showing 233 changed files with 755 additions and 649 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ jobs:
run: |
composer install --no-interaction --prefer-dist --no-progress ${{ matrix.dependencies }}
- name: Start docker validators
run: |
docker compose up --detach --wait --wait-timeout 30
- name: Run tests
run: |
php /vendor/bin/pest
./vendor/bin/pest
4 changes: 2 additions & 2 deletions .task/dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ tasks:
start:
desc: Start the different validators
cmds:
- docker compose up -d
-
- docker compose up --detach --wait --wait-timeout 60

stop:
desc: Stop the different validators
cmds:
Expand Down
91 changes: 91 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# e-invoicing
[![Generic badge](https://img.shields.io/badge/Version-0.1.0-important.svg)]()
[![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

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

### Example: Creating ZUGFeRD/factur-x XML
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);
$document->exchangedDocument->id = '471102';
$document->exchangedDocument->issueDateTime = DateTime::create(102, '20200305');
// etc...
$xml = ZUGFeRDTransformer::create()->transform($invoice)
```

### 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.

```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);
```

### 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.

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

$xml = file_get_contents($exampleXmlFile);

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

// If the format is supported and valid in its structure the following check will be true
$readerResult->isSuccess()

// If the format is not supported or a different error occurred the result will have the state error.
$readerResult->isError()

// If it's valid you may retrieve the deserialized object from the dto.
// Invoking the getDocument method on an error will result in a LogicException
$document = $readerResult->getDocument();

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

You can refer to the [tests](https://github.com/easybill/e-invoicing/tree/main/tests/Integration) in this repository for examples of using this library.

## 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.

## Issues and contribution
Feel free to create Pull-Requests or Issue if you have trouble with this library or any related resource.
7 changes: 4 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "easybill/e-invoicing",
"description": "A package to read and create the formats: factur-x, PEPPOL, XRechnung (CII/UBL)",
"version": "0.1.0",
"description": "A package to read and create the formats: factur-x, Peppol BIS Billing, XRechnung (CII/UBL)",
"type": "library",
"license": "MIT",
"keywords": [
Expand All @@ -18,12 +19,12 @@
],
"autoload": {
"psr-4": {
"Easybill\\eInvoicing\\": "src/"
"easybill\\eInvoicing\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Easybill\\eInvoicingTests\\": "tests/"
"easybill\\eInvoicingTests\\": "tests/"
}
},
"authors": [
Expand Down
10 changes: 9 additions & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@ services:
image: 'easybill/zugferd-validator202309:v0.0.62'
ports:
- '8080:8080'
healthcheck:
test: curl --fail http://localhost:8080/health || exit 0
interval: 10s
retries: 6

peppol-validator:
image: 'bolzerdev/peppol-bis-billing-validator:latest'
ports:
- '8081:8080'
- '8081:8080'
healthcheck:
test: curl --fail http://localhost:8081/health || exit 0
interval: 10s
retries: 6
24 changes: 12 additions & 12 deletions src/DocumentFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

declare(strict_types=1);

namespace Easybill\eInvoicing;

use Easybill\eInvoicing\Factories\PeppolDocumentFactory;
use Easybill\eInvoicing\Factories\XRechnungDocumentFactory;
use Easybill\eInvoicing\Factories\ZUGFeRDDocumentFactory;
use Easybill\eInvoicing\Specs\Peppol\Documents\PeppolBISCredit;
use Easybill\eInvoicing\Specs\Peppol\Documents\PeppolBISInvoice;
use Easybill\eInvoicing\Specs\XRechnung\CII\Documents\XRechnungCiiInvoice;
use Easybill\eInvoicing\Specs\XRechnung\UBL\Documents\XRechnungUblCredit;
use Easybill\eInvoicing\Specs\XRechnung\UBL\Documents\XRechnungUblInvoice;
use Easybill\eInvoicing\Specs\ZUGFeRD\Documents\ZUGFeRDInvoice;
use Easybill\eInvoicing\Specs\ZUGFeRD\Enums\ZUGFeRDProfileType;
namespace easybill\eInvoicing;

use easybill\eInvoicing\Factories\PeppolDocumentFactory;
use easybill\eInvoicing\Factories\XRechnungDocumentFactory;
use easybill\eInvoicing\Factories\ZUGFeRDDocumentFactory;
use easybill\eInvoicing\Specs\Peppol\Documents\PeppolBISCredit;
use easybill\eInvoicing\Specs\Peppol\Documents\PeppolBISInvoice;
use easybill\eInvoicing\Specs\XRechnung\CII\Documents\XRechnungCiiInvoice;
use easybill\eInvoicing\Specs\XRechnung\UBL\Documents\XRechnungUblCredit;
use easybill\eInvoicing\Specs\XRechnung\UBL\Documents\XRechnungUblInvoice;
use easybill\eInvoicing\Specs\ZUGFeRD\Documents\ZUGFeRDInvoice;
use easybill\eInvoicing\Specs\ZUGFeRD\Enums\ZUGFeRDProfileType;

final class DocumentFactory
{
Expand Down
24 changes: 12 additions & 12 deletions src/DocumentXmlReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

declare(strict_types=1);

namespace Easybill\eInvoicing;

use Easybill\eInvoicing\Specs\Dtos\ReaderResult;
use Easybill\eInvoicing\Specs\Peppol\Documents\PeppolBISCredit;
use Easybill\eInvoicing\Specs\Peppol\Documents\PeppolBISInvoice;
use Easybill\eInvoicing\Specs\XRechnung\CII\Documents\XRechnungCiiInvoice;
use Easybill\eInvoicing\Specs\XRechnung\UBL\Documents\XRechnungUblCredit;
use Easybill\eInvoicing\Specs\XRechnung\UBL\Documents\XRechnungUblInvoice;
use Easybill\eInvoicing\Specs\ZUGFeRD\Documents\ZUGFeRDInvoice;
use Easybill\eInvoicingTests\Validators\Traits\ReformatXmlTrait;
namespace easybill\eInvoicing;

use easybill\eInvoicing\Dtos\ReaderResult;
use easybill\eInvoicing\Specs\Peppol\Documents\PeppolBISCredit;
use easybill\eInvoicing\Specs\Peppol\Documents\PeppolBISInvoice;
use easybill\eInvoicing\Specs\XRechnung\CII\Documents\XRechnungCiiInvoice;
use easybill\eInvoicing\Specs\XRechnung\UBL\Documents\XRechnungUblCredit;
use easybill\eInvoicing\Specs\XRechnung\UBL\Documents\XRechnungUblInvoice;
use easybill\eInvoicing\Specs\ZUGFeRD\Documents\ZUGFeRDInvoice;
use easybill\eInvoicingTests\Validators\Traits\ReformatXmlTrait;
use JMS\Serializer\SerializerBuilder;
use JMS\Serializer\SerializerInterface;

Expand Down Expand Up @@ -84,7 +84,7 @@ private function tryDeserializingCIIDocument(\DOMDocument $document): ReaderResu
if ($this->isZUGFeRD($document)) {
$document = $this->serializer->deserialize($xml, ZUGFeRDInvoice::class, 'xml');

if (!$document instanceof XRechnungCiiInvoice) {
if (!$document instanceof ZUGFeRDInvoice) {
throw new \RuntimeException('could not deserialize ZUGFeRDInvoice');
}

Expand Down Expand Up @@ -130,7 +130,7 @@ private function tryDeserializingUBLDocument(\DOMDocument $document): ReaderResu
if ($this->isUBLInvoice($document)) {
$document = $this->serializer->deserialize($xml, PeppolBISInvoice::class, 'xml');

if (!$document instanceof XRechnungUblInvoice) {
if (!$document instanceof PeppolBISInvoice) {
throw new \RuntimeException('could not deserialize PeppolBISInvoice');
}

Expand Down
12 changes: 7 additions & 5 deletions src/Specs/Dtos/ReaderResult.php → src/Dtos/ReaderResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

declare(strict_types=1);

namespace Easybill\eInvoicing\Specs\Dtos;
namespace easybill\eInvoicing\Dtos;

use Easybill\eInvoicing\Specs\Peppol\Documents\PeppolBISAbstractDocument;
use Easybill\eInvoicing\Specs\XRechnung\CII\Documents\XRechnungCiiInvoice;
use Easybill\eInvoicing\Specs\XRechnung\UBL\Documents\XRechnungUblAbstractDocument;
use Easybill\eInvoicing\Specs\ZUGFeRD\Documents\ZUGFeRDInvoice;
use easybill\eInvoicing\Specs\Peppol\Documents\PeppolBISAbstractDocument;
use easybill\eInvoicing\Specs\XRechnung\CII\Documents\XRechnungCiiInvoice;
use easybill\eInvoicing\Specs\XRechnung\UBL\Documents\XRechnungUblAbstractDocument;
use easybill\eInvoicing\Specs\ZUGFeRD\Documents\ZUGFeRDInvoice;

final class ReaderResult
{
Expand Down Expand Up @@ -41,6 +41,7 @@ public function isSuccess(): bool
return null === $this->throwable;
}

/** @throws \LogicException */
public function getError(): \Throwable
{
if (null === $this->throwable || null !== $this->document) {
Expand All @@ -50,6 +51,7 @@ public function getError(): \Throwable
return $this->throwable;
}

/** @throws \LogicException */
public function getDocument(): PeppolBISAbstractDocument|XRechnungCiiInvoice|XRechnungUblAbstractDocument|ZUGFeRDInvoice
{
if (null !== $this->throwable || null === $this->document) {
Expand Down
6 changes: 3 additions & 3 deletions src/Factories/PeppolDocumentFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

declare(strict_types=1);

namespace Easybill\eInvoicing\Factories;
namespace easybill\eInvoicing\Factories;

use Easybill\eInvoicing\Specs\Peppol\Documents\PeppolBISCredit;
use Easybill\eInvoicing\Specs\Peppol\Documents\PeppolBISInvoice;
use easybill\eInvoicing\Specs\Peppol\Documents\PeppolBISCredit;
use easybill\eInvoicing\Specs\Peppol\Documents\PeppolBISInvoice;

final class PeppolDocumentFactory
{
Expand Down
14 changes: 7 additions & 7 deletions src/Factories/XRechnungDocumentFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

declare(strict_types=1);

namespace Easybill\eInvoicing\Factories;
namespace easybill\eInvoicing\Factories;

use Easybill\eInvoicing\Specs\XRechnung\CII\Documents\XRechnungCiiInvoice;
use Easybill\eInvoicing\Specs\XRechnung\CII\Models\DocumentContextParameter;
use Easybill\eInvoicing\Specs\XRechnung\CII\Models\ExchangedDocument;
use Easybill\eInvoicing\Specs\XRechnung\CII\Models\ExchangedDocumentContext;
use Easybill\eInvoicing\Specs\XRechnung\UBL\Documents\XRechnungUblCredit;
use Easybill\eInvoicing\Specs\XRechnung\UBL\Documents\XRechnungUblInvoice;
use easybill\eInvoicing\Specs\XRechnung\CII\Documents\XRechnungCiiInvoice;
use easybill\eInvoicing\Specs\XRechnung\CII\Models\DocumentContextParameter;
use easybill\eInvoicing\Specs\XRechnung\CII\Models\ExchangedDocument;
use easybill\eInvoicing\Specs\XRechnung\CII\Models\ExchangedDocumentContext;
use easybill\eInvoicing\Specs\XRechnung\UBL\Documents\XRechnungUblCredit;
use easybill\eInvoicing\Specs\XRechnung\UBL\Documents\XRechnungUblInvoice;

final class XRechnungDocumentFactory
{
Expand Down
12 changes: 6 additions & 6 deletions src/Factories/ZUGFeRDDocumentFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

declare(strict_types=1);

namespace Easybill\eInvoicing\Factories;
namespace easybill\eInvoicing\Factories;

use Easybill\eInvoicing\Specs\ZUGFeRD\Documents\ZUGFeRDInvoice;
use Easybill\eInvoicing\Specs\ZUGFeRD\Enums\ZUGFeRDProfileType;
use Easybill\eInvoicing\Specs\ZUGFeRD\Models\DocumentContextParameter;
use Easybill\eInvoicing\Specs\ZUGFeRD\Models\ExchangedDocument;
use Easybill\eInvoicing\Specs\ZUGFeRD\Models\ExchangedDocumentContext;
use easybill\eInvoicing\Specs\ZUGFeRD\Documents\ZUGFeRDInvoice;
use easybill\eInvoicing\Specs\ZUGFeRD\Enums\ZUGFeRDProfileType;
use easybill\eInvoicing\Specs\ZUGFeRD\Models\DocumentContextParameter;
use easybill\eInvoicing\Specs\ZUGFeRD\Models\ExchangedDocument;
use easybill\eInvoicing\Specs\ZUGFeRD\Models\ExchangedDocumentContext;

final class ZUGFeRDDocumentFactory
{
Expand Down
38 changes: 19 additions & 19 deletions src/Specs/Peppol/Documents/PeppolBISAbstractDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@

declare(strict_types=1);

namespace Easybill\eInvoicing\Specs\Peppol\Documents;

use Easybill\eInvoicing\Specs\Peppol\Models\AccountingParty;
use Easybill\eInvoicing\Specs\Peppol\Models\AllowanceCharge;
use Easybill\eInvoicing\Specs\Peppol\Models\BillingReference;
use Easybill\eInvoicing\Specs\Peppol\Models\Delivery;
use Easybill\eInvoicing\Specs\Peppol\Models\DocumentReference;
use Easybill\eInvoicing\Specs\Peppol\Models\LegalMonetaryTotal;
use Easybill\eInvoicing\Specs\Peppol\Models\Note;
use Easybill\eInvoicing\Specs\Peppol\Models\OrderReference;
use Easybill\eInvoicing\Specs\Peppol\Models\Party;
use Easybill\eInvoicing\Specs\Peppol\Models\PaymentMeans;
use Easybill\eInvoicing\Specs\Peppol\Models\PaymentTerms;
use Easybill\eInvoicing\Specs\Peppol\Models\Period;
use Easybill\eInvoicing\Specs\Peppol\Models\TaxTotal;
namespace easybill\eInvoicing\Specs\Peppol\Documents;

use easybill\eInvoicing\Specs\Peppol\Models\AccountingParty;
use easybill\eInvoicing\Specs\Peppol\Models\AllowanceCharge;
use easybill\eInvoicing\Specs\Peppol\Models\BillingReference;
use easybill\eInvoicing\Specs\Peppol\Models\Delivery;
use easybill\eInvoicing\Specs\Peppol\Models\DocumentReference;
use easybill\eInvoicing\Specs\Peppol\Models\LegalMonetaryTotal;
use easybill\eInvoicing\Specs\Peppol\Models\Note;
use easybill\eInvoicing\Specs\Peppol\Models\OrderReference;
use easybill\eInvoicing\Specs\Peppol\Models\Party;
use easybill\eInvoicing\Specs\Peppol\Models\PaymentMeans;
use easybill\eInvoicing\Specs\Peppol\Models\PaymentTerms;
use easybill\eInvoicing\Specs\Peppol\Models\Period;
use easybill\eInvoicing\Specs\Peppol\Models\TaxTotal;
use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
use JMS\Serializer\Annotation\XmlElement;
Expand Down Expand Up @@ -45,7 +45,7 @@ abstract class PeppolBISAbstractDocument
public ?string $issueDate = null;

/** @var Note[] */
#[Type('array<Easybill\eInvoicing\Specs\Peppol\Models\Note>')]
#[Type('array<easybill\eInvoicing\Specs\Peppol\Models\Note>')]
#[SerializedName('Note')]
#[XmlList(entry: 'Note', inline: true, namespace: 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2')]
public array $note = [];
Expand Down Expand Up @@ -111,7 +111,7 @@ abstract class PeppolBISAbstractDocument
public ?Delivery $delivery = null;

/** @var PaymentMeans[] */
#[Type('array<Easybill\eInvoicing\Specs\Peppol\Models\PaymentMeans>')]
#[Type('array<easybill\eInvoicing\Specs\Peppol\Models\PaymentMeans>')]
#[SerializedName('PaymentMeans')]
#[XmlList(entry: 'PaymentMeans', inline: true, namespace: 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2')]
public array $paymentMeans = [];
Expand All @@ -122,13 +122,13 @@ abstract class PeppolBISAbstractDocument
public ?PaymentTerms $paymentTerms = null;

/** @var AllowanceCharge[] */
#[Type('array<Easybill\eInvoicing\Specs\Peppol\Models\AllowanceCharge>')]
#[Type('array<easybill\eInvoicing\Specs\Peppol\Models\AllowanceCharge>')]
#[SerializedName('AllowanceCharge')]
#[XmlList(entry: 'AllowanceCharge', inline: true, namespace: 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2')]
public array $allowanceCharge = [];

/** @var TaxTotal[] */
#[Type('array<Easybill\eInvoicing\Specs\Peppol\Models\TaxTotal>')]
#[Type('array<easybill\eInvoicing\Specs\Peppol\Models\TaxTotal>')]
#[SerializedName('TaxTotal')]
#[XmlList(entry: 'TaxTotal', inline: true, namespace: 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2')]
public array $taxTotal = [];
Expand Down
Loading

0 comments on commit ceb7632

Please sign in to comment.