Updates for xrechung extended validation

This commit is contained in:
David Bomba 2025-08-29 11:37:26 +10:00
parent 5258f6cf3e
commit 0897d2ec11
8 changed files with 34307 additions and 18 deletions

View File

@ -246,7 +246,7 @@ class OrderXDocument extends AbstractService
} elseif (in_array($this->document->client->country->iso_3166_2, ["ES-CE", "ES-ML"])) { } elseif (in_array($this->document->client->country->iso_3166_2, ["ES-CE", "ES-ML"])) {
$tax_type = OrderDutyTaxFeeCategories::TAX_FOR_PRODUCTION_SERVICES_AND_IMPORTATION_IN_CEUTA_AND_MELILLA; $tax_type = OrderDutyTaxFeeCategories::TAX_FOR_PRODUCTION_SERVICES_AND_IMPORTATION_IN_CEUTA_AND_MELILLA;
} else { } else {
nlog("Unkown tax case for xinvoice"); // nlog("Unkown tax case for xinvoice");
$tax_type = OrderDutyTaxFeeCategories::STANDARD_RATE; $tax_type = OrderDutyTaxFeeCategories::STANDARD_RATE;
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -104,22 +104,22 @@ class ZugferdEDocument extends AbstractService
if ($this->document->custom_surcharge1 > 0) { if ($this->document->custom_surcharge1 > 0) {
$surcharge = $this->document->uses_inclusive_taxes ? ($this->document->custom_surcharge1 / (1 + ($item["tax_rate"] / 100))) : $this->document->custom_surcharge1; $surcharge = $this->document->uses_inclusive_taxes ? ($this->document->custom_surcharge1 / (1 + ($item["tax_rate"] / 100))) : $this->document->custom_surcharge1;
$this->xdocument->addDocumentAllowanceCharge($surcharge, true, $tax_code, "VAT", $item["tax_rate"]); $this->xdocument->addDocumentAllowanceCharge($surcharge, true, $tax_code, "VAT", $item["tax_rate"],null,null,null,null,null,null, ctrans('texts.surcharge'));
} }
if ($this->document->custom_surcharge2 > 0) { if ($this->document->custom_surcharge2 > 0) {
$surcharge = $this->document->uses_inclusive_taxes ? ($this->document->custom_surcharge2 / (1 + ($item["tax_rate"] / 100))) : $this->document->custom_surcharge2; $surcharge = $this->document->uses_inclusive_taxes ? ($this->document->custom_surcharge2 / (1 + ($item["tax_rate"] / 100))) : $this->document->custom_surcharge2;
$this->xdocument->addDocumentAllowanceCharge($surcharge, true, $tax_code, "VAT", $item["tax_rate"]); $this->xdocument->addDocumentAllowanceCharge($surcharge, true, $tax_code, "VAT", $item["tax_rate"],null,null,null,null,null,null, ctrans('texts.surcharge'));
} }
if ($this->document->custom_surcharge3 > 0) { if ($this->document->custom_surcharge3 > 0) {
$surcharge = $this->document->uses_inclusive_taxes ? ($this->document->custom_surcharge3 / (1 + ($item["tax_rate"] / 100))) : $this->document->custom_surcharge3; $surcharge = $this->document->uses_inclusive_taxes ? ($this->document->custom_surcharge3 / (1 + ($item["tax_rate"] / 100))) : $this->document->custom_surcharge3;
$this->xdocument->addDocumentAllowanceCharge($surcharge, true, $tax_code, "VAT", $item["tax_rate"]); $this->xdocument->addDocumentAllowanceCharge($surcharge, true, $tax_code, "VAT", $item["tax_rate"],null,null,null,null,null,null, ctrans('texts.surcharge'));
} }
if ($this->document->custom_surcharge4 > 0) { if ($this->document->custom_surcharge4 > 0) {
$surcharge = $this->document->uses_inclusive_taxes ? ($this->document->custom_surcharge4 / (1 + ($item["tax_rate"] / 100))) : $this->document->custom_surcharge4; $surcharge = $this->document->uses_inclusive_taxes ? ($this->document->custom_surcharge4 / (1 + ($item["tax_rate"] / 100))) : $this->document->custom_surcharge4;
$this->xdocument->addDocumentAllowanceCharge($surcharge, true, $tax_code, "VAT", $item["tax_rate"]); $this->xdocument->addDocumentAllowanceCharge($surcharge, true, $tax_code, "VAT", $item["tax_rate"],null,null,null,null,null,null, ctrans('texts.surcharge'));
} }
return $this; return $this;
@ -175,7 +175,8 @@ class ZugferdEDocument extends AbstractService
false, false,
$this->tax_code, $this->tax_code,
"VAT", "VAT",
0 0,
null,null,null,null,null,null, ctrans('texts.discount')
); );
} }
@ -215,7 +216,8 @@ class ZugferdEDocument extends AbstractService
false, false,
$this->getTaxType($item["tax_id"] ?? '2'), $this->getTaxType($item["tax_id"] ?? '2'),
"VAT", "VAT",
$item["tax_rate"] $item["tax_rate"],
null,null,null,null,null,null,ctrans('texts.discount')
); );
} }
@ -270,7 +272,7 @@ class ZugferdEDocument extends AbstractService
$this->tax_code = ZugferdDutyTaxFeeCategories::EXEMPT_FROM_TAX; $this->tax_code = ZugferdDutyTaxFeeCategories::EXEMPT_FROM_TAX;
// $this->exemption_reason_code = "VATEX-EU-NOT-TAX"; // $this->exemption_reason_code = "VATEX-EU-NOT-TAX";
$this->exemption_reason_code = "VATEX-EU-O"; $this->exemption_reason_code = "VATEX-EU-O";
nlog("exemption_reason_code: {$this->exemption_reason_code}"); // nlog("exemption_reason_code: {$this->exemption_reason_code}");
} elseif ($item->tax_id == '9') { //reverse charge } elseif ($item->tax_id == '9') { //reverse charge
$this->tax_code = ZugferdDutyTaxFeeCategories::VAT_REVERSE_CHARGE; $this->tax_code = ZugferdDutyTaxFeeCategories::VAT_REVERSE_CHARGE;
$this->exemption_reason_code = "VATEX-EU-AE"; $this->exemption_reason_code = "VATEX-EU-AE";
@ -587,7 +589,7 @@ class ZugferdEDocument extends AbstractService
} elseif (in_array($this->document->client->country->iso_3166_2, ["ES-CE", "ES-ML"])) { } elseif (in_array($this->document->client->country->iso_3166_2, ["ES-CE", "ES-ML"])) {
$tax_type = ZugferdDutyTaxFeeCategories::TAX_FOR_PRODUCTION_SERVICES_AND_IMPORTATION_IN_CEUTA_AND_MELILLA; $tax_type = ZugferdDutyTaxFeeCategories::TAX_FOR_PRODUCTION_SERVICES_AND_IMPORTATION_IN_CEUTA_AND_MELILLA;
} else { } else {
nlog("Unkown tax case for xinvoice"); // nlog("Unkown tax case for xinvoice");
$tax_type = ZugferdDutyTaxFeeCategories::STANDARD_RATE; $tax_type = ZugferdDutyTaxFeeCategories::STANDARD_RATE;
} }
} }

View File

@ -350,7 +350,7 @@ class ZugferdEDokument extends AbstractService
} elseif (in_array($this->document->client->country->iso_3166_2, ["ES-CE", "ES-ML"])) { } elseif (in_array($this->document->client->country->iso_3166_2, ["ES-CE", "ES-ML"])) {
$tax_type = ZugferdDutyTaxFeeCategories::TAX_FOR_PRODUCTION_SERVICES_AND_IMPORTATION_IN_CEUTA_AND_MELILLA; $tax_type = ZugferdDutyTaxFeeCategories::TAX_FOR_PRODUCTION_SERVICES_AND_IMPORTATION_IN_CEUTA_AND_MELILLA;
} else { } else {
nlog("Unkown tax case for xinvoice"); // nlog("Unkown tax case for xinvoice");
$tax_type = ZugferdDutyTaxFeeCategories::STANDARD_RATE; $tax_type = ZugferdDutyTaxFeeCategories::STANDARD_RATE;
} }
} }

12
composer.lock generated
View File

@ -20947,16 +20947,16 @@
}, },
{ {
"name": "spatie/backtrace", "name": "spatie/backtrace",
"version": "1.8.0", "version": "1.8.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/spatie/backtrace.git", "url": "https://github.com/spatie/backtrace.git",
"reference": "1607d8870bf597fc4ad79a6945cf0b2e584c2669" "reference": "8c0f16a59ae35ec8c62d85c3c17585158f430110"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/spatie/backtrace/zipball/1607d8870bf597fc4ad79a6945cf0b2e584c2669", "url": "https://api.github.com/repos/spatie/backtrace/zipball/8c0f16a59ae35ec8c62d85c3c17585158f430110",
"reference": "1607d8870bf597fc4ad79a6945cf0b2e584c2669", "reference": "8c0f16a59ae35ec8c62d85c3c17585158f430110",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -20995,7 +20995,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/spatie/backtrace/issues", "issues": "https://github.com/spatie/backtrace/issues",
"source": "https://github.com/spatie/backtrace/tree/1.8.0" "source": "https://github.com/spatie/backtrace/tree/1.8.1"
}, },
"funding": [ "funding": [
{ {
@ -21007,7 +21007,7 @@
"type": "other" "type": "other"
} }
], ],
"time": "2025-08-25T16:16:45+00:00" "time": "2025-08-26T08:22:30+00:00"
}, },
{ {
"name": "spatie/error-solutions", "name": "spatie/error-solutions",

View File

@ -67,6 +67,10 @@ class ZugferdTest extends TestCase
]; ];
private string $zug_16931 = 'Services/EDocument/Standards/Validation/Zugferd/zugferd_16931.xslt'; private string $zug_16931 = 'Services/EDocument/Standards/Validation/Zugferd/zugferd_16931.xslt';
private string $zf_extended_wl = 'Services/EDocument/Standards/Validation/Zugferd/FACTUR-X_EXTENDED.xslt';
private string $extended_profile = 'XInvoice-Extended';
protected function setUp(): void protected function setUp(): void
{ {
@ -96,7 +100,7 @@ class ZugferdTest extends TestCase
$settings->classification = $params['company_classification'] ?? 'business'; $settings->classification = $params['company_classification'] ?? 'business';
$settings->country_id = Country::where('iso_3166_2', 'DE')->first()->id; $settings->country_id = Country::where('iso_3166_2', 'DE')->first()->id;
$settings->email = $this->faker->safeEmail(); $settings->email = $this->faker->safeEmail();
$settings->e_invoice_type = 'XInvoice_3_0'; $settings->e_invoice_type = $params['e_invoice_type'] ?? 'XInvoice_3_0';
$settings->currency_id = '3'; $settings->currency_id = '3';
$settings->name = 'Test Company'; $settings->name = 'Test Company';
$settings->address1 = 'Line 1 of address of the seller'; $settings->address1 = 'Line 1 of address of the seller';
@ -255,6 +259,66 @@ class ZugferdTest extends TestCase
$this->assertCount(0, $validator->getErrors()); $this->assertCount(0, $validator->getErrors());
}
}
public function testDeTodeTaxExemptExtendedProfile()
{
$scenario = [
'company_vat' => 'DE923356489',
'company_country' => 'DE',
'client_country' => 'DE',
'client_vat' => 'DE923356488',
'classification' => 'business',
'has_valid_vat' => true,
'over_threshold' => true,
'legal_entity_id' => 290868,
'e_invoice_type' => $this->extended_profile,
];
$data = $this->setupTestData($scenario);
$invoice = $data['invoice'];
$repo = new InvoiceRepository();
foreach($this->inclusive_scenarios as $scenario){
$invoice_data = json_decode($scenario, true);
$line_items = $invoice_data['line_items'];
foreach ($line_items as &$item) {
$item['tax_rate1'] = 0;
$item['tax_name1'] = 'VAT';
$item['tax_id'] = '5';
}
unset($item);
$invoice_data['line_items'] = array_values($line_items);
$invoice_data['uses_inclusive_taxes'] = false;
$invoice = $repo->save($invoice_data, $invoice);
$invoice = $invoice->calc()->getInvoice();
$xml = $invoice->service()->getEInvoice();
$validator = new \App\Services\EDocument\Standards\Validation\XsltDocumentValidator($xml);
$validator->setStyleSheets([$this->zf_extended_wl]);
$validator->setXsd('/Services/EDocument/Standards/Validation/Zugferd/Schema/XSD/CrossIndustryInvoice_100pD22B.xsd');
$validator->validate();
if (count($validator->getErrors()) > 0) {
nlog($invoice->withoutRelations()->toArray());
nlog($xml);
nlog($validator->getErrors());
}
$this->assertCount(0, $validator->getErrors());
} }
} }
@ -585,7 +649,8 @@ class ZugferdTest extends TestCase
{ {
$zug_16931 = 'Services/EDocument/Standards/Validation/Zugferd/zugferd_16931.xslt'; $zug_16931 = 'Services/EDocument/Standards/Validation/Zugferd/zugferd_16931.xslt';
// $xr_cii = 'Services/EDocument/Standards/Validation/Zugferd/xrechnung_cii.xslt';
// $zug_16931 = 'Services/EDocument/Standards/Validation/Zugferd/FACTUR-X_MINIMUM.xslt'; // $zug_16931 = 'Services/EDocument/Standards/Validation/Zugferd/FACTUR-X_MINIMUM.xslt';
$scenario = [ $scenario = [
@ -621,6 +686,8 @@ class ZugferdTest extends TestCase
$validator = new \App\Services\EDocument\Standards\Validation\XsltDocumentValidator($xml); $validator = new \App\Services\EDocument\Standards\Validation\XsltDocumentValidator($xml);
$validator->setStyleSheets([$this->zug_16931]); $validator->setStyleSheets([$this->zug_16931]);
$validator->setXsd('/Services/EDocument/Standards/Validation/Zugferd/Schema/XSD/CrossIndustryInvoice_100pD22B.xsd'); $validator->setXsd('/Services/EDocument/Standards/Validation/Zugferd/Schema/XSD/CrossIndustryInvoice_100pD22B.xsd');
$validator->validate(); $validator->validate();
@ -684,5 +751,399 @@ class ZugferdTest extends TestCase
} }
// ============================================================================
// EXTENDED PROFILE TEST METHODS - Duplicates using extended profile and XSLT
// ============================================================================
public function testDeToNlReverseTaxExtendedProfile()
{
$scenario = [
'company_vat' => 'DE923356489',
'company_country' => 'DE',
'client_country' => 'NL',
'client_vat' => 'NL808436332B01',
'classification' => 'business',
'has_valid_vat' => true,
'over_threshold' => true,
'legal_entity_id' => 290868,
'e_invoice_type' => $this->extended_profile,
];
$data = $this->setupTestData($scenario);
$invoice = $data['invoice'];
$repo = new InvoiceRepository();
foreach($this->inclusive_scenarios as $scenario){
$invoice_data = json_decode($scenario, true);
$line_items = $invoice_data['line_items'];
foreach ($line_items as &$item) {
$item['tax_rate1'] = 0;
$item['tax_name1'] = '';
$item['tax_id'] = '9';
}
unset($item);
$invoice_data['line_items'] = array_values($line_items);
$invoice_data['uses_inclusive_taxes'] = false;
$invoice = $repo->save($invoice_data, $invoice);
$invoice = $invoice->calc()->getInvoice();
$xml = $invoice->service()->getEInvoice();
$validator = new \App\Services\EDocument\Standards\Validation\XsltDocumentValidator($xml);
$validator->setStyleSheets([$this->zf_extended_wl]);
$validator->setXsd('/Services/EDocument/Standards/Validation/Zugferd/Schema/XSD/CrossIndustryInvoice_100pD22B.xsd');
$validator->validate();
if (count($validator->getErrors()) > 0) {
nlog($invoice->withoutRelations()->toArray());
nlog($xml);
nlog($validator->getErrors());
}
$this->assertCount(0, $validator->getErrors());
}
}
public function testInclusiveScenariosExtendedProfile()
{
$scenario = [
'company_vat' => 'DE923356489',
'company_country' => 'DE',
'client_country' => 'DE',
'client_vat' => 'DE923356488',
'classification' => 'business',
'has_valid_vat' => true,
'over_threshold' => true,
'legal_entity_id' => 290868,
'e_invoice_type' => $this->extended_profile,
];
$data = $this->setupTestData($scenario);
$invoice = $data['invoice'];
$repo = new InvoiceRepository();
foreach($this->inclusive_scenarios as $scenario){
$invoice_data = json_decode($scenario, true);
$invoice = $repo->save($invoice_data, $invoice);
$invoice = $invoice->calc()->getInvoice();
$xml = $invoice->service()->getEInvoice();
$validator = new \App\Services\EDocument\Standards\Validation\XsltDocumentValidator($xml);
$validator->setStyleSheets([$this->zf_extended_wl]);
$validator->setXsd('/Services/EDocument/Standards/Validation/Zugferd/Schema/XSD/CrossIndustryInvoice_100pD22B.xsd');
$validator->validate();
if (count($validator->getErrors()) > 0) {
nlog($invoice->withoutRelations()->toArray());
nlog($xml);
nlog($validator->getErrors());
}
$this->assertCount(0, $validator->getErrors());
}
}
public function testExclusiveScenariosExtendedProfile()
{
$scenario = [
'company_vat' => 'DE923356489',
'company_country' => 'DE',
'client_country' => 'DE',
'client_vat' => 'DE923356488',
'classification' => 'business',
'has_valid_vat' => true,
'over_threshold' => true,
'legal_entity_id' => 290868,
'e_invoice_type' => $this->extended_profile,
];
$data = $this->setupTestData($scenario);
$invoice = $data['invoice'];
$repo = new InvoiceRepository();
foreach($this->inclusive_scenarios as $scenario){
$invoice_data = json_decode($scenario, true);
$invoice_data['uses_inclusive_taxes'] = false;
$invoice = $repo->save($invoice_data, $invoice);
$invoice = $invoice->calc()->getInvoice();
$xml = $invoice->service()->getEInvoice();
$validator = new \App\Services\EDocument\Standards\Validation\XsltDocumentValidator($xml);
$validator->setStyleSheets([$this->zf_extended_wl]);
$validator->setXsd('/Services/EDocument/Standards/Validation/Zugferd/Schema/XSD/CrossIndustryInvoice_100pD22B.xsd');
$validator->validate();
if (count($validator->getErrors()) > 0) {
nlog($invoice->withoutRelations()->toArray());
nlog($xml);
nlog($validator->getErrors());
}
$this->assertCount(0, $validator->getErrors());
}
}
public function testZugFerdValidationExtendedProfile()
{
$scenario = [
'company_vat' => 'DE923356489',
'company_country' => 'DE',
'client_country' => 'DE',
'client_vat' => 'DE923356488',
'classification' => 'business',
'has_valid_vat' => true,
'over_threshold' => true,
'legal_entity_id' => 290868,
'e_invoice_type' => $this->extended_profile,
];
$data = $this->setupTestData($scenario);
$invoice = $data['invoice'];
$xml = $invoice->service()->getEInvoice();
$validator = new \App\Services\EDocument\Standards\Validation\XsltDocumentValidator($xml);
$validator->setStyleSheets([$this->zf_extended_wl]);
$validator->setXsd('/Services/EDocument/Standards/Validation/Zugferd/Schema/XSD/CrossIndustryInvoice_100pD22B.xsd');
$validator->validate();
if (count($validator->getErrors()) > 0) {
nlog($xml);
nlog($validator->getErrors());
}
$this->assertCount(0, $validator->getErrors());
}
public function testZugFerdValidationWithInclusiveTaxesExtendedProfile()
{
$scenario = [
'company_vat' => 'DE923356489',
'company_country' => 'DE',
'client_country' => 'DE',
'client_vat' => 'DE923356488',
'classification' => 'business',
'has_valid_vat' => true,
'over_threshold' => true,
'legal_entity_id' => 290868,
'e_invoice_type' => $this->extended_profile,
];
$data = $this->setupTestData($scenario);
$invoice = $data['invoice'];
$invoice->uses_inclusive_taxes = true;
$invoice = $invoice->calc()->getInvoice();
$xml = $invoice->service()->getEInvoice();
$validator = new \App\Services\EDocument\Standards\Validation\XsltDocumentValidator($xml);
$validator->setStyleSheets([$this->zf_extended_wl]);
$validator->setXsd('/Services/EDocument/Standards/Validation/Zugferd/Schema/XSD/CrossIndustryInvoice_100pD22B.xsd');
$validator->validate();
if (count($validator->getErrors()) > 0) {
nlog($xml);
nlog($validator->getErrors());
}
$this->assertCount(0, $validator->getErrors());
}
public function testZugFerdValidationWithInclusiveTaxesAndTotalAmountDiscountExtendedProfile()
{
$scenario = [
'company_vat' => 'DE923356489',
'company_country' => 'DE',
'client_country' => 'DE',
'client_vat' => 'DE923356488',
'classification' => 'business',
'has_valid_vat' => true,
'over_threshold' => true,
'legal_entity_id' => 290868,
'e_invoice_type' => $this->extended_profile,
];
$data = $this->setupTestData($scenario);
$invoice = $data['invoice'];
$invoice->uses_inclusive_taxes = true;
$invoice = $invoice->calc()->getInvoice();
$invoice->discount=20;
$invoice->is_amount_discount = true;
$xml = $invoice->service()->getEInvoice();
$validator = new \App\Services\EDocument\Standards\Validation\XsltDocumentValidator($xml);
$validator->setStyleSheets([$this->zf_extended_wl]);
$validator->setXsd('/Services/EDocument/Standards/Validation/Zugferd/Schema/XSD/CrossIndustryInvoice_100pD22B.xsd');
$validator->validate();
if (count($validator->getErrors()) > 0) {
nlog($xml);
nlog($validator->getErrors());
}
$this->assertCount(0, $validator->getErrors());
}
public function testZugFerdValidationWithInclusiveTaxesAndTotalPercentDiscountExtendedProfile()
{
$scenario = [
'company_vat' => 'DE923356489',
'company_country' => 'DE',
'client_country' => 'DE',
'client_vat' => 'DE923356488',
'classification' => 'business',
'has_valid_vat' => true,
'over_threshold' => true,
'legal_entity_id' => 290868,
'e_invoice_type' => $this->extended_profile,
];
$data = $this->setupTestData($scenario);
$invoice = $data['invoice'];
$invoice->uses_inclusive_taxes = true;
$invoice = $invoice->calc()->getInvoice();
$invoice->discount=20;
$invoice->is_amount_discount = false;
$xml = $invoice->service()->getEInvoice();
$validator = new \App\Services\EDocument\Standards\Validation\XsltDocumentValidator($xml);
$validator->setStyleSheets([$this->zf_extended_wl]);
$validator->setXsd('/Services/EDocument/Standards/Validation/Zugferd/Schema/XSD/CrossIndustryInvoice_100pD22B.xsd');
$validator->validate();
if (count($validator->getErrors()) > 0) {
nlog($xml);
nlog($validator->getErrors());
}
$this->assertCount(0, $validator->getErrors());
}
public function testZugFerdValidationWithInclusiveTaxesAndTotalPercentDiscountOnLineItemsAlsoExtendedProfile()
{
$scenario = [
'company_vat' => 'DE923356489',
'company_country' => 'DE',
'client_country' => 'DE',
'client_vat' => 'DE923356488',
'classification' => 'business',
'has_valid_vat' => true,
'over_threshold' => true,
'legal_entity_id' => 290868,
'e_invoice_type' => $this->extended_profile,
];
$data = $this->setupTestData($scenario);
$invoice = $data['invoice'];
$invoice->uses_inclusive_taxes = true;
$invoice = $invoice->calc()->getInvoice();
$invoice->discount=20;
$invoice->is_amount_discount = false;
$items = $invoice->line_items;
foreach($items as &$item){
$item->discount=10;
$item->is_amount_discount = false;
}
unset($item);
$invoice->line_items = $items;
$xml = $invoice->service()->getEInvoice();
$validator = new \App\Services\EDocument\Standards\Validation\XsltDocumentValidator($xml);
$validator->setStyleSheets([$this->zf_extended_wl]);
$validator->setXsd('/Services/EDocument/Standards/Validation/Zugferd/Schema/XSD/CrossIndustryInvoice_100pD22B.xsd');
$validator->validate();
if (count($validator->getErrors()) > 0) {
nlog($xml);
nlog($validator->getErrors());
}
$this->assertCount(0, $validator->getErrors());
}
public function testZugFerdValidationWithInclusiveTaxesAndTotalAmountDiscountOnLineItemsAlsoExtendedProfile()
{
$scenario = [
'company_vat' => 'DE923356489',
'company_country' => 'DE',
'client_country' => 'DE',
'client_vat' => 'DE923356488',
'classification' => 'business',
'has_valid_vat' => true,
'over_threshold' => true,
'legal_entity_id' => 290868,
'e_invoice_type' => $this->extended_profile,
];
$data = $this->setupTestData($scenario);
$invoice = $data['invoice'];
$invoice->uses_inclusive_taxes = true;
$invoice = $invoice->calc()->getInvoice();
$invoice->discount=20;
$invoice->is_amount_discount = true;
$items = $invoice->line_items;
foreach($items as &$item){
$item->discount=5;
$item->is_amount_discount = true;
}
unset($item);
$invoice->line_items = $items;
$xml = $invoice->service()->getEInvoice();
$validator = new \App\Services\EDocument\Standards\Validation\XsltDocumentValidator($xml);
$validator->setStyleSheets([$this->zf_extended_wl]);
$validator->setXsd('/Services/EDocument/Standards/Validation/Zugferd/Schema/XSD/CrossIndustryInvoice_100pD22B.xsd');
$validator->validate();
if (count($validator->getErrors()) > 0) {
nlog($xml);
nlog($validator->getErrors());
}
$this->assertCount(0, $validator->getErrors());
}
} }