diff --git a/src/Invoice.php b/src/Invoice.php
index d83da5f..db624b1 100644
--- a/src/Invoice.php
+++ b/src/Invoice.php
@@ -36,6 +36,7 @@ class Invoice {
protected $purchaseOrderReference = null;
protected $salesOrderReference = null;
protected $tenderOrLotReference = null;
+ protected $contractReference = null;
protected $paidAmount = 0;
protected $roundingAmount = 0;
protected $seller = null;
@@ -354,6 +355,26 @@ public function setTenderOrLotReference(?string $tenderOrLotReference): self {
}
+ /**
+ * Get contract reference
+ * @return string|null Contract reference
+ */
+ public function getContractReference(): ?string {
+ return $this->contractReference;
+ }
+
+
+ /**
+ * Set contract reference
+ * @param string|null $contractReference Contract reference
+ * @return self Invoice instance
+ */
+ public function setContractReference(?string $contractReference): self {
+ $this->contractReference = $contractReference;
+ return $this;
+ }
+
+
/**
* Get invoice prepaid amount
* NOTE: may be rounded according to the CIUS specification
diff --git a/src/Party.php b/src/Party.php
index 9635f1c..a945bcf 100644
--- a/src/Party.php
+++ b/src/Party.php
@@ -10,6 +10,7 @@ class Party {
protected $tradingName = null;
protected $companyId = null;
protected $vatNumber = null;
+ protected $taxRegistrationId = null;
protected $contactName = null;
protected $contactPhone = null;
protected $contactEmail = null;
@@ -117,6 +118,26 @@ public function setVatNumber(?string $vatNumber): self {
}
+ /**
+ * Get tax registration ID
+ * @return Identifier|null Tax registration ID
+ */
+ public function getTaxRegistrationId(): ?Identifier {
+ return $this->taxRegistrationId;
+ }
+
+
+ /**
+ * Set tax registration ID
+ * @param Identifier|null $taxRegistrationId Tax registration ID
+ * @return self Party instance
+ */
+ public function setTaxRegistrationId(?Identifier $taxRegistrationId): self {
+ $this->taxRegistrationId = $taxRegistrationId;
+ return $this;
+ }
+
+
/**
* Get contact point name
* @return string|null Contact name
diff --git a/src/Readers/UblReader.php b/src/Readers/UblReader.php
index ce33d32..6be4ba3 100644
--- a/src/Readers/UblReader.php
+++ b/src/Readers/UblReader.php
@@ -163,6 +163,12 @@ public function import(string $document): Invoice {
$invoice->setTenderOrLotReference($tenderOrLotReferenceNode->asText());
}
+ // BT-12: Contract reference
+ $contractReferenceNode = $xml->get("{{$cac}}ContractDocumentReference/{{$cbc}}ID");
+ if ($contractReferenceNode !== null) {
+ $invoice->setContractReference($contractReferenceNode->asText());
+ }
+
// BG-24: Attachment nodes
foreach ($xml->getAll("{{$cac}}AdditionalDocumentReference") as $node) {
$invoice->addAttachment($this->parseAttachmentNode($node));
@@ -338,10 +344,20 @@ private function parseSellerOrBuyerNode(UXML $xml): Party {
$this->parsePostalAddressFields($addressNode, $party);
}
- // VAT number
- $vatNumberNode = $xml->get("{{$cac}}PartyTaxScheme/{{$cbc}}CompanyID");
- if ($vatNumberNode !== null) {
- $party->setVatNumber($vatNumberNode->asText());
+ // VAT number and tax registration identifier
+ foreach ($xml->getAll("{{$cac}}PartyTaxScheme") as $taxNode) {
+ $companyIdNode = $taxNode->get("{{$cbc}}CompanyID");
+ if ($companyIdNode === null) continue;
+ $companyId = $companyIdNode->asText();
+
+ $taxSchemeNode = $taxNode->get("{{$cac}}TaxScheme/{{$cbc}}ID");
+ $taxScheme = ($taxSchemeNode === null) ? null : $taxSchemeNode->asText();
+
+ if ($taxScheme === "VAT") {
+ $party->setVatNumber($companyId);
+ } else {
+ $party->setTaxRegistrationId(new Identifier($companyId, $taxScheme));
+ }
}
// Legal name
diff --git a/src/Writers/UblWriter.php b/src/Writers/UblWriter.php
index fb31768..d35efcc 100644
--- a/src/Writers/UblWriter.php
+++ b/src/Writers/UblWriter.php
@@ -112,6 +112,12 @@ public function export(Invoice $invoice): string {
$xml->add('cac:OriginatorDocumentReference')->add('cbc:ID', $tenderOrLotReference);
}
+ // BT-12: Contract reference
+ $contractReference = $invoice->getContractReference();
+ if ($contractReference !== null) {
+ $xml->add('cac:ContractDocumentReference')->add('cbc:ID', $contractReference);
+ }
+
// BG-24: Attachments node
foreach ($invoice->getAttachments() as $attachment) {
$this->addAttachmentNode($xml, $attachment);
@@ -373,6 +379,17 @@ private function addSellerOrBuyerNode(UXML $parent, Party $party) {
$taxNode->add('cac:TaxScheme')->add('cbc:ID', 'VAT');
}
+ // Tax registration identifier
+ $taxRegistrationId = $party->getTaxRegistrationId();
+ if ($taxRegistrationId !== null) {
+ $taxRegistrationNode = $xml->add('cac:PartyTaxScheme');
+ $taxRegistrationNode->add('cbc:CompanyID', $taxRegistrationId->getValue());
+ $taxRegistrationScheme = $taxRegistrationId->getScheme();
+ if ($taxRegistrationScheme !== null) {
+ $taxRegistrationNode->add('cac:TaxScheme')->add('cbc:ID', $taxRegistrationScheme);
+ }
+ }
+
// Initial legal entity node
$legalEntityNode = $xml->add('cac:PartyLegalEntity');
diff --git a/tests/Integration/peppol-allowance.xml b/tests/Integration/peppol-allowance.xml
index 2fe6b63..ccec97a 100644
--- a/tests/Integration/peppol-allowance.xml
+++ b/tests/Integration/peppol-allowance.xml
@@ -42,6 +42,12 @@
VAT
+
+ SE555555555501
+
+ TAX
+
+
SupplierOfficialName Ltd
GB983294
diff --git a/tests/Integration/peppol-base.xml b/tests/Integration/peppol-base.xml
index 14a6ed0..f4110b7 100644
--- a/tests/Integration/peppol-base.xml
+++ b/tests/Integration/peppol-base.xml
@@ -29,6 +29,9 @@
PPID-123
+
+ 123Contractref
+
INV-123
130
diff --git a/tests/Writers/UblWriterTest.php b/tests/Writers/UblWriterTest.php
index 31a73ee..b3190e6 100644
--- a/tests/Writers/UblWriterTest.php
+++ b/tests/Writers/UblWriterTest.php
@@ -73,6 +73,7 @@ private function getSampleInvoice(): Invoice {
->setBuyerReference('REF-0172637')
->addPrecedingInvoiceReference(new InvoiceReference('INV-123'))
->setTenderOrLotReference('PPID-123')
+ ->setContractReference('123Contractref')
->setSeller($seller)
->setBuyer($buyer)
->addLine($complexLine)