Completed
Pull Request — master (#19)
by
unknown
05:54
created

ISRCreditTransfer::setCreditorDetails()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 0
cts 4
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
crap 2
1
<?php
2
3
namespace Z38\SwissPayment\TransactionInformation;
4
5
use DOMDocument;
6
use InvalidArgumentException;
7
use LogicException;
8
use Z38\SwissPayment\ISRParticipant;
9
use Z38\SwissPayment\Money;
10
use Z38\SwissPayment\PaymentInformation\PaymentInformation;
11
use Z38\SwissPayment\PostalAddressInterface;
12
13
/**
14
 * ISRCreditTransfer contains all the information about a ISR (type 1) transaction.
15
 */
16
class ISRCreditTransfer extends CreditTransfer
17
{
18
    /**
19
     * @var ISRParticipant
20
     */
21
    protected $creditorAccount;
22
23
    /**
24
     * @var string
25
     */
26
    protected $creditorReference;
27
28
    /**
29
     * {@inheritdoc}
30
     *
31
     * @param ISRParticipant $creditorAccount   ISR participation number of the creditor
32
     * @param string         $creditorReference ISR reference number
33
     *
34
     * @throws InvalidArgumentException When the amount is not in EUR or CHF.
35
     */
36 3
    public function __construct($instructionId, $endToEndId, Money\Money $amount, ISRParticipant $creditorAccount, $creditorReference)
37
    {
38 3
        if (!$amount instanceof Money\EUR && !$amount instanceof Money\CHF) {
39
            throw new InvalidArgumentException(sprintf(
40
                'The amount must be an instance of Z38\SwissPayment\Money\EUR or Z38\SwissPayment\Money\CHF (instance of %s given).',
41
                get_class($amount)
42
            ));
43
        }
44
45 3
        if (self::modulo10(substr($creditorReference, 0, -1)) != (int) substr($creditorReference, -1)) {
46
            throw new InvalidArgumentException('Invalid ISR creditor reference.');
47
        }
48
49
        $this->instructionId = (string) $instructionId;
50
        $this->endToEndId = (string) $endToEndId;
51
        $this->amount = $amount;
52
        $this->creditorAccount = $creditorAccount;
53
        $this->creditorReference = (string) $creditorReference;
54
        $this->localInstrument = 'CH01';
55
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60
    public function setRemittanceInformation($remittanceInformation)
61
    {
62
        throw new LogicException('ISR payments are not able to store unstructured remittance information.');
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68
    public function asDom(DOMDocument $doc, PaymentInformation $paymentInformation)
69
    {
70
        $root = $this->buildHeader($doc, $paymentInformation);
71
72
        if (isset($this->creditorName) && isset($this->creditorAddress)) {
73
            $root->appendChild($this->buildCreditor($doc));
74
        }
75
76
        $creditorAccount = $doc->createElement('CdtrAcct');
77
        $creditorAccount->appendChild($this->creditorAccount->asDom($doc));
78
        $root->appendChild($creditorAccount);
79
80
        $this->appendPurpose($doc, $root);
81
82
        $this->appendRemittanceInformation($doc, $root);
83
84
        return $root;
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    protected function appendRemittanceInformation(\DOMDocument $doc, \DOMElement $transaction)
91
    {
92
        $remittanceInformation = $doc->createElement('RmtInf');
93
94
        $structured = $doc->createElement('Strd');
95
        $remittanceInformation->appendChild($structured);
96
97
        $creditorReferenceInformation = $doc->createElement('CdtrRefInf');
98
        $structured->appendChild($creditorReferenceInformation);
99
100
        $creditorReferenceInformation->appendChild($doc->createElement('Ref', $this->creditorReference));
101
102
        $transaction->appendChild($remittanceInformation);
103
    }
104
105
    /**
106
     * Permit to set optional creditor details
107
     *
108
     * @param string                 $creditorName
109
     * @param PostalAddressInterface $creditorAddress
110
     */
111
    public function setCreditorDetails($creditorName, PostalAddressInterface $creditorAddress)
112
    {
113
        $this->creditorName = $creditorName;
114
        $this->creditorAddress = $creditorAddress;
115
    }
116
117
    /**
118
     * Creates Modulo10 recursive check digit
119
     *
120
     * @param string $number Number to create recursive check digit off.
121
     *
122
     * @return int Recursive check digit.
123
     */
124
    private static function modulo10(string $number)
125
    {
126
        $moduloTable = [0, 9, 4, 6, 8, 2, 7, 1, 3, 5];
127
128
        $next = 0;
129
        for ($i = 0; $i < strlen($number); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
Consider avoiding function calls on each iteration of the for loop.

If you have a function call in the test part of a for loop, this function is executed on each iteration. Often such a function, can be moved to the initialization part and be cached.

// count() is called on each iteration
for ($i=0; $i < count($collection); $i++) { }

// count() is only called once
for ($i=0, $c=count($collection); $i<$c; $i++) { }
Loading history...
130
            $next = $moduloTable[($next + intval(substr($number, $i, 1))) % 10];
131
        }
132
133
        return (int) (10 - $next) % 10;
134
    }
135
}
136