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

EntryTransactionDetail   F

Complexity

Total Complexity 79

Size/Duplication

Total Lines 334
Duplicated Lines 0 %

Test Coverage

Coverage 98.91%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 159
c 2
b 0
f 0
dl 0
loc 334
rs 2.08
ccs 182
cts 184
cp 0.9891
wmc 79

13 Methods

Rating   Name   Duplication   Size   Complexity  
A addAmountDetails() 0 5 2
A addAmount() 0 5 2
A __construct() 0 4 1
D addReference() 0 32 19
A addBankTransactionCode() 0 35 5
C addRemittanceInformation() 0 81 14
A addAdditionalTransactionInformation() 0 7 2
A addRelatedDates() 0 13 3
A addRelatedAgents() 0 17 5
B addRelatedParties() 0 32 7
A addReturnInformation() 0 8 2
A addRelatedParty() 0 15 5
C addCharges() 0 31 12

How to fix   Complexity   

Complex Class

Complex classes like EntryTransactionDetail often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EntryTransactionDetail, and based on these observations, apply Extract Interface, too.

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) {
0 ignored issues
show
Deprecated Code introduced by
The function Genkgo\Camt\DTO\Remittan...formation::getMessage() has been deprecated: Use getStructuredBlocks method instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

160
                if (/** @scrutinizer ignore-deprecated */ $remittanceInformation->getMessage() === null) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
161 10
                    $unstructuredBlockExists = true;
162 10
                    $remittanceInformation->setMessage(
0 ignored issues
show
Deprecated Code introduced by
The function Genkgo\Camt\DTO\Remittan...formation::setMessage() has been deprecated: Use addStructuredBlock method instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

162
                    /** @scrutinizer ignore-deprecated */ $remittanceInformation->setMessage(

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
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