Completed
Push — feature-purposes ( ae1ada )
by z38
02:44
created

PaymentInformation::setCategoryPurpose()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Z38\SwissPayment\PaymentInformation;
4
5
use Z38\SwissPayment\BIC;
6
use Z38\SwissPayment\FinancialInstitutionInterface;
7
use Z38\SwissPayment\IBAN;
8
use Z38\SwissPayment\IID;
9
use Z38\SwissPayment\Money;
10
use Z38\SwissPayment\TransactionInformation\CreditTransfer;
11
12
/**
13
 * PaymentInformation contains a group of transactions as well as details about the debtor
14
 */
15
class PaymentInformation
16
{
17
    /**
18
     * @var string
19
     */
20
    protected $id;
21
22
    /**
23
     * @var array
24
     */
25
    protected $transactions;
26
27
    /**
28
     * @var bool
29
     */
30
    protected $batchBooking;
31
32
    /**
33
     * @var string|null
34
     */
35
    protected $serviceLevel;
36
37
    /**
38
     * @var string|null
39
     */
40
    protected $localInstrument;
41
42
    /**
43
     * @var CategoryPurposeCode|null
44
     */
45
    protected $categoryPurpose;
46
47
    /**
48
     * @var \DateTime
49
     */
50
    protected $executionDate;
51
52
    /**
53
     * @var string
54
     */
55
    protected $debtorName;
56
57
    /**
58
     * @var FinancialInstitutionInterface
59
     */
60
    protected $debtorAgent;
61
62
    /**
63
     * @var IBAN
64
     */
65
    protected $debtorIBAN;
66
67
    /**
68
     * Constructor
69
     *
70
     * @param string  $id          Identifier of this group (should be unique within a message)
71
     * @param string  $debtorName  Name of the debtor
72
     * @param BIC|IID $debtorAgent BIC or IID of the debtor's financial institution
73
     * @param IBAN    $debtorIBAN  IBAN of the debtor's account
74
     */
75 3
    public function __construct($id, $debtorName, FinancialInstitutionInterface $debtorAgent, IBAN $debtorIBAN)
76
    {
77 3
        if (!$debtorAgent instanceof BIC && !$debtorAgent instanceof IID) {
78 1
            throw new \InvalidArgumentException('The debtor agent must be an instance of BIC or IID.');
79
        }
80
81 2
        $this->id = (string) $id;
82 2
        $this->transactions = array();
83 2
        $this->batchBooking = true;
84 2
        $this->executionDate = new \DateTime();
85 2
        $this->debtorName = (string) $debtorName;
86 2
        $this->debtorAgent = $debtorAgent;
87 2
        $this->debtorIBAN = $debtorIBAN;
88 2
    }
89
90
    /**
91
     * Adds a single transaction to this payment
92
     *
93
     * @param CreditTransfer $transaction The transaction to be added
94
     *
95
     * @return PaymentInformation This payment instruction
96
     */
97 2
    public function addTransaction(CreditTransfer $transaction)
98
    {
99 2
        $this->transactions[] = $transaction;
100
101 2
        return $this;
102
    }
103
104
    /**
105
     * Gets the number of transactions
106
     *
107
     * @return int Number of transactions
108
     */
109 2
    public function getTransactionCount()
110
    {
111 2
        return count($this->transactions);
112
    }
113
114
    /**
115
     * Gets the sum of transactions
116
     *
117
     * @return Money\Mixed Sum of transactions
118
     */
119 2
    public function getTransactionSum()
120
    {
121 2
        $sum = new Money\Mixed(0);
122
123 2
        foreach ($this->transactions as $transaction) {
124 2
            $sum = $sum->plus($transaction->getAmount());
125 2
        }
126
127 2
        return $sum;
128
    }
129
130
    /**
131
     * Sets the required execution date.
132
     * Where appropriate, the value data is automatically modified to the next possible banking/Post Office working day.
133
     *
134
     * @param \DateTime $executionDate
135
     *
136
     * @return PaymentInformation This payment instruction
137
     */
138
    public function setExecutionDate(\DateTime $executionDate)
139
    {
140
        $this->executionDate = $executionDate;
141
142
        return $this;
143
    }
144
145
    /**
146
     * Sets the batch booking option.
147
     * It is recommended that one payment instruction is created for each currency transferred.
148
     *
149
     * @param bool $batchBooking
150
     *
151
     * @return PaymentInformation This payment instruction
152
     */
153
    public function setBatchBooking($batchBooking)
154
    {
155
        $this->batchBooking = boolval($batchBooking);
156
157
        return $this;
158
    }
159
160
    /**
161
     * Checks whether the payment type information is included on B- or C-level
162
     *
163
     * @return bool true if it is included on B-level
164
     */
165 4
    public function hasPaymentTypeInformation()
166
    {
167 4
        return ($this->localInstrument !== null || $this->serviceLevel !== null || $this->categoryPurpose !== null);
168
    }
169
170
    /**
171
     * Gets the local instrument
172
     *
173
     * @return string|null The local instrument
174
     */
175
    public function getLocalInstrument()
176
    {
177
        return $this->localInstrument;
178
    }
179
180
    /**
181
     * Gets the service level
182
     *
183
     * @return string|null The service level
184
     */
185
    public function getServiceLevel()
186
    {
187
        return $this->serviceLevel;
188
    }
189
190
    /**
191
     * Sets the category purpose
192
     *
193
     * @param CategoryPurposeCode $categoryPurpose The category purpose
194
     *
195
     * @return PaymentInformation This payment instruction
196
     */
197 2
    public function setCategoryPurpose(CategoryPurposeCode $categoryPurpose)
198
    {
199 2
        $this->categoryPurpose = $categoryPurpose;
200
201 2
        return $this;
202
    }
203
204
    /**
205
     * Builds a DOM tree of this payment instruction
206
     *
207
     * @param \DOMDocument $doc
208
     *
209
     * @return \DOMElement The built DOM tree
210
     */
211 5
    public function asDom(\DOMDocument $doc)
212
    {
213 5
        $root = $doc->createElement('PmtInf');
214
215 5
        $root->appendChild($doc->createElement('PmtInfId', $this->id));
216 5
        $root->appendChild($doc->createElement('PmtMtd', 'TRF'));
217 5
        $root->appendChild($doc->createElement('BtchBookg', ($this->batchBooking ? 'true' : 'false')));
218
219 5
        if ($this->hasPaymentTypeInformation()) {
220 5
            $paymentType = $doc->createElement('PmtTpInf');
221 5
            $localInstrument = $this->localInstrument ?: $this->inferLocalInstrument();
222 5
            if ($localInstrument !== null) {
223 3
                $localInstrumentNode = $doc->createElement('LclInstrm');
224 3
                $localInstrumentNode->appendChild($doc->createElement('Prtry', $localInstrument));
225 3
                $paymentType->appendChild($localInstrumentNode);
226 3
            }
227 5
            $serviceLevel = $this->serviceLevel ?: $this->inferServiceLevel();
228 5
            if ($serviceLevel !== null) {
229 4
                $serviceLevelNode = $doc->createElement('SvcLvl');
230 4
                $serviceLevelNode->appendChild($doc->createElement('Cd', $serviceLevel));
231 4
                $paymentType->appendChild($serviceLevelNode);
232 4
            }
233 5
            if ($this->categoryPurpose !== null) {
234 3
                $categoryPurposeNode = $doc->createElement('CtgyPurp');
235 3
                $categoryPurposeNode->appendChild($this->categoryPurpose->asDom($doc));
236 3
                $paymentType->appendChild($categoryPurposeNode);
237 3
            }
238 5
            $root->appendChild($paymentType);
239 5
        }
240
241 5
        $root->appendChild($doc->createElement('ReqdExctnDt', $this->executionDate->format('Y-m-d')));
242
243 5
        $debtor = $doc->createElement('Dbtr');
244 5
        $debtor->appendChild($doc->createElement('Nm', $this->debtorName));
245 5
        $root->appendChild($debtor);
246
247 5
        $debtorAccount = $doc->createElement('DbtrAcct');
248 5
        $debtorAccountId = $doc->createElement('Id');
249 5
        $debtorAccountId->appendChild($doc->createElement('IBAN', $this->debtorIBAN->normalize()));
250 5
        $debtorAccount->appendChild($debtorAccountId);
251 5
        $root->appendChild($debtorAccount);
252
253 5
        $debtorAgent = $doc->createElement('DbtrAgt');
254 5
        $debtorAgent->appendChild($this->debtorAgent->asDom($doc));
255 5
        $root->appendChild($debtorAgent);
256
257 5
        foreach ($this->transactions as $transaction) {
258 5
            if ($this->hasPaymentTypeInformation()) {
259 5
                if ($transaction->getLocalInstrument() !== $localInstrument) {
0 ignored issues
show
Bug introduced by
The variable $localInstrument does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
260
                    throw new \LogicException('You can not set the local instrument on B- and C-level.');
261
                }
262 5
                if ($transaction->getServiceLevel() !== $serviceLevel) {
0 ignored issues
show
Bug introduced by
The variable $serviceLevel does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
263 1
                    throw new \LogicException('You can not set the service level on B- and C-level.');
264
                }
265 4
            }
266 4
            $root->appendChild($transaction->asDom($doc, $this));
267 4
        }
268
269 4
        return $root;
270
    }
271
272 2
    private function inferServiceLevel()
273
    {
274 2
        if (!count($this->transactions)) {
275
            return null;
276
        }
277
278 2
        return $this->transactions[0]->getServiceLevel();
279
    }
280
281 2
    private function inferLocalInstrument()
282
    {
283 2
        if (!count($this->transactions)) {
284
            return null;
285
        }
286
287 2
        return $this->transactions[0]->getLocalInstrument();
288
    }
289
}
290