adawolfa / isdoc
ISDOC parser and generator.
Installs: 15 255
Dependents: 0
Suggesters: 0
Security: 0
Stars: 6
Watchers: 1
Forks: 1
Open Issues: 0
pkg:composer/adawolfa/isdoc
Requires
- php: >=8.0
- ext-bcmath: *
- ext-simplexml: *
- ext-zip: *
- nette/utils: ^3.2|^4.0
- symfony/serializer: ^5.4|^6.0|^7.0
Requires (Dev)
- goetas-webservices/xsd-reader: ^0.3|^0.4
- nette/php-generator: ^3.6|^4.0
- phpstan/phpstan: ^1.12
- phpunit/phpunit: ^9.5|^10.0|^11.0
- symfony/console: ^5.4|^6.0|^7.0
README
This is a PHP library for parsing and generating ISDOC files.
Installation
composer require adawolfa/isdoc
Reading files
$manager = Adawolfa\ISDOC\Manager::create(); $invoice = $manager->reader->file('filename.isdoc'); print $invoice->id; foreach ($invoice->invoiceLines as $invoiceLine) { print $invoiceLine->note->content; }
By default, files are deserialized into Adawolfa\ISDOC\Schema\Invoice
. All code in that namespace is automatically generated from the official XSD schema. You can extend the base Invoice
class and map your or your vendor's extensions.
use Adawolfa\ISDOC\Map; class MyInvoice extends Adawolfa\ISDOC\Schema\Invoice { #[Map('Extensions')] private ?MyExtensions $extensions; } class MyExtensions { #[Map('CustomElement')] private string $customElement; } $invoice = $manager->reader->file('filename.isdoc', MyInvoice::class);
Writing files
You should use the decorated Adawolfa\ISDOC\Invoice
class when creating ISDOC files, as the constructor is more sane and with reasonable defaults. It also takes care of some of the summary fields.
$invoice = new ISDOC\Invoice( '12345', '00000000-0000-0000-0000-000000001234', DateTimeImmutable::createFromFormat('Y-m-d', '2021-08-16'), false, 'CZK', new ISDOC\Schema\Invoice\AccountingSupplierParty( new ISDOC\Schema\Invoice\Party( new ISDOC\Schema\Invoice\PartyIdentification('12345678'), new ISDOC\Schema\Invoice\PartyName('Firma, a. s.'), new ISDOC\Schema\Invoice\PostalAddress( 'Dlouhá', '1234', 'Praha', '100 01', new ISDOC\Schema\Invoice\Country('CZ', 'Česká republika') ) ) ) ); $invoice->invoiceLines->add( new ISDOC\Schema\Invoice\InvoiceLine('1', '100.0', '121.0', '21.0', '100.0', '121.0', new ISDOC\Schema\Invoice\ClassifiedTaxCategory( '21', ISDOC\Schema\Invoice\ClassifiedTaxCategory::VAT_CALCULATION_METHOD_FROM_THE_TOP, ), ) ); $manager->writer->file($invoice, 'filename.isdoc');
ISDOCX
ISDOCX files are supported. Either use the .isdocx
extension or specify the file format when reading/writing.
$invoice = $manager->reader->file('filename.isdocx', ISDOC\Schema\Invoice::class, $manager::FORMAT_ISDOCX); $manager->writer->file('filename.isdocx', $manager::FORMAT_ISDOCX);
Attachments (a.k.a. supplements) are supported out of box. When generating an ISDOCX file, use Adawolfa\ISDOC\Invoice\Supplement
:
$supplement = Adawolfa\ISDOC\Invoice\Supplement::fromPath('attachment.pdf'); $invoice->supplementsList->add($supplement);
Digest will be computed and appended automatically (SHA1, no other algorithms are supported as of now).
When reading, a different subclass is being used:
foreach ($invoice->supplementsList as $supplement) { if ($supplement instanceof Adawolfa\ISDOC\X\Supplement) { if (!$supplement->ok) { throw new Exception('Digest failed.'); } $supplement->saveTo("supplements/{$supplement->filename}"); } }
FAQ
I have a non-conforming ISDOC file that's missing a required value.
You might encounter an exception like this:
Fatal error: Uncaught Adawolfa\ISDOC\Data\ValueException: Value VATApplicable is missing.
By default, the decoder hydrates (that is, decodes and assigns) all declared properties unless they are not present in the ISDOC file and have a default value. Some values are always supposed to be there, but sometimes they simply aren't because of an incomplete implementation on the issuing side.
One way to get around this is to enable the relaxed hydration mode, which causes the hydrator simply skip such properties.
$manager = Adawolfa\ISDOC\Manager::create($skipMissingPrimitiveValuesHydration = true); $invoice = $manager->reader->file('filename.isdoc');
Do note, however, that such an object might have uninitialized properties, causing issues later on.
I have an international ISDOC file with multiple party tax schemes.
Due to previous implementation mistake, the library only supports a single PartyTaxScheme
per Party
, manifesting in the following error:
Value Party/PartyTaxScheme/CompanyID is missing.
Currently, the only workaround is to specify the tax scheme you're interested in ahead of time. Individual tax schemes are identified using the TaxScheme
element, usually containing VAT
for Czech invoices and TIN
for Slovak ones.
// Reading Slovakian identifier. $manager = Adawolfa\ISDOC\Manager::create(false, $preferredTaxScheme = 'TIN'); $invoice = $manager->reader->file('filename.isdoc'); $invoice->getAccountingSupplierParty()->getParty()->getPartyTaxScheme()?->getCompanyID();
By default, the first tax scheme is being used.