Failed Conditions
Push — master ( c3df43...3c8a24 )
by Adrien
02:34
created

Record   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 183
Duplicated Lines 0 %

Test Coverage

Coverage 78.56%

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 97
dl 0
loc 183
ccs 77
cts 98
cp 0.7856
rs 9.1199
c 5
b 0
f 0
wmc 41

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
F addEntries() 0 126 34
B addBalances() 0 30 6

How to fix   Complexity   

Complex Class

Complex classes like Record 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 Record, 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\DTO;
8
use Genkgo\Camt\DTO\RecordWithBalances;
9
use Genkgo\Camt\Util\StringToUnits;
10
use Money\Currency;
11
use Money\Money;
12
use SimpleXMLElement;
13
14
class Record
15
{
16
    /**
17
     * @var Entry
18
     */
19
    private $entryDecoder;
20
21
    /**
22
     * @var DateDecoderInterface
23
     */
24
    private $dateDecoder;
25
26
    /**
27
     * Record constructor.
28
     */
29 33
    public function __construct(Entry $entryDecoder, DateDecoderInterface $dateDecoder)
30
    {
31 33
        $this->entryDecoder = $entryDecoder;
32 33
        $this->dateDecoder = $dateDecoder;
33 33
    }
34
35 20
    public function addBalances(RecordWithBalances $record, SimpleXMLElement $xmlRecord): void
36
    {
37 20
        $xmlBalances = $xmlRecord->Bal;
38 20
        foreach ($xmlBalances as $xmlBalance) {
39 15
            $amount = StringToUnits::convert((string) $xmlBalance->Amt);
40 15
            $currency = (string) $xmlBalance->Amt['Ccy'];
41 15
            $date = (string) $xmlBalance->Dt->Dt;
42
43 15
            if ((string) $xmlBalance->CdtDbtInd === 'DBIT') {
44 10
                $amount = $amount * -1;
45
            }
46
47 15
            if (isset($xmlBalance->Tp, $xmlBalance->Tp->CdOrPrtry)) {
48 15
                $code = (string) $xmlBalance->Tp->CdOrPrtry->Cd;
49
50 15
                if (in_array($code, ['OPBD', 'PRCD'], true)) {
51 12
                    $record->addBalance(DTO\Balance::opening(
52 12
                        new Money(
53 12
                            $amount,
54 12
                            new Currency($currency)
55
                        ),
56 12
                        $this->dateDecoder->decode($date)
57
                    ));
58 14
                } elseif ($code === 'CLBD') {
59 11
                    $record->addBalance(DTO\Balance::closing(
60 11
                        new Money(
61 11
                            $amount,
62 11
                            new Currency($currency)
63
                        ),
64 11
                        $this->dateDecoder->decode($date)
65
                    ));
66
                }
67
            }
68
        }
69 20
    }
70
71 24
    public function addEntries(DTO\Record $record, SimpleXMLElement $xmlRecord): void
72
    {
73 24
        $index = 0;
74 24
        $xmlEntries = $xmlRecord->Ntry;
75 24
        foreach ($xmlEntries as $xmlEntry) {
76 23
            $amount = StringToUnits::convert((string) $xmlEntry->Amt);
77 23
            $currency = (string) $xmlEntry->Amt['Ccy'];
78 23
            $bookingDate = ((string) $xmlEntry->BookgDt->Dt) ?: (string) $xmlEntry->BookgDt->DtTm;
79 23
            $valueDate = ((string) $xmlEntry->ValDt->Dt) ?: (string) $xmlEntry->ValDt->DtTm;
80 23
            $additionalInfo = ((string) $xmlEntry->AddtlNtryInf) ?: (string) $xmlEntry->AddtlNtryInf;
81
82 23
            if ((string) $xmlEntry->CdtDbtInd === 'DBIT') {
83 13
                $amount = $amount * -1;
84
            }
85
86 23
            $entry = new DTO\Entry(
87 23
                $record,
88
                $index,
89 23
                new Money($amount, new Currency($currency))
90
            );
91
92 23
            if ($bookingDate) {
93 22
                $entry->setBookingDate($this->dateDecoder->decode($bookingDate));
94
            }
95
96 23
            if ($valueDate) {
97 22
                $entry->setValueDate($this->dateDecoder->decode($valueDate));
98
            }
99
100 23
            $entry->setAdditionalInfo($additionalInfo);
101
102 23
            if (isset($xmlEntry->RvslInd) && (string) $xmlEntry->RvslInd === 'true') {
103 1
                $entry->setReversalIndicator(true);
104
            }
105
106 23
            if (isset($xmlEntry->NtryRef) && (string) $xmlEntry->NtryRef) {
107 1
                $entry->setReference((string) $xmlEntry->NtryRef);
108
            }
109
110 23
            if (isset($xmlEntry->AcctSvcrRef) && (string) $xmlEntry->AcctSvcrRef) {
111 19
                $entry->setAccountServicerReference((string) $xmlEntry->AcctSvcrRef);
112
            }
113
114 23
            if (isset($xmlEntry->NtryDtls->Btch->PmtInfId) && (string) $xmlEntry->NtryDtls->Btch->PmtInfId) {
115 12
                $entry->setBatchPaymentId((string) $xmlEntry->NtryDtls->Btch->PmtInfId);
116
            }
117
118 23
            if (isset($xmlEntry->NtryDtls->TxDtls->Refs->PmtInfId) && (string) $xmlEntry->NtryDtls->TxDtls->Refs->PmtInfId) {
119 4
                $entry->setBatchPaymentId((string) $xmlEntry->NtryDtls->TxDtls->Refs->PmtInfId);
120
            }
121
122 23
            if (isset($xmlEntry->BkTxCd)) {
123 22
                $bankTransactionCode = new DTO\BankTransactionCode();
124
125 22
                if (isset($xmlEntry->BkTxCd->Prtry)) {
126 21
                    $proprietaryBankTransactionCode = new DTO\ProprietaryBankTransactionCode(
127 21
                        (string) $xmlEntry->BkTxCd->Prtry->Cd,
128 21
                        (string) $xmlEntry->BkTxCd->Prtry->Issr
129
                    );
130
131 21
                    $bankTransactionCode->setProprietary($proprietaryBankTransactionCode);
132
                }
133
134 22
                if (isset($xmlEntry->BkTxCd->Domn)) {
135 18
                    $domainBankTransactionCode = new DTO\DomainBankTransactionCode(
136 18
                        (string) $xmlEntry->BkTxCd->Domn->Cd
137
                    );
138
139 18
                    if (isset($xmlEntry->BkTxCd->Domn->Fmly)) {
140 18
                        $domainFamilyBankTransactionCode = new DTO\DomainFamilyBankTransactionCode(
141 18
                            (string) $xmlEntry->BkTxCd->Domn->Fmly->Cd,
142 18
                            (string) $xmlEntry->BkTxCd->Domn->Fmly->SubFmlyCd
143
                        );
144
145 18
                        $domainBankTransactionCode->setFamily($domainFamilyBankTransactionCode);
146
                    }
147
148 18
                    $bankTransactionCode->setDomain($domainBankTransactionCode);
149
                }
150
151 22
                $entry->setBankTransactionCode($bankTransactionCode);
152
            }
153
154 23
            if (isset($xmlEntry->Chrgs)) {
155
                $charges = new DTO\Charges();
156
157
                if (isset($xmlEntry->Chrgs->TtlChrgsAndTaxAmt) && (string) $xmlEntry->Chrgs->TtlChrgsAndTaxAmt) {
158
                    $amount = StringToUnits::convert((string) $xmlEntry->Chrgs->TtlChrgsAndTaxAmt);
159
                    $currency = (string) $xmlEntry->Chrgs->TtlChrgsAndTaxAmt['Ccy'];
160
161
                    $charges->setTotalChargesAndTaxAmount(new Money($amount, new Currency($currency)));
162
                }
163
164
                $chargesRecords = $xmlEntry->Chrgs->Rcrd;
165
                if ($chargesRecords) {
166
167
                    /** @var SimpleXMLElement $chargesRecord */
168
                    foreach ($chargesRecords as $chargesRecord) {
169
                        $chargesDetail = new DTO\ChargesRecord();
170
171
                        if (isset($chargesRecord->Amt) && (string) $chargesRecord->Amt) {
172
                            $amount = StringToUnits::convert((string) $chargesRecord->Amt);
173
                            $currency = (string) $chargesRecord->Amt['Ccy'];
174
175
                            if ((string) $chargesRecord->CdtDbtInd === 'DBIT') {
176
                                $amount = $amount * -1;
177
                            }
178
179
                            $chargesDetail->setAmount(new Money($amount, new Currency($currency)));
180
                        }
181
                        if (isset($chargesRecord->CdtDbtInd) && (string) $chargesRecord->CdtDbtInd === 'true') {
182
                            $chargesDetail->setChargesIncludedIndicator(true);
183
                        }
184
                        if (isset($chargesRecord->Tp->Prtry->Id) && (string) $chargesRecord->Tp->Prtry->Id) {
185
                            $chargesDetail->setIdentification((string) $chargesRecord->Tp->Prtry->Id);
186
                        }
187
                        $charges->addRecord($chargesDetail);
188
                    }
189
                }
190
                $entry->setCharges($charges);
191
            }
192
193 23
            $this->entryDecoder->addTransactionDetails($entry, $xmlEntry);
194
195 23
            $record->addEntry($entry);
196 23
            ++$index;
197
        }
198 24
    }
199
}
200