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

Envio::getServiceInfo()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 0
cts 9
cp 0
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 13
nc 2
nop 0
crap 6
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\Task;
29
30
use NFe\Core\Nota;
31
use NFe\Core\SEFAZ;
32
use NFe\Common\Node;
33
use NFe\Common\Util;
34
use NFe\Common\CurlSoap;
35
36
/**
37
 * Envia requisições para os servidores da SEFAZ
38
 */
39
class Envio
0 ignored issues
show
Complexity introduced by
This class has a complexity of 63 which exceeds the configured maximum of 50.

The class complexity is the sum of the complexity of all methods. A very high value is usually an indication that your class does not follow the single reponsibility principle and does more than one job.

Some resources for further reading:

You can also find more detailed suggestions for refactoring in the “Code” section of your repository.

Loading history...
40
{
41
42
    /**
43
     * Tipo de serviço a ser executado
44
     */
45
    const SERVICO_INUTILIZACAO = 'inutilizacao';
46
    const SERVICO_PROTOCOLO = 'protocolo';
47
    const SERVICO_STATUS = 'status';
48
    const SERVICO_CADASTRO = 'cadastro';
49
    const SERVICO_AUTORIZACAO = 'autorizacao';
50
    const SERVICO_RETORNO = 'retorno';
51
    const SERVICO_RECEPCAO = 'recepcao';
52
    const SERVICO_CONFIRMACAO = 'confirmacao';
53
    const SERVICO_EVENTO = 'evento';
54
    const SERVICO_DESTINADAS = 'destinadas';
55
    const SERVICO_DOWNLOAD = 'download';
56
    const SERVICO_DISTRIBUICAO = 'distribuicao';
57
58
    /**
59
     * Tipo de serviço a ser executado
60
     */
61
    private $servico;
62
    /**
63
     * Identificação do Ambiente:
64
     * 1 - Produção
65
     * 2 - Homologação
66
     */
67
    private $ambiente;
68
    /**
69
     * Código do modelo do Documento Fiscal. 55 = NF-e; 65 = NFC-e.
70
     */
71
    private $modelo;
72
    /**
73
     * Forma de emissão da NF-e
74
     */
75
    private $emissao;
76
    /**
77
     * Conteudo a ser enviado
78
     */
79
    private $conteudo;
80
81
    /**
82
     * Constroi uma instância de Envio vazia
83
     * @param  array $envio Array contendo dados do Envio
84
     */
85 1
    public function __construct($envio = array())
86
    {
87 1
        $this->fromArray($envio);
88 1
    }
89
90
    /**
91
     * Tipo de serviço a ser executado
92
     * @param boolean $normalize informa se o servico deve estar no formato do XML
93
     * @return mixed servico do Envio
94
     */
95
    public function getServico($normalize = false)
96
    {
97
        if (!$normalize) {
98
            return $this->servico;
99
        }
100
        $url = $this->getServiceInfo();
101
        if (is_array($url) && isset($url['servico'])) {
102
            return Nota::PORTAL.'/wsdl/'.$url['servico'];
103
        }
104
        switch ($this->servico) {
105
            case self::SERVICO_INUTILIZACAO:
106
                return Nota::PORTAL.'/wsdl/NfeInutilizacao';
107
            case self::SERVICO_PROTOCOLO:
108
                return Nota::PORTAL.'/wsdl/NFeConsulta';
109
            case self::SERVICO_STATUS:
110
                return Nota::PORTAL.'/wsdl/NfeStatusServico';
111
            case self::SERVICO_CADASTRO:
112
                return Nota::PORTAL.'/wsdl/NfeConsultaCadastro';
113
            case self::SERVICO_AUTORIZACAO:
114
                return Nota::PORTAL.'/wsdl/NFeAutorizacao';
115
            case self::SERVICO_RETORNO:
116
                return Nota::PORTAL.'/wsdl/NFeRetAutorizacao';
117
            case self::SERVICO_RECEPCAO:
118
                return Nota::PORTAL.'/wsdl/NfeRecepcao';
119
            case self::SERVICO_CONFIRMACAO:
120
                return Nota::PORTAL.'/wsdl/NfeRetRecepcao';
121
            case self::SERVICO_EVENTO:
122
                return Nota::PORTAL.'/wsdl/RecepcaoEvento';
123
            case self::SERVICO_DESTINADAS:
124
                return Nota::PORTAL.'/wsdl/NfeConsultaDest';
125
            case self::SERVICO_DOWNLOAD:
126
                return Nota::PORTAL.'/wsdl/NfeDownloadNF';
127
            case self::SERVICO_DISTRIBUICAO:
128
                return Nota::PORTAL.'/wsdl/NFeDistribuicaoDFe';
129
        }
130
        return $this->servico;
131
    }
132
133
    /**
134 1
     * Altera o valor do Servico para o informado no parâmetro
135
     * @param mixed $servico novo valor para Servico
136 1
     * @return Envio A própria instância da classe
137 1
     */
138
    public function setServico($servico)
139
    {
140
        $this->servico = $servico;
141
        return $this;
142
    }
143
144
    /**
145
     * Identificação do Ambiente:
146
     * 1 - Produção
147
     * 2 - Homologação
148
     * @param boolean $normalize informa se o ambiente deve estar no formato do XML
149
     * @return mixed ambiente do Envio
150
     */
151
    public function getAmbiente($normalize = false)
152
    {
153
        if (!$normalize) {
154
            return $this->ambiente;
155
        }
156
        switch ($this->ambiente) {
157
            case Nota::AMBIENTE_PRODUCAO:
158
                return '1';
159
            case Nota::AMBIENTE_HOMOLOGACAO:
160
                return '2';
161
        }
162
        return $this->ambiente;
163
    }
164
165
    /**
166 1
     * Altera o valor do Ambiente para o informado no parâmetro
167
     * @param mixed $ambiente novo valor para Ambiente
168
     * @return Envio A própria instância da classe
169 1
     */
170
    public function setAmbiente($ambiente)
171
    {
172 1
        switch ($ambiente) {
173
            case '1':
174
                $ambiente = Nota::AMBIENTE_PRODUCAO;
175
                break;
176 1
            case '2':
177 1
                $ambiente = Nota::AMBIENTE_HOMOLOGACAO;
178
                break;
179
        }
180
        $this->ambiente = $ambiente;
181
        return $this;
182
    }
183
184
    /**
185
     * Código do modelo do Documento Fiscal. 55 = NF-e; 65 = NFC-e.
186
     * @param boolean $normalize informa se o modelo deve estar no formato do XML
187
     * @return mixed modelo do Envio
188
     */
189
    public function getModelo($normalize = false)
190
    {
191
        if (!$normalize) {
192
            return $this->modelo;
193
        }
194
        switch ($this->modelo) {
195
            case Nota::MODELO_NFE:
196
                return '55';
197
            case Nota::MODELO_NFCE:
198
                return '65';
199
        }
200
        return $this->modelo;
201
    }
202
203
    /**
204 1
     * Altera o valor do Modelo para o informado no parâmetro
205
     * @param mixed $modelo novo valor para Modelo
206
     * @return Envio A própria instância da classe
207 1
     */
208
    public function setModelo($modelo)
209
    {
210 1
        switch ($modelo) {
211
            case '55':
212
                $modelo = Nota::MODELO_NFE;
213
                break;
214 1
            case '65':
215 1
                $modelo = Nota::MODELO_NFCE;
216
                break;
217
        }
218
        $this->modelo = $modelo;
219
        return $this;
220
    }
221
222
    /**
223
     * Forma de emissão da NF-e
224
     * @param boolean $normalize informa se o emissao deve estar no formato do XML
225
     * @return mixed emissao do Envio
226
     */
227
    public function getEmissao($normalize = false)
228
    {
229
        if (!$normalize) {
230
            return $this->emissao;
231
        }
232
        switch ($this->emissao) {
233
            case Nota::EMISSAO_NORMAL:
234
                return '1';
235
            case Nota::EMISSAO_CONTINGENCIA:
236
                return '9';
237
        }
238
        return $this->emissao;
239
    }
240
241
    /**
242 1
     * Altera o valor do Emissao para o informado no parâmetro
243
     * @param mixed $emissao novo valor para Emissao
244
     * @return Envio A própria instância da classe
245 1
     */
246
    public function setEmissao($emissao)
247
    {
248 1
        switch ($emissao) {
249
            case '1':
250
                $emissao = Nota::EMISSAO_NORMAL;
251
                break;
252 1
            case '9':
253 1
                $emissao = Nota::EMISSAO_CONTINGENCIA;
254
                break;
255
        }
256
        $this->emissao = $emissao;
257
        return $this;
258
    }
259
260
    /**
261
     * Conteudo a ser enviado
262
     * @return mixed conteudo do Envio
263
     */
264
    public function getConteudo()
265
    {
266
        return $this->conteudo;
267
    }
268
269
    /**
270 1
     * Altera o valor do Conteudo para o informado no parâmetro
271
     * @param mixed $conteudo novo valor para Conteudo
272 1
     * @return Envio A própria instância da classe
273 1
     */
274
    public function setConteudo($conteudo)
275
    {
276
        $this->conteudo = $conteudo;
277
        return $this;
278
    }
279
280
    /**
281
     * Obtém a versão do serviço a ser utilizado
282
     * @return string Versão do serviço
283
     */
284
    public function getVersao()
285
    {
286
        $url = $this->getServiceInfo();
287
        if (is_array($url) && isset($url['versao'])) {
288
            return $url['versao'];
289
        }
290
        return Nota::VERSAO;
291
    }
292
293
    /**
294
     * Devolve um array com as informações de serviço (URL, Versão, Serviço)
295
     * @return array Informações de serviço
296
     */
297
    private function getServiceInfo()
298
    {
299
        $config = SEFAZ::getInstance()->getConfiguracao();
300
        $db = $config->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...
301
        $estado = $config->getEmitente()->getEndereco()->getMunicipio()->getEstado();
302
        $info = $db->getInformacaoServico(
303
            $this->getEmissao(),
304
            $estado->getUF(),
305
            $this->getModelo(),
306
            $this->getAmbiente()
307
        );
308
        if (!isset($info[$this->getServico()])) {
309
            throw new \Exception('O serviço "'.$this->getServico().
310
                '" não está disponível para o estado "'.$estado->getUF().'"', 404);
311
        }
312
        return $info[$this->getServico()];
313
    }
314
315
    /**
316
     * Converte a instância da classe para um array de campos com valores
317
     * @return array Array contendo todos os campos e valores da instância
318
     */
319
    public function toArray($recursive = false)
0 ignored issues
show
Unused Code introduced by
The parameter $recursive 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...
320
    {
321
        $envio = array();
322 1
        $envio['servico'] = $this->getServico();
323
        $envio['ambiente'] = $this->getAmbiente();
324 1
        $envio['modelo'] = $this->getModelo();
325
        $envio['emissao'] = $this->getEmissao();
326 1
        $envio['conteudo'] = $this->getConteudo();
327
        return $envio;
328
    }
329 1
330
    /**
331
     * Atribui os valores do array para a instância atual
332 1
     * @param mixed $envio Array ou instância de Envio, para copiar os valores
333
     * @return Envio A própria instância da classe
334 1
     */
335
    public function fromArray($envio = array())
336
    {
337 1
        if ($envio instanceof Envio) {
338
            $envio = $envio->toArray();
339 1
        } elseif (!is_array($envio)) {
340
            return $this;
341
        }
342 1
        if (isset($envio['servico'])) {
343
            $this->setServico($envio['servico']);
344 1
        } else {
345
            $this->setServico(null);
346
        }
347 1
        if (isset($envio['ambiente'])) {
348
            $this->setAmbiente($envio['ambiente']);
349 1
        } else {
350
            $this->setAmbiente(null);
351
        }
352 1
        if (isset($envio['modelo'])) {
353
            $this->setModelo($envio['modelo']);
354 1
        } else {
355
            $this->setModelo(null);
356
        }
357
        if (isset($envio['emissao'])) {
358
            $this->setEmissao($envio['emissao']);
359
        } else {
360
            $this->setEmissao(null);
361
        }
362
        if (isset($envio['conteudo'])) {
363
            $this->setConteudo($envio['conteudo']);
364
        } else {
365
            $this->setConteudo(null);
366
        }
367
        return $this;
368
    }
369
370
    /**
371
     * Obtém o nó do cabeçalho da requisição SOAP
372
     * @return DOMDocument Cabeçalho para adicionar na requisição
373
     */
374
    private function getNodeHeader()
375
    {
376
        $config = SEFAZ::getInstance()->getConfiguracao();
377
        $estado = $config->getEmitente()->getEndereco()->getMunicipio()->getEstado();
378
        $estado->checkCodigos();
379
        $doh = new \DOMDocument('1.0', 'UTF-8');
380
        $element = $doh->createElement('nfeCabecMsg');
381
        $element->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', $this->getServico(true));
382
        Util::appendNode($element, 'cUF', $estado->getCodigo(true));
383
        Util::appendNode($element, 'versaoDados', $this->getVersao());
384
        $doh->appendChild($element);
385
        return $doh;
386
    }
387
388
    /**
389
     * Cria um nó XML do envio de acordo com o leiaute da NFe
390
     * @param  string $name Nome do nó que será criado
391
     * @return DOMElement   Nó que contém todos os campos da classe
392
     */
393
    public function getNode($name = null)
394
    {
395
        $dom = new \DOMDocument('1.0', 'UTF-8');
396
        $element = $dom->createElement(is_null($name)?'nfeDadosMsg':$name);
397
        $element->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', $this->getServico(true));
398
        // Corrige xmlns:default
399
        // $data = $dom->importNode($this->getConteudo()->documentElement, true);
400
        // $element->appendChild($data);
401
        Util::appendNode($element, 'Conteudo', 0);
402
403
        $dom->appendChild($element);
404
405
        // Corrige xmlns:default
406
        // return $dom;
407
        if ($this->getConteudo() instanceof \DOMDocument) {
408
            $xml = $this->getConteudo()->saveXML($this->getConteudo()->documentElement);
409
        } else {
410
            $xml = $this->getConteudo();
411
        }
412
        $xml = str_replace('<Conteudo>0</Conteudo>', $xml, $dom->saveXML($dom->documentElement));
413
        $dom->loadXML($xml);
414
        return $dom;
415
    }
416
417
    /**
418
     * Envia o conteúdo para o serviço da SEFAZ informado
419
     * @return DOMDocument Documento XML da resposta da SEFAZ
420
     */
421
    public function envia()
422
    {
423
        $config = SEFAZ::getInstance()->getConfiguracao();
424
        $url = $this->getServiceInfo();
425
        if (is_array($url)) {
426
            $url = $url['url'];
427
        }
428
        if ($config->isOffline()) {
429
            throw new \NFe\Exception\NetworkException('Operação offline, sem conexão com a internet', 7);
430
        }
431
        $soap = new CurlSoap();
432
        $soap->setConnectTimeout(intval($config->getTempoLimite()));
433
        $soap->setTimeout(ceil($config->getTempoLimite() * 1.5));
434
        $soap->setCertificate($config->getArquivoChavePublica());
435
        $soap->setPrivateKey($config->getArquivoChavePrivada());
436
        $doh = $this->getNodeHeader();
437
        $dob = $this->getNode();
438
        try {
439
            $resp = $soap->send($url, $dob, $doh);
0 ignored issues
show
Documentation introduced by
$doh is of type object<DOMDocument>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
440
            return $resp;
441
        } catch (\NFe\Exception\NetworkException $e) {
442
            $config->setOffline(time());
443
            throw $e;
444
        }
445
    }
446
}
447