Skip to content

Add support for Related party identification structure #168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/DTO/Creditor.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class Creditor implements RelatedPartyTypeInterface
{
private ?Address $address = null;

private ?Identification $identification = null;

public function __construct(private ?string $name)
{
}
Expand All @@ -17,6 +19,11 @@ public function setAddress(Address $address): void
$this->address = $address;
}

public function setIdentification(Identification $identification): void
{
$this->identification = $identification;
}

public function getAddress(): ?Address
{
return $this->address;
Expand All @@ -26,4 +33,9 @@ public function getName(): ?string
{
return $this->name;
}

public function getIdentification(): ?Identification
{
return $this->identification;
}
}
12 changes: 12 additions & 0 deletions src/DTO/Debtor.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class Debtor implements RelatedPartyTypeInterface
{
private ?Address $address = null;

private ?Identification $identification = null;

public function __construct(private ?string $name)
{
}
Expand All @@ -17,6 +19,11 @@ public function setAddress(Address $address): void
$this->address = $address;
}

public function setIdentification(Identification $identification): void
{
$this->identification = $identification;
}

public function getAddress(): ?Address
{
return $this->address;
Expand All @@ -26,4 +33,9 @@ public function getName(): ?string
{
return $this->name;
}

public function getIdentification(): ?Identification
{
return $this->identification;
}
}
94 changes: 94 additions & 0 deletions src/DTO/PrivateIdentification.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

declare(strict_types=1);

namespace Genkgo\Camt\DTO;

use DateTimeImmutable;

class PrivateIdentification extends Identification
{
private ?DateTimeImmutable $birthDate = null;

private ?string $provinceOfBirth = null;

private ?string $cityOfBirth = null;

private ?string $countryOfBirth = null;

private ?string $otherId = null;

private ?string $otherIssuer = null;

private ?string $otherSchemeName = null;

public function getBirthDate(): ?DateTimeImmutable
{
return $this->birthDate;
}

public function setBirthDate(?DateTimeImmutable $birthDate): void
{
$this->birthDate = $birthDate;
}

public function getProvinceOfBirth(): ?string
{
return $this->provinceOfBirth;
}

public function setProvinceOfBirth(?string $provinceOfBirth): void
{
$this->provinceOfBirth = $provinceOfBirth;
}

public function getCityOfBirth(): ?string
{
return $this->cityOfBirth;
}

public function setCityOfBirth(?string $cityOfBirth): void
{
$this->cityOfBirth = $cityOfBirth;
}

public function getCountryOfBirth(): ?string
{
return $this->countryOfBirth;
}

public function setCountryOfBirth(?string $countryOfBirth): void
{
$this->countryOfBirth = $countryOfBirth;
}

public function getOtherId(): ?string
{
return $this->otherId;
}

public function setOtherId(?string $otherId): void
{
$this->otherId = $otherId;
}

public function getOtherIssuer(): ?string
{
return $this->otherIssuer;
}

public function setOtherIssuer(?string $otherIssuer): void
{
$this->otherIssuer = $otherIssuer;
}

public function getOtherSchemeName(): ?string
{
return $this->otherSchemeName;
}

public function setOtherSchemeName(?string $otherSchemeName): void
{
$this->otherSchemeName = $otherSchemeName;
}
}
4 changes: 4 additions & 0 deletions src/DTO/RelatedPartyTypeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@ public function setAddress(Address $address): void;
public function getAddress(): ?Address;

public function getName(): ?string;

public function getIdentification(): ?Identification;

public function setIdentification(Identification $identification): void;
}
8 changes: 8 additions & 0 deletions src/Decoder/EntryTransactionDetail.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,14 @@ protected function addRelatedParty(DTO\EntryTransactionDetail $detail, SimpleXML
$relatedPartyType->setAddress(DTOFactory\Address::createFromXml($xmlPartyDetail->PstlAdr));
}

if (isset($xmlPartyDetail->Id)) {
if (isset($xmlPartyDetail->Id->PrvtId)) {
$relatedPartyType->setIdentification(DTOFactory\PrivateIdentification::createFromXml($xmlPartyDetail->Id->PrvtId));
} elseif (isset($xmlPartyDetail->Id->OrgId)) {
$relatedPartyType->setIdentification(DTOFactory\OrganisationIdentification::createFromXml($xmlPartyDetail->Id->OrgId));
}
}

$relatedParty = new RelatedParty($relatedPartyType, $this->getRelatedPartyAccount($xmlRelatedPartyTypeAccount));

$detail->addRelatedParty($relatedParty);
Expand Down
51 changes: 51 additions & 0 deletions src/Decoder/Factory/DTO/PrivateIdentification.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace Genkgo\Camt\Decoder\Factory\DTO;

use Genkgo\Camt\Decoder\Date;
use Genkgo\Camt\DTO;
use SimpleXMLElement;

class PrivateIdentification
{
public static function createFromXml(SimpleXMLElement $xmlPrivateIdentification): DTO\PrivateIdentification
{
$privateIdentification = new DTO\PrivateIdentification();
if (isset($xmlPrivateIdentification->DtAndPlcOfBirth)) {
if (isset($xmlPrivateIdentification->DtAndPlcOfBirth->BirthDt)) {
$dateDecoder = new Date();
$privateIdentification->setBirthDate($dateDecoder->decode((string) $xmlPrivateIdentification->DtAndPlcOfBirth->BirthDt));
}
if (isset($xmlPrivateIdentification->DtAndPlcOfBirth->PrvcOfBirth)) {
$privateIdentification->setProvinceOfBirth((string) $xmlPrivateIdentification->DtAndPlcOfBirth->PrvcOfBirth);
}
if (isset($xmlPrivateIdentification->DtAndPlcOfBirth->CityOfBirth)) {
$privateIdentification->setCityOfBirth((string) $xmlPrivateIdentification->DtAndPlcOfBirth->CityOfBirth);
}
if (isset($xmlPrivateIdentification->DtAndPlcOfBirth->CtryOfBirth)) {
$privateIdentification->setCountryOfBirth((string) $xmlPrivateIdentification->DtAndPlcOfBirth->CtryOfBirth);
}
}
if (isset($xmlPrivateIdentification->Othr)) {
if (isset($xmlPrivateIdentification->Othr->Id)) {
$privateIdentification->setOtherId((string) $xmlPrivateIdentification->Othr->Id);
}

if (isset($xmlPrivateIdentification->Othr->SchmeNm)) {
if (isset($xmlPrivateIdentification->Othr->SchmeNm->Cd)) {
$privateIdentification->setOtherSchemeName((string) $xmlPrivateIdentification->Othr->SchmeNm->Cd);
}
if (isset($xmlPrivateIdentification->Othr->SchmeNm->Prtry)) {
$privateIdentification->setOtherSchemeName((string) $xmlPrivateIdentification->Othr->SchmeNm->Prtry);
}
}
if (isset($xmlPrivateIdentification->Othr->Issr)) {
$privateIdentification->setOtherIssuer((string) $xmlPrivateIdentification->Othr->Issr);
}
}

return $privateIdentification;
}
}
2 changes: 2 additions & 0 deletions test/Unit/Camt053/EndToEndTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@ public function testEntries(): void
self::assertEquals('NL', $party->getRelatedPartyType()->getAddress()->getCountry());
self::assertEquals([], $party->getRelatedPartyType()->getAddress()->getAddressLines());
self::assertEquals('NL56AGDH9619008421', (string) $party->getAccount()->getIdentification());
self::assertEquals('455454654', $party->getRelatedPartyType()->getIdentification()->getOtherId());
self::assertEquals('KBO-BCE', $party->getRelatedPartyType()->getIdentification()->getOtherIssuer());
}
} elseif ($party->getRelatedPartyType() instanceof DTO\Debtor) {
if ($party->getRelatedPartyType() instanceof DTO\UltimateDebtor) {
Expand Down
18 changes: 18 additions & 0 deletions test/data/camt052.v2.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,23 @@
"getSubDepartment": null,
"getTownName": null
},
"getIdentification": {
"__CLASS__": "Genkgo\\Camt\\DTO\\OrganisationIdentification",
"getBankPartyId": null,
"getBei": null,
"getBic": null,
"getChipsUniversalId": null,
"getDuns": null,
"getEangln": null,
"getIbei": null,
"getIdentification": "455454654",
"getIssuer": null,
"getOtherId": "455454654",
"getOtherIssuer": "KBO-BCE",
"getOtherSchemeName": null,
"getOtherType": null,
"getTaxId": null
},
"getName": "Company Name"
}
},
Expand Down Expand Up @@ -166,6 +183,7 @@
"getSubDepartment": null,
"getTownName": null
},
"getIdentification": null,
"getName": "NAME NAME"
}
}
Expand Down
18 changes: 18 additions & 0 deletions test/data/camt052.v2.other-account.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,23 @@
"getSubDepartment": null,
"getTownName": null
},
"getIdentification": {
"__CLASS__": "Genkgo\\Camt\\DTO\\OrganisationIdentification",
"getBankPartyId": null,
"getBei": null,
"getBic": null,
"getChipsUniversalId": null,
"getDuns": null,
"getEangln": null,
"getIbei": null,
"getIdentification": "455454654",
"getIssuer": null,
"getOtherId": "455454654",
"getOtherIssuer": "KBO-BCE",
"getOtherSchemeName": null,
"getOtherType": null,
"getTaxId": null
},
"getName": "Company Name"
}
},
Expand Down Expand Up @@ -160,6 +177,7 @@
"getSubDepartment": null,
"getTownName": null
},
"getIdentification": null,
Copy link
Preview

Copilot AI May 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an inconsistency in how identification is represented; in some sections it is defined as an object and here as null. It would be helpful to document the conditions under which each representation is used to avoid confusion.

Copilot uses AI. Check for mistakes.

"getName": "NAME NAME"
}
}
Expand Down
2 changes: 2 additions & 0 deletions test/data/camt052.v2.with-account-name.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"getRelatedPartyType": {
"__CLASS__": "Genkgo\\Camt\\DTO\\Creditor",
"getAddress": null,
"getIdentification": null,
"getName": "Company Name"
}
},
Expand All @@ -102,6 +103,7 @@
"getRelatedPartyType": {
"__CLASS__": "Genkgo\\Camt\\DTO\\Debtor",
"getAddress": null,
"getIdentification": null,
"getName": "NAME NAME"
}
}
Expand Down
2 changes: 2 additions & 0 deletions test/data/camt052.v4.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@
"getRelatedPartyType": {
"__CLASS__": "Genkgo\\Camt\\DTO\\Creditor",
"getAddress": null,
"getIdentification": null,
"getName": "UNIFITS GmbH"
}
},
Expand Down Expand Up @@ -240,6 +241,7 @@
"getSubDepartment": null,
"getTownName": "Example Creditor Town 4 - V1"
},
"getIdentification": null,
"getName": "Example Creditor 4 - V1"
}
}
Expand Down
2 changes: 2 additions & 0 deletions test/data/camt052.v6.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@
"getRelatedPartyType": {
"__CLASS__": "Genkgo\\Camt\\DTO\\Creditor",
"getAddress": null,
"getIdentification": null,
"getName": "UNIFITS GmbH"
}
},
Expand Down Expand Up @@ -240,6 +241,7 @@
"getSubDepartment": null,
"getTownName": "Example Creditor Town 6 - V1"
},
"getIdentification": null,
"getName": "Example Creditor 6 - V1"
}
}
Expand Down
1 change: 1 addition & 0 deletions test/data/camt053.v2.all-balance-types.json
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@
"getSubDepartment": null,
"getTownName": null
},
"getIdentification": null,
"getName": "Company Name"
}
}
Expand Down
1 change: 1 addition & 0 deletions test/data/camt053.v2.five.decimals.json
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@
"getSubDepartment": null,
"getTownName": null
},
"getIdentification": null,
"getName": "Company Name"
}
}
Expand Down
Loading