genkgo /
camt
| 1 | <?php |
||
| 2 | |||
| 3 | declare(strict_types=1); |
||
| 4 | |||
| 5 | namespace Genkgo\Camt\Decoder; |
||
| 6 | |||
| 7 | use Genkgo\Camt\Decoder\Factory\DTO as DTOFactory; |
||
| 8 | use Genkgo\Camt\DTO; |
||
| 9 | use Genkgo\Camt\DTO\RelatedParty; |
||
| 10 | use Genkgo\Camt\DTO\RelatedPartyTypeInterface; |
||
| 11 | use Genkgo\Camt\Util\MoneyFactory; |
||
| 12 | use SimpleXMLElement; |
||
| 13 | |||
| 14 | abstract class EntryTransactionDetail |
||
| 15 | { |
||
| 16 | private DateDecoderInterface $dateDecoder; |
||
| 17 | |||
| 18 | private MoneyFactory $moneyFactory; |
||
| 19 | |||
| 20 | /** |
||
| 21 | * EntryTransactionDetail constructor. |
||
| 22 | */ |
||
| 23 | public function __construct(DateDecoderInterface $dateDecoder) |
||
| 24 | { |
||
| 25 | 40 | $this->dateDecoder = $dateDecoder; |
|
| 26 | $this->moneyFactory = new MoneyFactory(); |
||
| 27 | 40 | } |
|
| 28 | 40 | ||
| 29 | public function addReference(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
||
| 30 | 24 | { |
|
| 31 | if (false === isset($xmlDetail->Refs)) { |
||
| 32 | 24 | return; |
|
| 33 | 8 | } |
|
| 34 | |||
| 35 | $refs = $xmlDetail->Refs; |
||
| 36 | 19 | $reference = new DTO\Reference(); |
|
| 37 | 19 | ||
| 38 | $reference->setMessageId(isset($refs->MsgId) ? (string) $refs->MsgId : null); |
||
| 39 | 19 | $reference->setAccountServicerReference(isset($refs->AcctSvcrRef) ? (string) $refs->AcctSvcrRef : null); |
|
| 40 | 19 | $reference->setPaymentInformationId(isset($refs->PmtInfId) ? (string) $refs->PmtInfId : null); |
|
| 41 | 19 | $reference->setInstructionId(isset($refs->InstrId) ? (string) $refs->InstrId : null); |
|
| 42 | 19 | $reference->setEndToEndId(isset($refs->EndToEndId) ? (string) $refs->EndToEndId : null); |
|
| 43 | 19 | $reference->setUuidEndToEndReference(isset($refs->UETR) ? (string) $refs->UETR : null); |
|
| 44 | 19 | $reference->setTransactionId(isset($refs->TxId) ? (string) $refs->TxId : null); |
|
| 45 | 19 | $reference->setMandateId(isset($refs->MndtId) ? (string) $refs->MndtId : null); |
|
| 46 | 19 | $reference->setChequeNumber(isset($refs->ChqNb) ? (string) $refs->ChqNb : null); |
|
| 47 | 19 | $reference->setClearingSystemReference(isset($refs->ClrSysRef) ? (string) $refs->ClrSysRef : null); |
|
| 48 | 19 | $reference->setAccountOwnerTransactionId(isset($refs->AcctOwnrTxId) ? (string) $refs->AcctOwnrTxId : null); |
|
| 49 | 19 | $reference->setAccountServicerTransactionId(isset($refs->AcctSvcrTxId) ? (string) $refs->AcctSvcrTxId : null); |
|
| 50 | 19 | $reference->setMarketInfrastructureTransactionId(isset($refs->MktInfrstrctrTxId) ? (string) $refs->MktInfrstrctrTxId : null); |
|
| 51 | 19 | $reference->setProcessingId(isset($refs->PrcgId) ? (string) $refs->PrcgId : null); |
|
| 52 | |||
| 53 | 19 | foreach ($refs->Prtry as $xmlProprietary) { |
|
| 54 | 9 | $type = isset($xmlProprietary->Tp) ? (string) $xmlProprietary->Tp : null; |
|
| 55 | 9 | $subReference = isset($xmlProprietary->Ref) ? (string) $xmlProprietary->Ref : null; |
|
| 56 | |||
| 57 | 9 | $reference->addProprietary(new DTO\ProprietaryReference($type, $subReference)); |
|
| 58 | } |
||
| 59 | |||
| 60 | 19 | $detail->setReference($reference); |
|
| 61 | 19 | } |
|
| 62 | |||
| 63 | 24 | public function addRelatedParties(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
|
| 64 | { |
||
| 65 | 24 | if (false === isset($xmlDetail->RltdPties)) { |
|
| 66 | 1 | return; |
|
| 67 | } |
||
| 68 | |||
| 69 | /** @var SimpleXMLElement $xmlRelatedParty */ |
||
| 70 | 23 | foreach ($xmlDetail->RltdPties as $xmlRelatedParty) { |
|
| 71 | 23 | if (isset($xmlRelatedParty->Cdtr)) { |
|
| 72 | 23 | $xmlRelatedPartyType = $xmlRelatedParty->Cdtr; |
|
| 73 | 23 | $xmlRelatedPartyTypeAccount = $xmlRelatedParty->CdtrAcct; |
|
| 74 | 23 | ||
| 75 | 23 | $this->addRelatedParty($detail, $xmlRelatedPartyType, DTO\Creditor::class, $xmlRelatedPartyTypeAccount); |
|
| 76 | } |
||
| 77 | 23 | ||
| 78 | if (isset($xmlRelatedParty->UltmtCdtr)) { |
||
| 79 | $xmlRelatedPartyType = $xmlRelatedParty->UltmtCdtr; |
||
| 80 | 23 | ||
| 81 | 5 | $this->addRelatedParty($detail, $xmlRelatedPartyType, DTO\UltimateCreditor::class); |
|
| 82 | 5 | } |
|
| 83 | 5 | ||
| 84 | if (isset($xmlRelatedParty->Dbtr)) { |
||
| 85 | 5 | $xmlRelatedPartyType = $xmlRelatedParty->Dbtr; |
|
| 86 | $xmlRelatedPartyTypeAccount = $xmlRelatedParty->DbtrAcct; |
||
| 87 | |||
| 88 | 23 | $this->addRelatedParty($detail, $xmlRelatedPartyType, DTO\Debtor::class, $xmlRelatedPartyTypeAccount); |
|
| 89 | 20 | } |
|
| 90 | 20 | ||
| 91 | 20 | if (isset($xmlRelatedParty->UltmtDbtr)) { |
|
| 92 | 20 | $xmlRelatedPartyType = $xmlRelatedParty->UltmtDbtr; |
|
| 93 | |||
| 94 | 20 | $this->addRelatedParty($detail, $xmlRelatedPartyType, DTO\UltimateDebtor::class); |
|
| 95 | } |
||
| 96 | } |
||
| 97 | 23 | } |
|
| 98 | 5 | ||
| 99 | 5 | /** |
|
| 100 | 5 | * @param class-string<RelatedPartyTypeInterface> $relatedPartyTypeClass |
|
|
0 ignored issues
–
show
Documentation
Bug
introduced
by
Loading history...
|
|||
| 101 | */ |
||
| 102 | 5 | protected function addRelatedParty(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlRelatedPartyType, string $relatedPartyTypeClass, ?SimpleXMLElement $xmlRelatedPartyTypeAccount = null): void |
|
| 103 | { |
||
| 104 | // CAMT v08 uses substructure, so we check for its existence or fallback to the element itself to keep compatibility with CAMT v04 |
||
| 105 | 23 | $xmlPartyDetail = $xmlRelatedPartyType->Pty ?: $xmlRelatedPartyType->Agt?->FinInstnId ?: $xmlRelatedPartyType; |
|
| 106 | |||
| 107 | 23 | $xmlRelatedPartyName = (isset($xmlPartyDetail->Nm)) ? (string) $xmlPartyDetail->Nm : null; |
|
| 108 | $relatedPartyType = new $relatedPartyTypeClass($xmlRelatedPartyName); |
||
| 109 | 23 | ||
| 110 | 23 | if (isset($xmlPartyDetail->PstlAdr)) { |
|
| 111 | $relatedPartyType->setAddress(DTOFactory\Address::createFromXml($xmlPartyDetail->PstlAdr)); |
||
| 112 | } |
||
| 113 | 23 | ||
| 114 | $relatedParty = new RelatedParty($relatedPartyType, $this->getRelatedPartyAccount($xmlRelatedPartyTypeAccount)); |
||
| 115 | 23 | ||
| 116 | $detail->addRelatedParty($relatedParty); |
||
| 117 | 23 | } |
|
| 118 | |||
| 119 | public function addRelatedAgents(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
||
| 120 | 22 | { |
|
| 121 | if (false === isset($xmlDetail->RltdAgts)) { |
||
| 122 | 22 | return; |
|
| 123 | 14 | } |
|
| 124 | |||
| 125 | foreach ($xmlDetail->RltdAgts as $xmlRelatedAgent) { |
||
| 126 | 17 | if (isset($xmlRelatedAgent->CdtrAgt)) { |
|
| 127 | 17 | $agent = new DTO\CreditorAgent((string) $xmlRelatedAgent->CdtrAgt->FinInstnId->Nm, (string) $xmlRelatedAgent->CdtrAgt->FinInstnId->BIC); |
|
| 128 | 17 | $relatedAgent = new DTO\RelatedAgent($agent); |
|
| 129 | 17 | $detail->addRelatedAgent($relatedAgent); |
|
| 130 | 17 | } |
|
| 131 | |||
| 132 | if (isset($xmlRelatedAgent->DbtrAgt)) { |
||
| 133 | 17 | $agent = new DTO\DebtorAgent((string) $xmlRelatedAgent->DbtrAgt->FinInstnId->Nm, (string) $xmlRelatedAgent->DbtrAgt->FinInstnId->BIC); |
|
| 134 | 17 | $relatedAgent = new DTO\RelatedAgent($agent); |
|
| 135 | 17 | $detail->addRelatedAgent($relatedAgent); |
|
| 136 | 17 | } |
|
| 137 | } |
||
| 138 | } |
||
| 139 | 17 | ||
| 140 | public function addRemittanceInformation(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
||
| 141 | 25 | { |
|
| 142 | if (false === isset($xmlDetail->RmtInf)) { |
||
| 143 | 25 | return; |
|
| 144 | 8 | } |
|
| 145 | |||
| 146 | $remittanceInformation = new DTO\RemittanceInformation(); |
||
| 147 | 20 | $unstructuredBlockExists = false; |
|
| 148 | 20 | ||
| 149 | // Unstructured blocks |
||
| 150 | $xmlDetailsUnstructuredBlocks = $xmlDetail->RmtInf->Ustrd; |
||
| 151 | 20 | if ($xmlDetailsUnstructuredBlocks !== null) { |
|
| 152 | 20 | foreach ($xmlDetailsUnstructuredBlocks as $xmlDetailsUnstructuredBlock) { |
|
| 153 | 20 | $unstructuredRemittanceInformation = new DTO\UnstructuredRemittanceInformation( |
|
| 154 | 10 | (string) $xmlDetailsUnstructuredBlock |
|
| 155 | 10 | ); |
|
| 156 | |||
| 157 | $remittanceInformation->addUnstructuredBlock($unstructuredRemittanceInformation); |
||
| 158 | 10 | ||
| 159 | // Legacy : use the very first unstructured block |
||
| 160 | if ($remittanceInformation->getMessage() === null) { |
||
| 161 | 10 | $unstructuredBlockExists = true; |
|
| 162 | 10 | $remittanceInformation->setMessage( |
|
| 163 | 10 | (string) $xmlDetailsUnstructuredBlock |
|
| 164 | 10 | ); |
|
| 165 | } |
||
| 166 | } |
||
| 167 | } |
||
| 168 | |||
| 169 | // Strutcured blocks |
||
| 170 | $xmlDetailsStructuredBlocks = $xmlDetail->RmtInf->Strd; |
||
| 171 | 20 | if ($xmlDetailsStructuredBlocks !== null) { |
|
| 172 | 20 | foreach ($xmlDetailsStructuredBlocks as $xmlDetailsStructuredBlock) { |
|
| 173 | 20 | $structuredRemittanceInformation = new DTO\StructuredRemittanceInformation(); |
|
| 174 | 14 | ||
| 175 | if (isset($xmlDetailsStructuredBlock->AddtlRmtInf)) { |
||
| 176 | 14 | $structuredRemittanceInformation->setAdditionalRemittanceInformation( |
|
| 177 | 4 | (string) $xmlDetailsStructuredBlock->AddtlRmtInf |
|
| 178 | 4 | ); |
|
| 179 | } |
||
| 180 | |||
| 181 | if (isset($xmlDetailsStructuredBlock->CdtrRefInf)) { |
||
| 182 | 14 | $creditorReferenceInformation = new DTO\CreditorReferenceInformation(); |
|
| 183 | 14 | ||
| 184 | if (isset($xmlDetailsStructuredBlock->CdtrRefInf->Ref)) { |
||
| 185 | 14 | $creditorReferenceInformation->setRef( |
|
| 186 | 14 | (string) $xmlDetailsStructuredBlock->CdtrRefInf->Ref |
|
| 187 | 14 | ); |
|
| 188 | } |
||
| 189 | |||
| 190 | if (isset($xmlDetailsStructuredBlock->CdtrRefInf->Tp, $xmlDetailsStructuredBlock->CdtrRefInf->Tp->CdOrPrtry, $xmlDetailsStructuredBlock->CdtrRefInf->Tp->CdOrPrtry->Prtry) |
||
| 191 | 14 | ||
| 192 | ) { |
||
| 193 | $creditorReferenceInformation->setProprietary( |
||
| 194 | 4 | (string) $xmlDetailsStructuredBlock->CdtrRefInf->Tp->CdOrPrtry->Prtry |
|
| 195 | 4 | ); |
|
| 196 | } |
||
| 197 | |||
| 198 | if (isset($xmlDetailsStructuredBlock->CdtrRefInf->Tp, $xmlDetailsStructuredBlock->CdtrRefInf->Tp->CdOrPrtry, $xmlDetailsStructuredBlock->CdtrRefInf->Tp->CdOrPrtry->Cd) |
||
| 199 | 14 | ||
| 200 | ) { |
||
| 201 | $creditorReferenceInformation->setCode( |
||
| 202 | 13 | (string) $xmlDetailsStructuredBlock->CdtrRefInf->Tp->CdOrPrtry->Cd |
|
| 203 | 13 | ); |
|
| 204 | } |
||
| 205 | |||
| 206 | $structuredRemittanceInformation->setCreditorReferenceInformation($creditorReferenceInformation); |
||
| 207 | 14 | ||
| 208 | // Legacy : do not overwrite message if already defined above |
||
| 209 | // and no creditor reference is already defined |
||
| 210 | if (false === $unstructuredBlockExists |
||
| 211 | 14 | && $remittanceInformation->getCreditorReferenceInformation() === null) { |
|
| 212 | 14 | $remittanceInformation->setCreditorReferenceInformation($creditorReferenceInformation); |
|
| 213 | 14 | } |
|
| 214 | } |
||
| 215 | |||
| 216 | $remittanceInformation->addStructuredBlock($structuredRemittanceInformation); |
||
| 217 | 14 | } |
|
| 218 | } |
||
| 219 | |||
| 220 | $detail->setRemittanceInformation($remittanceInformation); |
||
| 221 | 20 | } |
|
| 222 | 20 | ||
| 223 | public function addRelatedDates(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
||
| 224 | 24 | { |
|
| 225 | if (false === isset($xmlDetail->RltdDts)) { |
||
| 226 | 24 | return; |
|
| 227 | 23 | } |
|
| 228 | |||
| 229 | if (isset($xmlDetail->RltdDts->AccptncDtTm)) { |
||
| 230 | 1 | $RelatedDates = DTO\RelatedDates::fromUnstructured( |
|
| 231 | 1 | $this->dateDecoder->decode((string) $xmlDetail->RltdDts->AccptncDtTm) |
|
| 232 | 1 | ); |
|
| 233 | $detail->setRelatedDates($RelatedDates); |
||
| 234 | 1 | ||
| 235 | return; |
||
| 236 | 1 | } |
|
| 237 | } |
||
| 238 | |||
| 239 | public function addReturnInformation(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
||
| 240 | 24 | { |
|
| 241 | if (isset($xmlDetail->RtrInf, $xmlDetail->RtrInf->Rsn->Cd)) { |
||
| 242 | 24 | $remittanceInformation = DTO\ReturnInformation::fromUnstructured( |
|
| 243 | 1 | (string) $xmlDetail->RtrInf->Rsn->Cd, |
|
| 244 | 1 | (string) $xmlDetail->RtrInf->AddtlInf |
|
| 245 | 1 | ); |
|
| 246 | $detail->setReturnInformation($remittanceInformation); |
||
| 247 | 1 | } |
|
| 248 | } |
||
| 249 | 24 | ||
| 250 | public function addAdditionalTransactionInformation(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
||
| 251 | 24 | { |
|
| 252 | if (isset($xmlDetail->AddtlTxInf)) { |
||
| 253 | 24 | $additionalInformation = new DTO\AdditionalTransactionInformation( |
|
| 254 | 1 | (string) $xmlDetail->AddtlTxInf |
|
| 255 | 1 | ); |
|
| 256 | $detail->setAdditionalTransactionInformation($additionalInformation); |
||
| 257 | 1 | } |
|
| 258 | } |
||
| 259 | 24 | ||
| 260 | public function addBankTransactionCode(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
||
| 261 | 22 | { |
|
| 262 | $bankTransactionCode = new DTO\BankTransactionCode(); |
||
| 263 | 22 | ||
| 264 | if (isset($xmlDetail->BkTxCd)) { |
||
| 265 | 22 | $bankTransactionCode = new DTO\BankTransactionCode(); |
|
| 266 | 20 | ||
| 267 | if (isset($xmlDetail->BkTxCd->Prtry)) { |
||
| 268 | 20 | $proprietaryBankTransactionCode = new DTO\ProprietaryBankTransactionCode( |
|
| 269 | 20 | (string) $xmlDetail->BkTxCd->Prtry->Cd, |
|
| 270 | 20 | (string) $xmlDetail->BkTxCd->Prtry->Issr |
|
| 271 | 20 | ); |
|
| 272 | |||
| 273 | $bankTransactionCode->setProprietary($proprietaryBankTransactionCode); |
||
| 274 | 20 | } |
|
| 275 | |||
| 276 | if (isset($xmlDetail->BkTxCd->Domn)) { |
||
| 277 | 20 | $domainBankTransactionCode = new DTO\DomainBankTransactionCode( |
|
| 278 | 7 | (string) $xmlDetail->BkTxCd->Domn->Cd |
|
| 279 | 7 | ); |
|
| 280 | |||
| 281 | if (isset($xmlDetail->BkTxCd->Domn->Fmly)) { |
||
| 282 | 7 | $domainFamilyBankTransactionCode = new DTO\DomainFamilyBankTransactionCode( |
|
| 283 | 7 | (string) $xmlDetail->BkTxCd->Domn->Fmly->Cd, |
|
| 284 | 7 | (string) $xmlDetail->BkTxCd->Domn->Fmly->SubFmlyCd |
|
| 285 | 7 | ); |
|
| 286 | |||
| 287 | $domainBankTransactionCode->setFamily($domainFamilyBankTransactionCode); |
||
| 288 | 7 | } |
|
| 289 | |||
| 290 | $bankTransactionCode->setDomain($domainBankTransactionCode); |
||
| 291 | 7 | } |
|
| 292 | } |
||
| 293 | |||
| 294 | $detail->setBankTransactionCode($bankTransactionCode); |
||
| 295 | 22 | } |
|
| 296 | 22 | ||
| 297 | public function addCharges(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
||
| 298 | 24 | { |
|
| 299 | if (isset($xmlDetail->Chrgs)) { |
||
| 300 | 24 | $charges = new DTO\Charges(); |
|
| 301 | 4 | ||
| 302 | if (isset($xmlDetail->Chrgs->TtlChrgsAndTaxAmt) && (string) $xmlDetail->Chrgs->TtlChrgsAndTaxAmt) { |
||
| 303 | 4 | $money = $this->moneyFactory->create($xmlDetail->Chrgs->TtlChrgsAndTaxAmt, null); |
|
| 304 | 4 | ||
| 305 | 4 | $charges->setTotalChargesAndTaxAmount($money); |
|
| 306 | } |
||
| 307 | 4 | ||
| 308 | $chargesRecords = $xmlDetail->Chrgs->Rcrd; |
||
| 309 | if ($chargesRecords !== null) { |
||
| 310 | 4 | /** @var SimpleXMLElement $chargesRecord */ |
|
| 311 | 4 | foreach ($chargesRecords as $chargesRecord) { |
|
| 312 | $chargesDetail = new DTO\ChargesRecord(); |
||
| 313 | |||
| 314 | 4 | if (isset($chargesRecord->Amt) && (string) $chargesRecord->Amt) { |
|
| 315 | 4 | $money = $this->moneyFactory->create($chargesRecord->Amt, $chargesRecord->CdtDbtInd); |
|
| 316 | $chargesDetail->setAmount($money); |
||
| 317 | 4 | } |
|
| 318 | 4 | if (isset($chargesRecord->CdtDbtInd) && (string) $chargesRecord->CdtDbtInd === 'true') { |
|
| 319 | 4 | $chargesDetail->setChargesIncludedIndicator(true); |
|
| 320 | } |
||
| 321 | 4 | if (isset($chargesRecord->Tp->Prtry->Id) && (string) $chargesRecord->Tp->Prtry->Id) { |
|
| 322 | 4 | $chargesDetail->setIdentification((string) $chargesRecord->Tp->Prtry->Id); |
|
| 323 | } |
||
| 324 | $charges->addRecord($chargesDetail); |
||
| 325 | 4 | } |
|
| 326 | } |
||
| 327 | 4 | $detail->setCharges($charges); |
|
| 328 | } |
||
| 329 | } |
||
| 330 | 4 | ||
| 331 | 4 | public function addAmountDetails(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail, SimpleXMLElement $CdtDbtInd): void |
|
| 332 | { |
||
| 333 | 4 | if (isset($xmlDetail->AmtDtls, $xmlDetail->AmtDtls->TxAmt, $xmlDetail->AmtDtls->TxAmt->Amt)) { |
|
| 334 | $money = $this->moneyFactory->create($xmlDetail->AmtDtls->TxAmt->Amt, $CdtDbtInd); |
||
| 335 | $detail->setAmountDetails($money); |
||
| 336 | 4 | } |
|
| 337 | } |
||
| 338 | 24 | ||
| 339 | public function addAmount(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail, SimpleXMLElement $CdtDbtInd): void |
||
| 340 | 23 | { |
|
| 341 | if (isset($xmlDetail->Amt)) { |
||
| 342 | 23 | $money = $this->moneyFactory->create($xmlDetail->Amt, $CdtDbtInd); |
|
| 343 | 8 | $detail->setAmount($money); |
|
| 344 | 8 | } |
|
| 345 | } |
||
| 346 | 23 | ||
| 347 | abstract public function getRelatedPartyAccount(?SimpleXMLElement $xmlRelatedPartyTypeAccount): ?DTO\Account; |
||
| 348 | } |
||
| 349 |