Passed
Push — master ( 90eaf0...c1d1cf )
by Francimar
12:38
created

NFCe::checkQRCode()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 22
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 4.0027

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 17
cts 18
cp 0.9444
rs 8.9197
c 0
b 0
f 0
cc 4
eloc 17
nc 5
nop 1
crap 4.0027
1
<?php
2
/**
3
 * MIT License
4
 *
5
 * Copyright (c) 2016 MZ Desenvolvimento de Sistemas LTDA
6
 *
7
 * @author Francimar Alves <[email protected]>
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
10
 * of this software and associated documentation files (the "Software"), to deal
11
 * in the Software without restriction, including without limitation the rights
12
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
 * copies of the Software, and to permit persons to whom the Software is
14
 * furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included in all
17
 * copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
 * SOFTWARE.
26
 *
27
 */
28
namespace NFe\Core;
29
30
use NFe\Common\Util;
31
use NFe\Entity\Imposto;
32
33
/**
34
 * Classe para validação da nota fiscal eletrônica do consumidor
35
 */
36
class NFCe extends Nota
37
{
38
39
    /**
40
     * Versão do QRCode
41
     */
42
    const QRCODE_VERSAO = '100';
43
44
    /**
45
     * Texto com o QR-Code impresso no DANFE NFC-e
46
     */
47
    private $qrcode_url;
48
49
    /**
50
     * Constroi uma instância de NFCe vazia
51
     * @param  array $nfce Array contendo dados do NFCe
52
     */
53 7
    public function __construct($nfce = array())
54
    {
55 7
        parent::__construct($nfce);
56 7
        $this->setModelo(self::MODELO_NFCE);
57 7
        $this->setFormato(self::FORMATO_CONSUMIDOR);
58 7
    }
59
60
    /**
61
     * Texto com o QR-Code impresso no DANFE NFC-e
62
     * @param boolean $normalize informa se a qrcode_url deve estar no formato do XML
63
     * @return mixed qrcode_url do NFCe
64
     */
65 4
    public function getQRCodeURL($normalize = false)
66
    {
67 4
        if (!$normalize) {
68 2
            return $this->qrcode_url;
69
        }
70 3
        return $this->qrcode_url;
71
    }
72
    
73
    /**
74
     * Altera o valor da QrcodeURL para o informado no parâmetro
75
     * @param mixed $qrcode_url novo valor para QrcodeURL
76
     * @return NFCe A própria instância da classe
77
     */
78 7
    public function setQRCodeURL($qrcode_url)
79
    {
80 7
        $this->qrcode_url = $qrcode_url;
81 7
        return $this;
82
    }
83
84
    /**
85
     * URL da página de consulta da nota fiscal
86
     * @param boolean $normalize informa se a URL de consulta deve estar no formato do XML
87
     * @return string URL de consulta da NFCe
88
     */
89
    public function getConsultaURL($normalize = false)
0 ignored issues
show
Unused Code introduced by
The parameter $normalize is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
90
    {
91
        $estado = $this->getEmitente()->getEndereco()->getMunicipio()->getEstado();
92
        $db = SEFAZ::getInstance()->getConfiguracao()->getBanco();
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $db. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
93
        $info = $db->getInformacaoServico(
94
            $this->getEmissao(),
95
            $estado->getUF(),
96
            $this->getModelo(),
97
            $this->getAmbiente()
98
        );
99
        if (!isset($info['consulta'])) {
100
            throw new \Exception('Não existe URL de consulta da nota para o estado "'.$estado->getUF().'"', 404);
101
        }
102
        $url = $info['consulta'];
103
        if (is_array($url)) {
104
            $url = $url['url'];
105
        }
106
        return $url;
107
    }
108
109 2
    /**
110
     * Converte a instância da classe para um array de campos com valores
111 2
     * @return array Array contendo todos os campos e valores da instância
112 2
     */
113 2
    public function toArray($recursive = false)
114
    {
115
        $nfce = parent::toArray($recursive);
116
        $nfce['qrcode_url'] = $this->getQRCodeURL();
117
        return $nfce;
118
    }
119
120
    /**
121 7
     * Atribui os valores do array para a instância atual
122
     * @param mixed $nfce Array ou instância de NFCe, para copiar os valores
123 7
     * @return NFCe A própria instância da classe
124 2
     */
125 7
    public function fromArray($nfce = array())
126 2
    {
127
        if ($nfce instanceof NFCe) {
128 7
            $nfce = $nfce->toArray();
129 7
        } elseif (!is_array($nfce)) {
130 7
            return $this;
131
        }
132
        parent::fromArray($nfce);
133
        if (!isset($nfce['qrcode_url'])) {
134 7
            $this->setQRCodeURL(null);
135
        } else {
136
            $this->setQRCodeURL($nfce['qrcode_url']);
137 3
        }
138
        return $this;
139 3
    }
140 3
141 3
    private function gerarQRCodeInfo(&$dom)
142
    {
143 3
        $config = SEFAZ::getInstance()->getConfiguracao();
144
        $totais = $this->getTotais();
145
        $digest = $dom->getElementsByTagName('DigestValue')->item(0);
146
        // if($this->getEmissao() == self::EMISSAO_NORMAL)
147 3
            $dig_val = $digest->nodeValue;
148 3
        // else
149 3
        // 	$dig_val = base64_encode(sha1($dom->saveXML(), true));
150
        $params = array(
151 3
            'chNFe' => $this->getID(),
152 3
            'nVersao' => self::QRCODE_VERSAO,
153 3
            'tpAmb' => $this->getAmbiente(true),
154 3
            'cDest' => null,
155 3
            'dhEmi' => Util::toHex($this->getDataEmissao(true)),
156
            'vNF' => Util::toCurrency($totais['nota']),
157
            'vICMS' => Util::toCurrency($totais[Imposto::GRUPO_ICMS]),
158 3
            'digVal' => Util::toHex($dig_val),
159 3
            'cIdToken' => Util::padDigit($config->getToken(), 6),
160
            'cHashQRCode' => null
161
        );
162
        if (!is_null($this->getDestinatario())) {
163 3
            $params['cDest'] = $this->getDestinatario()->getID(true);
164 3
        } else {
165 3
            unset($params['cDest']);
166 3
        }
167 3
        $_params = $params;
168
        unset($_params['cHashQRCode']);
169
        $query = http_build_query($_params);
170 3
        $params['cHashQRCode'] = sha1($query.$config->getCSC());
171
        return $params;
172 3
    }
173 3
174 3
    private function checkQRCode(&$dom)
175 3
    {
176 3
        $estado = $this->getEmitente()->getEndereco()->getMunicipio()->getEstado();
177 3
        $db = SEFAZ::getInstance()->getConfiguracao()->getBanco();
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $db. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
178 3
        $params = $this->gerarQRCodeInfo($dom);
179 3
        $query = http_build_query($params);
180 3
        $info = $db->getInformacaoServico(
181
            $this->getEmissao(),
182 3
            $estado->getUF(),
183
            $this->getModelo(),
184
            $this->getAmbiente()
185 3
        );
186 3
        if (!isset($info['qrcode'])) {
187 3
            throw new \Exception('Não existe URL de consulta de QRCode para o estado "'.$estado->getUF().'"', 404);
188 3
        }
189
        $url = $info['qrcode'];
190 3
        if (is_array($url)) {
191
            $url = $url['url'];
192 3
        }
193 3
        $url .= (strpos($url, '?') === false?'?':'&').$query;
194 3
        $this->setQRCodeURL($url);
195 3
    }
196 3
197 3
    private function getNodeSuplementar(&$dom)
198 3
    {
199
        $this->checkQRCode($dom);
200
        $element = $dom->createElement('infNFeSupl');
201
        $qrcode = $dom->createElement('qrCode');
202
        $data = $dom->createCDATASection($this->getQRCodeURL(true));
203
        $qrcode->appendChild($data);
204
        $element->appendChild($qrcode);
205
        return $element;
206
    }
207 3
208
    /**
209 3
     * Carrega as informações do nó e preenche a instância da classe
210 3
     * @param  DOMElement $element Nó do xml com todos as tags dos campos
211 3
     * @param  string $name        Nome do nó que será carregado
212 3
     * @return DOMElement          Instância do nó que foi carregado
213 3
     */
214 2
    public function loadNode($element, $name = null)
215 1
    {
216
        $element = parent::loadNode($element, $name);
217
        $_fields = $element->getElementsByTagName('qrCode');
218 3
        $_sig_fields = $element->getElementsByTagName('Signature');
219 3
        $qrcode_url = null;
220
        if ($_fields->length > 0) {
221
            $qrcode_url = $_fields->item(0)->nodeValue;
222
        } elseif ($_sig_fields->length > 0) {
223
            throw new \Exception('Tag "qrCode" não encontrada', 404);
224
        }
225 3
        $this->setQRCodeURL($qrcode_url);
226
        return $element;
227 3
    }
228 3
229 3
    /**
230 3
     * Assina e adiciona informações suplementares da nota
231 3
     */
232
    public function assinar($dom = null)
233
    {
234
        $dom = parent::assinar($dom);
235
        $suplementar = $this->getNodeSuplementar($dom);
236
        $signature = $dom->getElementsByTagName('Signature')->item(0);
237
        $signature->parentNode->insertBefore($suplementar, $signature);
238
        return $dom;
239
    }
240
}
241