Failed Conditions
Push — master ( d9594d...c34324 )
by Adrien
01:53
created

src/Decoder/EntryTransactionDetail.php (1 issue)

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
The doc comment class-string<RelatedPartyTypeInterface> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<RelatedPartyTypeInterface>.
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