Passed
Push — master ( dc09fe...b3fb7f )
by Francimar
12:59
created

NFCe::makeUrlQuery()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 21
cts 21
cp 1
rs 9.456
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
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 = '2';
43
44
    /**
45
     * Texto com o QR-Code impresso no DANFE NFC-e
46
     */
47
    private $qrcode_url;
48
    /**
49
     * Informar a URL da "Consulta por chave de acesso da NFC-e". A mesma URL
50
     * que deve estar informada no DANFE NFC-e para consulta por chave de
51
     * acesso.
52
     */
53
    private $consulta_url;
54
55
    /**
56
     * Constroi uma instância de NFCe vazia
57
     * @param  array $nfce Array contendo dados do NFCe
58
     */
59 33
    public function __construct($nfce = [])
60
    {
61 33
        parent::__construct($nfce);
62 33
        $this->setModelo(self::MODELO_NFCE);
63 33
        $this->setFormato(self::FORMATO_CONSUMIDOR);
64 33
    }
65
66
    /**
67
     * Texto com o QR-Code impresso no DANFE NFC-e
68
     * @param boolean $normalize informa se a qrcode_url deve estar no formato do XML
69
     * @return mixed qrcode_url do NFCe
70
     */
71 30
    public function getQRCodeURL($normalize = false)
72
    {
73 30
        if (!$normalize) {
74 6
            return $this->qrcode_url;
75
        }
76 29
        return $this->qrcode_url;
77
    }
78
    
79
    /**
80
     * Altera o valor da QrcodeURL para o informado no parâmetro
81
     * @param mixed $qrcode_url novo valor para QrcodeURL
82
     * @return NFCe A própria instância da classe
83
     */
84 33
    public function setQRCodeURL($qrcode_url)
85
    {
86 33
        $this->qrcode_url = $qrcode_url;
87 33
        return $this;
88
    }
89
90
    /**
91
     * Informar a URL da "Consulta por chave de acesso da NFC-e". A mesma URL
92
     * que deve estar informada no DANFE NFC-e para consulta por chave de
93
     * acesso.
94
     * @param boolean $normalize informa se o consulta_url deve estar no formato do XML
95
     * @return mixed consulta_url do NFCe
96
     */
97 30
    public function getConsultaURL($normalize = false)
98
    {
99 30
        if (!$normalize) {
100 6
            return $this->consulta_url;
101
        }
102 29
        return $this->consulta_url;
103
    }
104
    
105
    /**
106
     * Altera o valor do ConsultaURL para o informado no parâmetro
107
     * @param mixed $consulta_url novo valor para ConsultaURL
108
     * @return NFCe A própria instância da classe
109
     */
110 33
    public function setConsultaURL($consulta_url)
111
    {
112 33
        $this->consulta_url = $consulta_url;
113 33
        return $this;
114
    }
115
116
    /**
117
     * URL da página do QRCode e consulta da nota fiscal
118
     * @return array URL do QRCode e consulta da NFCe
119
     */
120 29
    private function getURLs()
121
    {
122 29
        $estado = $this->getEmitente()->getEndereco()->getMunicipio()->getEstado();
123 29
        $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...
124 29
        $info = $db->getInformacaoServico(
125 29
            $this->getEmissao(),
126 29
            $estado->getUF(),
127 29
            $this->getModelo(),
128 29
            $this->getAmbiente()
129
        );
130 29
        return $info;
131
    }
132
133
    /**
134
     * Converte a instância da classe para um array de campos com valores
135
     * @return array Array contendo todos os campos e valores da instância
136
     */
137 6
    public function toArray($recursive = false)
138
    {
139 6
        $nfce = parent::toArray($recursive);
140 6
        $nfce['qrcode_url'] = $this->getQRCodeURL();
141 6
        $nfce['consulta_url'] = $this->getConsultaURL();
142 6
        return $nfce;
143
    }
144
145
    /**
146
     * Atribui os valores do array para a instância atual
147
     * @param mixed $nfce Array ou instância de NFCe, para copiar os valores
148
     * @return NFCe A própria instância da classe
149
     */
150 33
    public function fromArray($nfce = [])
151
    {
152 33
        if ($nfce instanceof NFCe) {
153 5
            $nfce = $nfce->toArray();
154 33
        } elseif (!is_array($nfce)) {
155 5
            return $this;
156
        }
157 33
        parent::fromArray($nfce);
158 33
        if (!isset($nfce['qrcode_url'])) {
159 33
            $this->setQRCodeURL(null);
160
        } else {
161
            $this->setQRCodeURL($nfce['qrcode_url']);
162
        }
163 33
        if (!isset($nfce['consulta_url'])) {
164 33
            $this->setConsultaURL(null);
165
        } else {
166
            $this->setConsultaURL($nfce['consulta_url']);
167
        }
168 33
        return $this;
169
    }
170
171 29
    private function makeUrlQuery($dom)
172
    {
173 29
        $config = SEFAZ::getInstance()->getConfiguracao();
174 29
        $totais = $this->getTotais();
175 29
        if ($this->getEmissao() == self::EMISSAO_NORMAL) {
176
            $params = [
177 29
                $this->getID(), // chave de acesso
178 29
                self::QRCODE_VERSAO, // versão do QR Code
179 29
                $this->getAmbiente(true), // Identificação do ambiente
180 29
                intval($config->getToken()), // Identificador do CSC (Sem zeros não significativos)
181
            ];
182
        } else { // contingência
183 1
            $dig_val = Util::loadNode($dom, 'DigestValue', 'Tag "DigestValue" não encontrada na NFCe');
184
            $params = [
185 1
                $this->getID(), // chave de acesso
186 1
                self::QRCODE_VERSAO, // versão do QR Code
187 1
                $this->getAmbiente(true), // Identificação do ambiente
188 1
                date('d', $this->getDataEmissao()), // dia da data de emissão
189 1
                Util::toCurrency($totais['nota']), // valor total da NFC-e
190 1
                Util::toHex($dig_val), // DigestValue da NFC-e
191 1
                intval($config->getToken()), // Identificador do CSC (Sem zeros não significativos)
192
            ];
193
        }
194 29
        $query = implode('|', $params);
195 29
        $hash = sha1($query.$config->getCSC());
196 29
        $params = [$query, $hash];
197 29
        $query = implode('|', $params);
198 29
        return ['p' => $query];
199
    }
200
201 29
    private function buildURLs($dom)
202
    {
203 29
        $info = $this->getURLs();
204 29
        if (!isset($info['qrcode'])) {
205
            throw new \Exception('Não existe URL de consulta de QRCode para o estado "'.$estado->getUF().'"', 404);
206
        }
207 29
        $url = $info['qrcode'];
208 29
        if (is_array($url)) {
209
            $url = $url['url'];
210
        }
211 29
        $params = $this->makeUrlQuery($dom);
212 29
        $query = urldecode(http_build_query($params));
213 29
        $url .= (strpos($url, '?') === false?'?':'&').$query;
214 29
        $this->setQRCodeURL($url);
215 29
        if (!isset($info['consulta'])) {
216
            throw new \Exception('Não existe URL de consulta da nota para o estado "'.$estado->getUF().'"', 404);
217
        }
218 29
        $url = $info['consulta'];
219 29
        if (is_array($url)) {
220
            $url = $url['url'];
221
        }
222 29
        $this->setConsultaURL($url);
223 29
    }
224
225 29
    private function getNodeSuplementar($dom)
226
    {
227 29
        $this->buildURLs($dom);
228 29
        $element = $dom->createElement('infNFeSupl');
229 29
        $qrcode = $dom->createElement('qrCode');
230 29
        $data = $dom->createCDATASection($this->getQRCodeURL(true));
231 29
        $qrcode->appendChild($data);
232 29
        $element->appendChild($qrcode);
233 29
        $urlchave = $dom->createElement('urlChave');
234 29
        $data = $dom->createCDATASection($this->getConsultaURL(true));
235 29
        $urlchave->appendChild($data);
236 29
        $element->appendChild($urlchave);
237 29
        return $element;
238
    }
239
240
    /**
241
     * Carrega as informações do nó e preenche a instância da classe
242
     * @param  DOMElement $element Nó do xml com todos as tags dos campos
243
     * @param  string $name        Nome do nó que será carregado
244
     * @return DOMElement          Instância do nó que foi carregado
245
     */
246 27
    public function loadNode($element, $name = null)
247
    {
248 27
        $element = parent::loadNode($element, $name);
249 27
        $qrcode_url = Util::loadNode($element, 'qrCode');
250 27
        if (Util::nodeExists($element, 'Signature') && is_null($qrcode_url)) {
251
            throw new \Exception('Tag "qrCode" não encontrada na NFCe', 404);
252
        }
253 27
        $this->setQRCodeURL($qrcode_url);
254 27
        $consulta_url = Util::loadNode($element, 'urlChave');
255 27
        $this->setConsultaURL($consulta_url);
256 27
        return $element;
257
    }
258
259
    /**
260
     * Assina e adiciona informações suplementares da nota
261
     */
262 29
    public function assinar($dom = null)
263
    {
264 29
        $dom = parent::assinar($dom);
265 29
        $suplementar = $this->getNodeSuplementar($dom);
266 29
        $signature = $dom->getElementsByTagName('Signature')->item(0);
267 29
        $signature->parentNode->insertBefore($suplementar, $signature);
268 29
        return $dom;
269
    }
270
}
271