Passed
Push — master ( af81ee...d4daf1 )
by Manuel
38s queued 11s
created

QrPaymentReferenceGenerator::doGenerate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 0
dl 0
loc 13
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Sprain\SwissQrBill\Reference;
4
5
use Sprain\SwissQrBill\Validator\Exception\InvalidQrPaymentReferenceException;
6
use Sprain\SwissQrBill\Validator\SelfValidatableInterface;
7
use Sprain\SwissQrBill\Validator\SelfValidatableTrait;
8
use Symfony\Component\Validator\Constraints as Assert;
9
use Symfony\Component\Validator\Mapping\ClassMetadata;
10
11
class QrPaymentReferenceGenerator implements SelfValidatableInterface
12
{
13
    use SelfValidatableTrait;
14
15
    /** @var string */
16
    private $customerIdentificationNumber;
17
18
    /** @var string */
19
    private $referenceNumber;
20
21
    public static function generate(string $customerIdentificationNumber, string $referenceNumber)
22
    {
23
        $qrPaymentReferenceGenerator = new self();
24
        $qrPaymentReferenceGenerator->customerIdentificationNumber = $qrPaymentReferenceGenerator->removeWhitespace($customerIdentificationNumber);
25
        $qrPaymentReferenceGenerator->referenceNumber = $qrPaymentReferenceGenerator->removeWhitespace($referenceNumber);
26
27
        return $qrPaymentReferenceGenerator->doGenerate();
28
    }
29
30
    public function getCustomerIdentificationNumber(): ?string
31
    {
32
        return $this->customerIdentificationNumber;
33
    }
34
35
    public function getReferenceNumber(): ?string
36
    {
37
        return $this->referenceNumber;
38
    }
39
40
    public function doGenerate()
41
    {
42
        if (!$this->isValid()) {
43
            throw new InvalidQrPaymentReferenceException(
44
                'The provided data is not valid to generate a qr payment reference number. Use getViolations() to find details.'
45
            );
46
        }
47
48
        $completeReferenceNumber  = str_pad($this->getCustomerIdentificationNumber(), 6, '0', STR_PAD_RIGHT);
49
        $completeReferenceNumber .= str_pad($this->getReferenceNumber(), 20, '0', STR_PAD_LEFT);
50
        $completeReferenceNumber .= $this->modulo10($completeReferenceNumber);
51
52
        return $completeReferenceNumber;
53
    }
54
55
    public static function loadValidatorMetadata(ClassMetadata $metadata): void
56
    {
57
        $metadata->addPropertyConstraints('customerIdentificationNumber', [
58
            // Only numbers are allowed (including leading zeros)
59
            new Assert\Regex([
60
                'pattern' => '/^\d*$/',
61
                'match' => true
62
            ]),
63
            new Assert\Length([
64
                'max' => 6
65
            ]),
66
            new Assert\NotBlank()
67
        ]);
68
69
        $metadata->addPropertyConstraints('referenceNumber', [
70
            // Only numbers are allowed (including leading zeros)
71
            new Assert\Regex([
72
                'pattern' => '/^\d*$/',
73
                'match' => true
74
            ]),
75
            new Assert\Length([
76
                'max' => 20
77
            ]),
78
            new Assert\NotBlank()
79
        ]);
80
    }
81
82
    private function removeWhitespace(string $string): string
83
    {
84
        return preg_replace('/\s+/', '', $string);
85
    }
86
87
    private function modulo10($number)
88
    {
89
        $table = array(0, 9, 4, 6, 8, 2, 7, 1, 3, 5);
90
        $next = 0;
91
        for ($i = 0; $i < strlen($number); $i++) {
92
            $next =  $table[($next + substr($number, $i, 1)) % 10];
93
        }
94
95
        return (10 - $next) % 10;
96
    }
97
}
98