Passed
Push — master ( 6a2c86...eb5e70 )
by Antonio Oertel
30s
created

NFeAccessKey::calculateDigit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
ccs 6
cts 6
cp 1
rs 9.6666
cc 1
eloc 6
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Brazanation\Documents;
4
5
use Brazanation\Documents\Exception\InvalidDocument as InvalidDocumentException;
6
7
final class NFeAccessKey implements DocumentInterface
8
{
9
    const LABEL = 'NFeAccessKey';
10
11
    const LENGTH = 44;
12
13
    const REGEX = '/([\d]{4})/';
14
15
    const MASK = '$1 ';
16
17
    const MODEL = 55;
18
19
    /**
20
     * @var string
21
     */
22
    private $nfeKey;
23
24
    /**
25
     * NFeAccessKey constructor.
26
     *
27
     * @param $nfeKey
28
     */
29 17
    public function __construct($nfeKey)
30
    {
31 17
        $this->validate($nfeKey);
32 4
        $this->nfeKey = $nfeKey;
33 4
    }
34
35
    /**
36
     * @param int       $state
37
     * @param \DateTime $generatedAt
38
     * @param Cnpj      $cnpj
39
     * @param int       $serie
40
     * @param int       $invoiceNumber
41
     * @param int       $controlNumber
42
     *
43
     * @return NFeAccessKey
44
     */
45 1
    public static function generate($state, \DateTime $generatedAt, Cnpj $cnpj, $serie, $invoiceNumber, $controlNumber)
46
    {
47 1
        $yearMonth = $generatedAt->format('ym');
48 1
        $serie = str_pad($serie, 3, 0, STR_PAD_LEFT);
49 1
        $model = self::MODEL;
50 1
        $invoiceNumber = str_pad($invoiceNumber, 9, 0, STR_PAD_LEFT);
51 1
        $controlNumber = str_pad($controlNumber, 9, 0, STR_PAD_LEFT);
52
53 1
        $baseNumber = "{$state}{$yearMonth}{$cnpj}{$model}{$serie}{$invoiceNumber}{$controlNumber}";
54
55 1
        $digit = self::calculateDigit($baseNumber);
56
57 1
        return new self("{$baseNumber}{$digit}");
58
    }
59
60 1
    public function format()
61
    {
62 1
        return trim(preg_replace(self::REGEX, self::MASK, $this->nfeKey));
63
    }
64
65 3
    public function __toString()
66
    {
67 3
        return $this->nfeKey;
68
    }
69
70 17
    private function validate($number)
71
    {
72 17
        if (empty($number)) {
73 3
            throw InvalidDocumentException::notEmpty(self::LABEL);
74
        }
75 14
        if (!$this->isValid($number)) {
76 10
            throw InvalidDocumentException::isNotValid(self::LABEL, $number);
77
        }
78 4
    }
79
80 14
    private function isValid($number)
81
    {
82 14
        if (strlen($number) != self::LENGTH) {
83
            return false;
84
        }
85
86 14
        if (preg_match("/^{$number[0]}{" . self::LENGTH . '}$/', $number)) {
87 1
            return false;
88
        }
89
90 13
        $digits = self::calculateDigit(substr($number, 0, -1));
91
92 13
        return $digits === substr($number, -1);
93
    }
94
95
    /**
96
     * @param string $baseNumber
97
     *
98
     * @return string
99
     */
100 13
    private static function calculateDigit($baseNumber)
101
    {
102 13
        $calculator = new DigitCalculator($baseNumber);
103 13
        $calculator->useComplementaryInsteadOfModule();
104 13
        $calculator->withModule(DigitCalculator::MODULE_11);
105 13
        $digit = $calculator->calculate();
106
107 13
        return "{$digit}";
108
    }
109
}
110