Passed
Pull Request — master (#193)
by Roberto
03:33
created

Keys   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 87.5%

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 0
dl 0
loc 104
ccs 28
cts 32
cp 0.875
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A build() 0 34 3
A isValid() 0 12 3
B verifyingDigit() 0 20 6
A random() 0 4 1
1
<?php
2
3
namespace NFePHP\Common;
4
5
/**
6
 * Class to create and validate the identification keys of electronic documents
7
 * from SPED
8
 * NT 2018.001 Emitente com CPF e IE
9
 * @category   NFePHP
10
 * @package    NFePHP\Common\Keys
11
 * @copyright  Copyright (c) 2008-2018
12
 * @license    http://www.gnu.org/licenses/lesser.html LGPL v3
13
 * @author     Roberto L. Machado <linux dot rlm at gmail dot com>
14
 * @link       http://github.com/nfephp-org/sped-common for the canonical source repository
15
 */
16
17
class Keys
18
{
19
    /**
20
     * Build 44 digits keys to NFe, NFCe, CTe and MDFe
21
     * @param string $cUF UF number
22
     * @param string $ano year
23
     * @param string $mes month
24
     * @param string $cnpj or CPF
25
     * @param string $mod model of document 55, 65, 57 etc
26
     * @param string $serie
27
     * @param string $numero document number
28
     * @param string $tpEmis emission type
29
     * @param string $codigo random number or document number
30
     * @return string
31
     */
32 2
    public static function build(
33
        $cUF,
34
        $ano,
35
        $mes,
36
        $cnpj,
37
        $mod,
38
        $serie,
39
        $numero,
40
        $tpEmis,
41
        $codigo = null
42
    ) {
43 2
        if (empty($codigo)) {
44
            $codigo = self::random();
45
        }
46
        //if a cpf with 11 digits is passed then complete with leading zeros
47
        //up to the 14 digits
48 2
        if (strlen($cnpj) < 14) {
49 1
            $cnpj = str_pad($cnpj, 14, '0', STR_PAD_LEFT);
50
        }
51 2
        $format = "%02d%02d%02d%s%02d%03d%09d%01d%08d";
52 2
        $key = sprintf(
53
            $format,
54
            $cUF,
55
            $ano,
56
            $mes,
57
            $cnpj,
58
            $mod,
59
            $serie,
60
            $numero,
61
            $tpEmis,
62
            $codigo
63
        );
64 2
        return $key . self::verifyingDigit($key);
65
    }
66
    
67
    /**
68
     * Verifies that the key provided is valid
69
     * @param string $key
70
     * @return boolean
71
     */
72 2
    public static function isValid($key)
73
    {
74 2
        if (strlen($key) != 44) {
75
            return false;
76
        }
77 2
        $cDV = substr($key, -1);
78 2
        $calcDV = self::verifyingDigit(substr($key, 0, 43));
79 2
        if ($cDV === $calcDV) {
80 1
            return true;
81
        }
82 1
        return false;
83
    }
84
    
85
    /**
86
     * This method calculates verifying digit
87
     * @param string $key
88
     * @return string
89
     */
90 6
    public static function verifyingDigit($key)
91
    {
92 6
        if (strlen($key) != 43) {
93 1
            return '';
94
        }
95 5
        $multipliers = [2, 3, 4, 5, 6, 7, 8, 9];
96 5
        $iCount = 42;
97 5
        $weightedSum = 0;
98 5
        while ($iCount >= 0) {
99 5
            for ($mCount = 0; $mCount < 8 && $iCount >= 0; $mCount++) {
100 5
                $weightedSum += (substr($key, $iCount, 1) * $multipliers[$mCount]);
101 5
                $iCount--;
102
            }
103
        }
104 5
        $vdigit = 11 - ($weightedSum % 11);
105 5
        if ($vdigit > 9) {
106 3
            $vdigit = 0;
107
        }
108 5
        return (string) $vdigit;
109
    }
110
    
111
    /**
112
     * Generate and return a 8 digits random number
113
     * for cNF tag
114
     * @return string
115
     */
116
    public static function random()
117
    {
118
        return str_pad(mt_rand(0, 99999999), 8, '0', STR_PAD_LEFT);
119
    }
120
}
121