Completed
Pull Request — master (#19)
by
unknown
01:59
created

ISRCreditTransfer::modulo10()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 7
cts 7
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 1
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 1
            throw new InvalidArgumentException('Invalid ISR creditor reference.');
47
        }
48
49 2
        $this->instructionId = (string) $instructionId;
50 2
        $this->endToEndId = (string) $endToEndId;
51 2
        $this->amount = $amount;
52 2
        $this->creditorAccount = $creditorAccount;
53 2
        $this->creditorReference = (string) $creditorReference;
54 2
        $this->localInstrument = 'CH01';
55 2
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60 1
    public function setRemittanceInformation($remittanceInformation)
61
    {
62 1
        throw new LogicException('ISR payments are not able to store unstructured remittance information.');
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68 2
    public function asDom(DOMDocument $doc, PaymentInformation $paymentInformation)
69
    {
70 2
        $root = $this->buildHeader($doc, $paymentInformation);
71
72 2
        if (isset($this->creditorName) && isset($this->creditorAddress)) {
73 2
            $root->appendChild($this->buildCreditor($doc));
74 2
        }
75
76 2
        $creditorAccount = $doc->createElement('CdtrAcct');
77 2
        $creditorAccount->appendChild($this->creditorAccount->asDom($doc));
78 2
        $root->appendChild($creditorAccount);
79
80 2
        $this->appendPurpose($doc, $root);
81
82 2
        $this->appendRemittanceInformation($doc, $root);
83
84 2
        return $root;
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90 2
    protected function appendRemittanceInformation(\DOMDocument $doc, \DOMElement $transaction)
91
    {
92 2
        $remittanceInformation = $doc->createElement('RmtInf');
93
94 2
        $structured = $doc->createElement('Strd');
95 2
        $remittanceInformation->appendChild($structured);
96
97 2
        $creditorReferenceInformation = $doc->createElement('CdtrRefInf');
98 2
        $structured->appendChild($creditorReferenceInformation);
99
100 2
        $creditorReferenceInformation->appendChild($doc->createElement('Ref', $this->creditorReference));
101
102 2
        $transaction->appendChild($remittanceInformation);
103 2
    }
104
105
    /**
106
     * Permit to set optional creditor details
107
     *
108
     * @param string                 $creditorName
109
     * @param PostalAddressInterface $creditorAddress
110
     */
111 3
    public function setCreditorDetails($creditorName, PostalAddressInterface $creditorAddress)
112
    {
113 3
        $this->creditorName = $creditorName;
114 3
        $this->creditorAddress = $creditorAddress;
115 3
    }
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 2
    private static function modulo10($number)
125
    {
126 2
        $moduloTable = [0, 9, 4, 6, 8, 2, 7, 1, 3, 5];
127
128 2
        $next = 0;
129 2
        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 2
            $next = $moduloTable[($next + intval(substr($number, $i, 1))) % 10];
131 2
        }
132
133 2
        return (int) (10 - $next) % 10;
134
    }
135
}
136