From 0fbb07afe1802e8fd0b82a25a8194ec5986526fe Mon Sep 17 00:00:00 2001 From: Jasper Briers Date: Sat, 10 Jan 2026 12:27:55 +0100 Subject: [PATCH] Improve retrieving cac:PayeeParty The PayeeParty structure differs from the Party model, so a dedicated class is required. --- src/Invoice.php | 8 +- src/LegalEntity.php | 15 +++ src/PayeeParty.php | 185 ++++++++++++++++++++++++++++++++++ src/Reader.php | 2 +- tests/Read/PayeePartyTest.php | 112 ++++++++++++++++++++ 5 files changed, 317 insertions(+), 5 deletions(-) create mode 100644 src/PayeeParty.php create mode 100644 tests/Read/PayeePartyTest.php diff --git a/src/Invoice.php b/src/Invoice.php index 141d9d9..123fb61 100644 --- a/src/Invoice.php +++ b/src/Invoice.php @@ -311,18 +311,18 @@ public function setAccountingCustomerPartyContact( } /** - * @return Party + * @return PayeeParty */ - public function getPayeeParty(): ?Party + public function getPayeeParty(): ?PayeeParty { return $this->payeeParty; } /** - * @param Party $payeeParty + * @param PayeeParty $payeeParty * @return static */ - public function setPayeeParty(?Party $payeeParty) + public function setPayeeParty(?PayeeParty $payeeParty) { $this->payeeParty = $payeeParty; return $this; diff --git a/src/LegalEntity.php b/src/LegalEntity.php index be84ff8..28bfe96 100644 --- a/src/LegalEntity.php +++ b/src/LegalEntity.php @@ -57,6 +57,21 @@ public function setCompanyId(?string $companyId, $attributes = null) } return $this; } + /** + * @return array|null + */ + public function getCompanyIdAttributes(): ?array + { + return $this->companyIdAttributes; + } + + /** + * @return string|null + */ + public function getCompanyIdSchemeId(): ?string + { + return $this->companyIdAttributes['schemeID'] ?? null; + } /** * diff --git a/src/PayeeParty.php b/src/PayeeParty.php new file mode 100644 index 0000000..ae3bfd0 --- /dev/null +++ b/src/PayeeParty.php @@ -0,0 +1,185 @@ +partyIdentificationId; + } + + /** + * @param string|null $partyIdentificationId + * @return static + */ + public function setPartyIdentificationId(?string $partyIdentificationId) + { + $this->partyIdentificationId = $partyIdentificationId; + return $this; + } + + /** + * @return string + */ + public function getPartyIdentificationSchemeId(): ?string + { + return $this->partyIdentificationSchemeId; + } + + /** + * @param string|null $partyIdentificationSchemeId + * @return static + */ + public function setPartyIdentificationSchemeId(?string $partyIdentificationSchemeId) + { + $this->partyIdentificationSchemeId = $partyIdentificationSchemeId; + return $this; + } + + /** + * @return string + */ + public function getPartyName(): ?string + { + return $this->partyName; + } + + /** + * @param string|null $partyName + * + * @return static + */ + public function setPartyName(?string $partyName) + { + $this->partyName = $partyName; + return $this; + } + + /** + * @return string + */ + public function getPartyLegalEntityCompanyId(): ?string + { + return $this->partyLegalEntityCompanyId; + } + + /** + * @param string|null $partyLegalEntityCompanyId + * @return static + */ + public function setPartyLegalEntityCompanyId(?string $partyLegalEntityCompanyId) + { + $this->partyLegalEntityCompanyId = $partyLegalEntityCompanyId; + return $this; + } + + /** + * @return string + */ + public function getPartyLegalEntityCompanySchemeId(): ?string + { + return $this->partyLegalEntityCompanySchemeId; + } + + /** + * @param string|null $partyLegalEntityCompanySchemeId + * @return static + */ + public function setPartyLegalEntityCompanySchemeId(?string $partyLegalEntityCompanySchemeId) + { + $this->partyLegalEntityCompanySchemeId = $partyLegalEntityCompanySchemeId; + return $this; + } + + /** + * The xmlSerialize method is called during xml writing. + * + * @param Writer $writer + * @return void + */ + public function xmlSerialize(Writer $writer): void + { + if ($this->partyIdentificationId !== null) { + $partyIdentificationAttributes = []; + + if (!empty($this->getPartyIdentificationSchemeId())) { + $partyIdentificationAttributes['schemeID'] = $this->getPartyIdentificationSchemeId(); + } + + $writer->write([ + Schema::CAC . 'PartyIdentification' => [ + [ + 'name' => Schema::CBC . 'ID', + 'value' => $this->partyIdentificationId, + 'attributes' => $partyIdentificationAttributes + ] + ], + ]); + } + if ($this->partyName !== null) { + $writer->write([ + Schema::CAC . 'PartyName' => [ + Schema::CBC . 'Name' => $this->partyName + ], + ]); + } + if ($this->partyLegalEntityCompanyId !== null) { + $writer->write([ + Schema::CAC . 'PartyLegalEntity' => [ + Schema::CBC . 'CompanyID' => $this->partyLegalEntityCompanyId + ], + ]); + } + } + + /** + * The xmlDeserialize method is called during xml reading. + * @param Reader $reader + * @return static + */ + public static function xmlDeserialize(Reader $reader) + { + $mixedContent = mixedContent($reader); + $collection = new ArrayCollection($mixedContent); + + $partyIdentification = ReaderHelper::getTag(Schema::CAC . 'PartyIdentification', $collection); + $partyIdentificationId = ReaderHelper::getTag(Schema::CBC . 'ID', new ArrayCollection($partyIdentification['value'] ?? [])); + + $partyName = ReaderHelper::getTag(Schema::CAC . 'PartyName', $collection); + $partyNameName = ReaderHelper::getTag(Schema::CBC . 'Name', new ArrayCollection($partyName['value'] ?? [])); + + $partyLegalEntity = ReaderHelper::getTag(Schema::CAC . 'PartyLegalEntity', $collection); + $partyLegalEntityValue = $partyLegalEntity['value'] ?? null; + $partyLegalEntityCompanyId = null; + $partyLegalEntityCompanySchemeId = null; + if ($partyLegalEntityValue instanceof LegalEntity) { + $partyLegalEntityCompanyId = ['value' => $partyLegalEntityValue->getCompanyId()]; + $partyLegalEntityCompanySchemeId = $partyLegalEntityValue->getCompanyIdSchemeId(); + } + + return (new static()) + ->setPartyIdentificationId($partyIdentificationId['value'] ?? null) + ->setPartyIdentificationSchemeId($partyIdentificationId['attributes']['schemeID'] ?? null) + ->setPartyName($partyNameName['value'] ?? null) + ->setPartyLegalEntityCompanyId($partyLegalEntityCompanyId['value'] ?? null) + ->setPartyLegalEntityCompanySchemeId($partyLegalEntityCompanySchemeId); + } +} diff --git a/src/Reader.php b/src/Reader.php index 2ec38e4..f54339a 100644 --- a/src/Reader.php +++ b/src/Reader.php @@ -54,7 +54,7 @@ public static function ubl($currencyId = 'EUR'): Service Schema::CAC. 'PartyTaxScheme' => fn ($reader) => PartyTaxScheme::xmlDeserialize($reader), Schema::CAC. 'OriginatorDocumentReference' => fn ($reader) => OriginatorDocumentReference::xmlDeserialize($reader), Schema::CAC. 'PayeeFinancialAccount' => fn ($reader) => PayeeFinancialAccount::xmlDeserialize($reader), - Schema::CAC. 'PayeeParty' => fn ($reader) => Party::xmlDeserialize($reader), + Schema::CAC. 'PayeeParty' => fn ($reader) => PayeeParty::xmlDeserialize($reader), Schema::CAC. 'PaymentMandate' => fn ($reader) => PaymentMandate::xmlDeserialize($reader), Schema::CAC. 'PaymentMeans' => fn ($reader) => PaymentMeans::xmlDeserialize($reader), Schema::CAC. 'PaymentTerms' => fn ($reader) => PaymentTerms::xmlDeserialize($reader), diff --git a/tests/Read/PayeePartyTest.php b/tests/Read/PayeePartyTest.php new file mode 100644 index 0000000..d8896a1 --- /dev/null +++ b/tests/Read/PayeePartyTest.php @@ -0,0 +1,112 @@ + + + 2.1 + 123 + 2024-01-01 + 380 + EUR + + + + Main Street 123 + Building A + Copenhagen + 1000 + + 3rd Floor + + + Suite 5 + + + DK + + + + + + + + Customer Street + Amsterdam + 1000 + + NL + + + + + + + 098740918237 + + + Ebeneser Scrooge Inc. + + + 6411982340 + + + + 0 + + + 100 + + + 1 + 1 + 100 + + +XML; + + $ublReader = \NumNum\UBL\Reader::ubl(); + $invoice = $ublReader->parse($xml); + + $this->assertInstanceOf(Invoice::class, $invoice); + + // Get the payee party + $payeeParty = $invoice->getPayeeParty(); + + $this->assertInstanceOf(PayeeParty::class, $payeeParty); + + // Get the payee party identification + $identification = $payeeParty->getPartyIdentificationId(); + $identificationScheme = $payeeParty->getPartyIdentificationSchemeId(); + + $this->assertEquals('098740918237', $identification); + $this->assertEquals('GLN', $identificationScheme); + + // Get the payee party name + $partyName = $payeeParty->getPartyName(); + + $this->assertEquals('Ebeneser Scrooge Inc.', $partyName); + + // Get the payee party legal entity company + $legalEntityCompany = $payeeParty->getPartyLegalEntityCompanyId(); + $legalEntityCompanyScheme = $payeeParty->getPartyLegalEntityCompanySchemeId(); + + $this->assertEquals('6411982340', $legalEntityCompany); + $this->assertEquals('UK:CH', $legalEntityCompanyScheme); + } +}