Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: CI

on:
pull_request:

jobs:
phpunit:
name: PHPUnit (PHP ${{ matrix.php }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: ['8.1', '8.2', '8.3', '8.4', '8.5']

steps:
- uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, libxml, simplexml, mbstring, gd
coverage: none

- name: Install dependencies
run: composer install --prefer-dist --no-progress

- name: Run PHPUnit
run: composer test

phpstan:
name: PHPStan
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
extensions: dom, libxml, simplexml
coverage: none

- name: Install dependencies
run: composer install --prefer-dist --no-progress

- name: Run PHPStan
run: composer phpstan

cs-fixer:
name: PHP CS Fixer
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
extensions: dom, libxml, simplexml
coverage: none

- name: Install dependencies
run: composer install --prefer-dist --no-progress

- name: Run PHP CS Fixer
run: composer cs-check
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
/vendor/
composer.lock
.phpstan.cache
.php-cs-fixer.cache
.phpunit.cache
.phpunit.result.cache
32 changes: 32 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

$finder = (new PhpCsFixer\Finder())
->in(__DIR__)
->exclude('var')
;

return (new PhpCsFixer\Config())
->setHideProgress(true)
->setRules([
'@Symfony' => true,
'@PER-CS' => true,
'no_unused_imports' => true,
'php_unit_method_casing' => ['case' => 'snake_case'],
'global_namespace_import' => ['import_classes' => true],
'yoda_style' => [
'equal' => false,
'identical' => false,
'less_and_greater' => false,
],
'trailing_comma_in_multiline' => [
'elements' => [
'arrays',
'arguments',
'parameters',
],
],
'native_function_invocation' => false,
])
->setUsingCache(false)
->setFinder($finder)
;
23 changes: 21 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,37 @@
"name": "stann/factur-x",
"type": "library",
"require": {
"php": "^8.1",
"mpdf/mpdf": "^8.1",
"ext-libxml": "*"
"ext-libxml": "*",
"ext-simplexml": "*",
"ext-dom": "*"
},
"require-dev": {
"phpunit/phpunit": "^10.0",
"phpstan/phpstan": "^2.1",
"friendsofphp/php-cs-fixer": "^3.92"
},
"autoload": {
"psr-4": {
"Stann\\FacturX\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Stann\\FacturX\\Tests\\": "tests/"
}
},
"authors": [
{
"name": "Camille Baronnet",
"email": "git@camillebaronnet.fr"
}
]
],
"scripts": {
"test": "phpunit",
"phpstan": "phpstan analyse --memory-limit=512M",
"cs-fix": "php-cs-fixer fix",
"cs-check": "php-cs-fixer fix --dry-run --diff"
}
}
6 changes: 6 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
parameters:
level: max
paths:
- src
- tests
tmpDir: .phpstan.cache
24 changes: 24 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
cacheDirectory=".phpunit.cache"
executionOrder="depends,defects"
requireCoverageMetadata="false"
beStrictAboutCoverageMetadata="false"
beStrictAboutOutputDuringTests="true"
failOnRisky="true"
failOnWarning="true">
<testsuites>
<testsuite name="default">
<directory>tests</directory>
</testsuite>
</testsuites>

<source>
<include>
<directory>src</directory>
</include>
</source>
</phpunit>
21 changes: 9 additions & 12 deletions src/AppendixParts/ExchangedDocument.php
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
<?php

declare(strict_types=1);

namespace Stann\FacturX\AppendixParts;

use DateTimeImmutable;
use SimpleXMLElement;
use Stann\FacturX\XmlSpecifications\Namespaces;
use Stann\FacturX\XmlBuilder;

class ExchangedDocument
{
public function __construct(
private readonly string $invoiceId,
private readonly TypeCode $typeCode,
private readonly DateTimeImmutable $issuedAt,
)
{
}
) {}

public function toXml(SimpleXMLElement $element): void
public function toXml(XmlBuilder $xml): void
{
$element->addChild('ram:ID', $this->invoiceId, Namespaces::NS_RAM->value);
$element->addChild('ram:TypeCode', $this->typeCode->value, Namespaces::NS_RAM->value);
$element->addChild('ram:IssueDateTime', null, Namespaces::NS_RAM->value)
?->addChild('udt:DateTimeString', $this->issuedAt->format('Ymd'), Namespaces::NS_UDT->value)
?->addAttribute('format', '102')
;
$xml->ram('ID', $this->invoiceId);
$xml->ram('TypeCode', (string) $this->typeCode->value);
$xml->ram('IssueDateTime')
->udt('DateTimeString', $this->issuedAt->format('Ymd'))->attr('format', '102');
}
}
23 changes: 11 additions & 12 deletions src/AppendixParts/MonetarySummation.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<?php

declare(strict_types=1);

namespace Stann\FacturX\AppendixParts;

use SimpleXMLElement;
use Stann\FacturX\XmlSpecifications\Namespaces;
use Stann\FacturX\XmlBuilder;

class MonetarySummation
{
Expand All @@ -12,17 +13,15 @@ public function __construct(
private readonly float $totalAmountExcludingTaxes,
private readonly float $totalAmountIncludingTaxes,
private readonly float $duePayableAmount,
)
{
}
) {}

public function toXml(SimpleXMLElement $xml): void
public function toXml(XmlBuilder $xml): void
{
$xml->addChild('ram:InvoiceCurrencyCode', $this->currency, Namespaces::NS_RAM->value);
$summation = $xml->addChild('ram:SpecifiedTradeSettlementHeaderMonetarySummation', null, Namespaces::NS_RAM->value);
$summation?->addChild('ram:TaxBasisTotalAmount', $this->totalAmountExcludingTaxes, Namespaces::NS_RAM->value);
$summation?->addChild('ram:TaxTotalAmount', $this->totalAmountIncludingTaxes - $this->totalAmountExcludingTaxes, Namespaces::NS_RAM->value);
$summation?->addChild('ram:GrandTotalAmount', $this->totalAmountIncludingTaxes, Namespaces::NS_RAM->value);
$summation?->addChild('ram:DuePayableAmount', $this->duePayableAmount, Namespaces::NS_RAM->value);
$xml->ram('InvoiceCurrencyCode', $this->currency);
$summation = $xml->ram('SpecifiedTradeSettlementHeaderMonetarySummation');
$summation->ram('TaxBasisTotalAmount', (string) $this->totalAmountExcludingTaxes);
$summation->ram('TaxTotalAmount', (string) ($this->totalAmountIncludingTaxes - $this->totalAmountExcludingTaxes));
$summation->ram('GrandTotalAmount', (string) $this->totalAmountIncludingTaxes);
$summation->ram('DuePayableAmount', (string) $this->duePayableAmount);
}
}
37 changes: 18 additions & 19 deletions src/AppendixParts/TradeParty.php
Original file line number Diff line number Diff line change
@@ -1,43 +1,42 @@
<?php

declare(strict_types=1);

namespace Stann\FacturX\AppendixParts;

use SimpleXMLElement;
use Stann\FacturX\ValueObjects\CountryCode;
use Stann\FacturX\ValueObjects\VATNumber;
use Stann\FacturX\XmlSpecifications\Namespaces;
use Stann\FacturX\XmlBuilder;

class TradeParty
{
public function __construct(
private readonly string $legalName,
private readonly string $legalName,
/**
* For exemple in France, that's corresponding to the SIRET number.
*/
private readonly string $registrationNumber,
private readonly string $registrationNumber,
private readonly ?CountryCode $countryCode,
private readonly ?VATNumber $vatNumber,
)
{
}
private readonly ?VATNumber $vatNumber,
) {}

public function toXml(SimpleXMLElement $xml): void
public function toXml(XmlBuilder $xml): void
{
$xml->addChild('ram:Name', $this->legalName, Namespaces::NS_RAM->value);
$xml->ram('Name', $this->legalName);

if(!empty($this->registrationNumber)) {
$xml->addChild('ram:SpecifiedLegalOrganization', null, Namespaces::NS_RAM->value)
?->addChild('ram:ID', $this->registrationNumber, Namespaces::NS_RAM->value)?->addAttribute('schemeID', '0002');
if (!empty($this->registrationNumber)) {
$xml->ram('SpecifiedLegalOrganization')
->ram('ID', $this->registrationNumber)->attr('schemeID', '0002');
}

if(!empty($this->countryCode)) {
$xml->addChild('ram:PostalTradeAddress', null, Namespaces::NS_RAM->value)
?->addChild('ram:CountryID', $this->countryCode->value, Namespaces::NS_RAM->value);
if (!empty($this->countryCode)) {
$xml->ram('PostalTradeAddress')
->ram('CountryID', $this->countryCode->value);
}

if(!empty($this->vatNumber)) {
$xml->addChild('ram:SpecifiedTaxRegistration', null, Namespaces::NS_RAM->value)
?->addChild('ram:ID', $this->vatNumber->value, Namespaces::NS_RAM->value)?->addAttribute('schemeID', 'VA');
if (!empty($this->vatNumber)) {
$xml->ram('SpecifiedTaxRegistration')
->ram('ID', $this->vatNumber->value)->attr('schemeID', 'VA');
}
}
}
2 changes: 2 additions & 0 deletions src/AppendixParts/TypeCode.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace Stann\FacturX\AppendixParts;

enum TypeCode: int
Expand Down
Loading