@@ -310,6 +310,7 @@ public static function generatePdf(Invoice $invoice): string {
310
310
311
311
/**
312
312
* Generate invoice XML (EN16931 conform), save it and return path/filename
313
+ * @see https://validator.invoice-portal.de for validation check
313
314
*
314
315
* @param Invoice $invoice Record to export
315
316
* @return string
@@ -430,8 +431,12 @@ public static function generateEn16931Xml(Invoice $invoice): string {
430
431
$ x ->text ($ invoice ->vat );
431
432
$ x ->endElement ();
432
433
$ x ->startElement ('cac:TaxCategory ' );
433
- $ x ->writeElement ('cbc:ID ' , 'S ' );
434
- $ x ->writeElement ('cbc:Percent ' , $ invoice ->vat_rate *100 );
434
+ // See https://developer.vertexinc.com/einvoicing/docs/en-16931-tax-categories
435
+ $ x ->writeElement ('cbc:ID ' , $ invoice ->taxable ? 'S ' : 'G ' );
436
+ $ x ->writeElement ('cbc:Percent ' , $ invoice ->taxable ? $ invoice ->vat_rate *100 : 0 );
437
+ if (!$ invoice ->taxable ) {
438
+ $ x ->writeElement ('cbc:TaxExemptionReasonCode ' , 'VATEX-EU-G ' );
439
+ }
435
440
$ x ->startElement ('cac:TaxScheme ' );
436
441
$ x ->writeElement ('cbc:ID ' , 'VAT ' );
437
442
$ x ->endElement ();
@@ -477,8 +482,8 @@ public static function generateEn16931Xml(Invoice $invoice): string {
477
482
$ x ->writeElement ('cbc:Description ' , $ position ->description );
478
483
$ x ->writeElement ('cbc:Name ' , trans_choice ('position ' , 1 , locale: $ lang ));
479
484
$ x ->startElement ('cac:ClassifiedTaxCategory ' );
480
- $ x ->writeElement ('cbc:ID ' , ' S ' );
481
- $ x ->writeElement ('cbc:Percent ' , $ invoice ->vat_rate *100 );
485
+ $ x ->writeElement ('cbc:ID ' , $ invoice -> taxable ? ' S ' : ' G ' );
486
+ $ x ->writeElement ('cbc:Percent ' , $ invoice ->taxable ? $ invoice -> vat_rate *100 : 0 );
482
487
$ x ->startElement ('cac:TaxScheme ' );
483
488
$ x ->writeElement ('cbc:ID ' , 'VAT ' );
484
489
$ x ->endElement ();
0 commit comments