Test Failed
Push — master ( e53a66...43458c )
by Francimar
16:26
created

Evento   D

Complexity

Total Complexity 98

Size/Duplication

Total Lines 776
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 34.49%

Importance

Changes 0
Metric Value
wmc 98
lcom 1
cbo 6
dl 0
loc 776
ccs 149
cts 432
cp 0.3449
rs 4.4444
c 0
b 0
f 0

44 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A setID() 0 5 1
A setOrgao() 0 5 1
A setIdentificador() 0 5 1
A setChave() 0 5 1
A setTipo() 0 5 1
A setSequencia() 0 5 1
A setDescricao() 0 5 1
A setNumero() 0 5 1
A setJustificativa() 0 5 1
A setEmail() 0 5 1
A getInformacao() 0 4 1
A setInformacao() 0 5 1
A toArray() 0 18 1
A setData() 0 8 2
A getID() 0 7 2
A getOrgao() 0 9 3
A getIdentificador() 0 7 2
A getChave() 0 7 2
A getData() 0 7 2
A getTipo() 0 7 2
A getSequencia() 0 7 2
A getDescricao() 0 7 2
A getNumero() 0 7 2
A getJustificativa() 0 7 2
A getEmail() 0 7 2
A getModelo() 0 13 4
A setModelo() 0 13 3
A isCNPJ() 0 4 1
A isProcessado() 0 4 1
A isCancelado() 0 4 1
F fromArray() 0 75 16
A gerarID() 0 10 1
B getNode() 0 44 3
B loadNode() 0 95 4
A loadResponse() 0 7 1
A loadStatusNode() 0 13 2
C getReturnNode() 0 44 8
B loadReturnNode() 0 32 3
A getConteudo() 0 20 1
A envia() 0 17 2
B addInformacao() 0 30 2
A assinar() 0 17 2
B validar() 0 23 4

How to fix   Complexity   

Complex Class

Complex classes like Evento often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Evento, and based on these observations, apply Extract Interface, too.

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\Util;
33
use NFe\Exception\ValidationException;
34
use FR3D\XmlDSig\Adapter\AdapterInterface;
35
use FR3D\XmlDSig\Adapter\XmlseclibsAdapter;
36
37
class Evento extends Retorno
0 ignored issues
show
Complexity introduced by
This class has a complexity of 98 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...
38
{
39
40
    const VERSAO = '1.00';
41
42
    const TIPO_CANCELAMENTO = '110111';
43
    const TAG_RETORNO = 'retEvento';
44
    const TAG_RETORNO_ENVIO = 'retEnvEvento';
45
46
    private $id;
47
    private $orgao;
48
    private $identificador;
49
    private $chave;
50
    private $data;
51
    private $tipo;
52
    private $sequencia;
53
    private $descricao;
54
    private $numero;
55
    private $justificativa;
56
    private $email;
57
    private $modelo;
58
    private $informacao;
59
60 2
    public function __construct($evento = [])
61
    {
62 2
        parent::__construct($evento);
63 2
    }
64
65
    /**
66
     * Identificador da TAG a ser assinada, a regra de formação do Id é: "ID" +
67
     * tpEvento +  chave da NF-e + nSeqEvento
68
     */
69 1
    public function getID($normalize = false)
70
    {
71 1
        if (!$normalize) {
72 1
            return $this->id;
73
        }
74
        return 'ID'.$this->id;
75
    }
76
77 2
    public function setID($id)
78
    {
79 2
        $this->id = $id;
80 2
        return $this;
81
    }
82
83
    /**
84
     * Código do órgão de recepção do Evento. Utilizar a Tabela do IBGE
85
     * extendida, utilizar 91 para identificar o Ambiente Nacional
86
     */
87 1
    public function getOrgao($normalize = false)
88
    {
89 1
        if (!$normalize || is_numeric($this->orgao)) {
90 1
            return $this->orgao;
91
        }
92
93
        $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...
94
        return $db->getCodigoOrgao($this->orgao);
95
    }
96
97 2
    public function setOrgao($orgao)
98
    {
99 2
        $this->orgao = $orgao;
100 2
        return $this;
101
    }
102
103
    /**
104
     * Identificação do  autor do evento
105
     */
106 1
    public function getIdentificador($normalize = false)
107
    {
108 1
        if (!$normalize) {
109 1
            return $this->identificador;
110
        }
111
        return $this->identificador;
112
    }
113
114 2
    public function setIdentificador($identificador)
115
    {
116 2
        $this->identificador = $identificador;
117 2
        return $this;
118
    }
119
120
    /**
121
     * Chave de Acesso da NF-e vinculada ao evento
122
     */
123 1
    public function getChave($normalize = false)
124
    {
125 1
        if (!$normalize) {
126 1
            return $this->chave;
127
        }
128
        return $this->chave;
129
    }
130
131 2
    public function setChave($chave)
132
    {
133 2
        $this->chave = $chave;
134 2
        return $this;
135
    }
136
137
    /**
138
     * Data e Hora do Evento, formato UTC (AAAA-MM-DDThh:mm:ssTZD, onde TZD =
139
     * +hh:mm ou -hh:mm)
140
     */
141 1
    public function getData($normalize = false)
142
    {
143 1
        if (!$normalize) {
144 1
            return $this->data;
145
        }
146
        return Util::toDateTime($this->data);
147
    }
148
149 2
    public function setData($data)
150
    {
151 2
        if (!is_numeric($data)) {
152 2
            $data = strtotime($data);
153
        }
154 2
        $this->data = $data;
155 2
        return $this;
156
    }
157
158
    /**
159
     * Tipo do Evento
160
     */
161 1
    public function getTipo($normalize = false)
162
    {
163 1
        if (!$normalize) {
164 1
            return $this->tipo;
165
        }
166
        return $this->tipo;
167
    }
168
169 2
    public function setTipo($tipo)
170
    {
171 2
        $this->tipo = $tipo;
172 2
        return $this;
173
    }
174
175
    /**
176
     * Seqüencial do evento para o mesmo tipo de evento.  Para maioria dos
177
     * eventos será 1, nos casos em que possa existir mais de um evento, como é
178
     * o caso da carta de correção, o autor do evento deve numerar de forma
179
     * seqüencial.
180
     */
181 1
    public function getSequencia($normalize = false)
182
    {
183 1
        if (!$normalize) {
184 1
            return $this->sequencia;
185
        }
186
        return $this->sequencia;
187
    }
188
189 2
    public function setSequencia($sequencia)
190
    {
191 2
        $this->sequencia = $sequencia;
192 2
        return $this;
193
    }
194
195
    /**
196
     * Descrição do Evento
197
     */
198 1
    public function getDescricao($normalize = false)
199
    {
200 1
        if (!$normalize) {
201 1
            return $this->descricao;
202
        }
203
        return $this->descricao;
204
    }
205
206 2
    public function setDescricao($descricao)
207
    {
208 2
        $this->descricao = $descricao;
209 2
        return $this;
210
    }
211
212
    /**
213
     * Número do Protocolo de Status da NF-e. 1 posição (1 – Secretaria de
214
     * Fazenda Estadual 2 – Receita Federal); 2 posições ano; 10 seqüencial no
215
     * ano.
216
     */
217 1
    public function getNumero($normalize = false)
218
    {
219 1
        if (!$normalize) {
220 1
            return $this->numero;
221
        }
222
        return $this->numero;
223
    }
224
225 2
    public function setNumero($numero)
226
    {
227 2
        $this->numero = $numero;
228 2
        return $this;
229
    }
230
231
    /**
232
     * Justificativa do cancelamento
233
     */
234 1
    public function getJustificativa($normalize = false)
235
    {
236 1
        if (!$normalize) {
237 1
            return $this->justificativa;
238
        }
239
        return $this->justificativa;
240
    }
241
242 2
    public function setJustificativa($justificativa)
243
    {
244 2
        $this->justificativa = $justificativa;
245 2
        return $this;
246
    }
247
248
    /**
249
     * email do destinatário
250
     */
251 1
    public function getEmail($normalize = false)
252
    {
253 1
        if (!$normalize) {
254 1
            return $this->email;
255
        }
256 1
        return $this->email;
257
    }
258
259 2
    public function setEmail($email)
260
    {
261 2
        $this->email = $email;
262 2
        return $this;
263
    }
264
265
    /**
266
     * Código do modelo do Documento Fiscal. 55 = NF-e; 65 = NFC-e.
267
     * @param boolean $normalize informa se o modelo deve estar no formato do XML
268
     * @return mixed modelo do Envio
269
     */
270 1
    public function getModelo($normalize = false)
271
    {
272 1
        if (!$normalize) {
273 1
            return $this->modelo;
274
        }
275 1
        switch ($this->modelo) {
276 1
            case Nota::MODELO_NFE:
277 1
                return '55';
278 1
            case Nota::MODELO_NFCE:
279 1
                return '65';
280
        }
281 1
        return $this->modelo;
282
    }
283
284
    /**
285
     * Altera o valor do Modelo para o informado no parâmetro
286
     * @param mixed $modelo novo valor para Modelo
287
     * @return Envio A própria instância da classe
288
     */
289 2
    public function setModelo($modelo)
290
    {
291
        switch ($modelo) {
292 2
            case '55':
293 1
                $modelo = Nota::MODELO_NFE;
294 1
                break;
295 2
            case '65':
296 1
                $modelo = Nota::MODELO_NFCE;
297 1
                break;
298
        }
299 2
        $this->modelo = $modelo;
300 2
        return $this;
301
    }
302
303
    /**
304
     * Resposta de informação do evento
305
     */
306 1
    public function getInformacao()
307
    {
308 1
        return $this->informacao;
309
    }
310
311 2
    public function setInformacao($informacao)
312
    {
313 2
        $this->informacao = $informacao;
314 2
        return $this;
315
    }
316
317
    /**
318
     * Informa se a identificação é um CNPJ
319
     */
320
    public function isCNPJ()
321
    {
322
        return strlen($this->getIdentificador()) == 14;
323
    }
324
325
    /**
326
     * Informa se o lote já foi processado e já tem um protocolo
327
     */
328
    public function isProcessado()
329
    {
330
        return $this->getStatus() == '128';
331
    }
332
333
    /**
334
     * Informa se a nota foi cancelada com sucesso
335
     */
336
    public function isCancelado()
337
    {
338
        return in_array($this->getStatus(), ['135', '155']);
339
    }
340
341 1
    public function toArray($recursive = false)
342
    {
343 1
        $evento = parent::toArray($recursive);
344 1
        $evento['id'] = $this->getID();
345 1
        $evento['orgao'] = $this->getOrgao();
346 1
        $evento['identificador'] = $this->getIdentificador();
347 1
        $evento['chave'] = $this->getChave();
348 1
        $evento['data'] = $this->getData();
349 1
        $evento['tipo'] = $this->getTipo();
350 1
        $evento['sequencia'] = $this->getSequencia();
351 1
        $evento['descricao'] = $this->getDescricao();
352 1
        $evento['numero'] = $this->getNumero();
353 1
        $evento['justificativa'] = $this->getJustificativa();
354 1
        $evento['email'] = $this->getEmail();
355 1
        $evento['modelo'] = $this->getModelo();
356 1
        $evento['informacao'] = $this->getInformacao();
357 1
        return $evento;
358
    }
359
360 2
    public function fromArray($evento = [])
0 ignored issues
show
Complexity introduced by
This operation has 24576 execution paths which exceeds the configured maximum of 200.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

You can also find more information in the “Code” section of your repository.

Loading history...
361
    {
362 2
        if ($evento instanceof Evento) {
363 1
            $evento = $evento->toArray();
364 2
        } elseif (!is_array($evento)) {
365
            return $this;
366
        }
367 2
        parent::fromArray($evento);
368 2
        if (isset($evento['id'])) {
369
            $this->setID($evento['id']);
370
        } else {
371 2
            $this->setID(null);
372
        }
373 2
        if (isset($evento['orgao'])) {
374
            $this->setOrgao($evento['orgao']);
375
        } else {
376 2
            $this->setOrgao(null);
377
        }
378 2
        if (isset($evento['identificador'])) {
379
            $this->setIdentificador($evento['identificador']);
380
        } else {
381 2
            $this->setIdentificador(null);
382
        }
383 2
        if (isset($evento['chave'])) {
384
            $this->setChave($evento['chave']);
385
        } else {
386 2
            $this->setChave(null);
387
        }
388 2
        if (isset($evento['data'])) {
389 1
            $this->setData($evento['data']);
390
        } else {
391 2
            $this->setData(null);
392
        }
393 2
        if (!isset($evento['tipo'])) {
394 2
            $this->setTipo(self::TIPO_CANCELAMENTO);
395
        } else {
396 1
            $this->setTipo($evento['tipo']);
397
        }
398 2
        if (!isset($evento['sequencia'])) {
399 2
            $this->setSequencia(1);
400
        } else {
401 1
            $this->setSequencia($evento['sequencia']);
402
        }
403 2
        if (!isset($evento['descricao'])) {
404 2
            $this->setDescricao('Cancelamento');
405
        } else {
406 1
            $this->setDescricao($evento['descricao']);
407
        }
408 2
        if (isset($evento['numero'])) {
409
            $this->setNumero($evento['numero']);
410
        } else {
411 2
            $this->setNumero(null);
412
        }
413 2
        if (isset($evento['justificativa'])) {
414
            $this->setJustificativa($evento['justificativa']);
415
        } else {
416 2
            $this->setJustificativa(null);
417
        }
418 2
        if (isset($evento['email'])) {
419 1
            $this->setEmail($evento['email']);
420
        } else {
421 2
            $this->setEmail(null);
422
        }
423 2
        if (isset($evento['modelo'])) {
424 1
            $this->setModelo($evento['modelo']);
425
        } else {
426 2
            $this->setModelo(null);
427
        }
428 2
        if (isset($evento['informacao'])) {
429
            $this->setInformacao($evento['informacao']);
430
        } else {
431 2
            $this->setInformacao(null);
432
        }
433 2
        return $this;
434
    }
435
436
    /**
437
     * Gera o ID, a regra de formação do Id é: "ID" +
438
     * tpEvento +  chave da NF-e + nSeqEvento
439
     */
440
    public function gerarID()
441
    {
442
        $id = sprintf(
443
            '%s%s%02d',
444
            $this->getTipo(true),
445
            $this->getChave(true),
446
            $this->getSequencia(true)
447
        );
448
        return $id;
449
    }
450
451
    public function getNode($name = null)
452
    {
453
        $this->setID($this->gerarID());
454
455
        $dom = new \DOMDocument('1.0', 'UTF-8');
456
        $element = $dom->createElement(is_null($name)?'evento':$name);
457
        $element->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', Nota::PORTAL);
458
        $versao = $dom->createAttribute('versao');
459
        $versao->value = self::VERSAO;
460
        $element->appendChild($versao);
461
462
        $info = $dom->createElement('infEvento');
463
        $dom = $element->ownerDocument;
464
        $id = $dom->createAttribute('Id');
465
        $id->value = $this->getID(true);
466
        $info->appendChild($id);
467
        
468
        Util::appendNode($info, 'cOrgao', $this->getOrgao(true));
469
        Util::appendNode($info, 'tpAmb', $this->getAmbiente(true));
470
        if ($this->isCNPJ()) {
471
            Util::appendNode($info, 'CNPJ', $this->getIdentificador(true));
472
        } else {
473
            Util::appendNode($info, 'CPF', $this->getIdentificador(true));
474
        }
475
        Util::appendNode($info, 'chNFe', $this->getChave(true));
476
        Util::appendNode($info, 'dhEvento', $this->getData(true));
477
        Util::appendNode($info, 'tpEvento', $this->getTipo(true));
478
        Util::appendNode($info, 'nSeqEvento', $this->getSequencia(true));
479
        Util::appendNode($info, 'verEvento', self::VERSAO);
480
481
        $detalhes = $dom->createElement('detEvento');
482
        $versao = $dom->createAttribute('versao');
483
        $versao->value = self::VERSAO;
484
        $detalhes->appendChild($versao);
485
486
        Util::appendNode($detalhes, 'descEvento', $this->getDescricao(true));
487
        Util::appendNode($detalhes, 'nProt', $this->getNumero(true));
488
        Util::appendNode($detalhes, 'xJust', $this->getJustificativa(true));
489
        $info->appendChild($detalhes);
490
491
        $element->appendChild($info);
492
        $dom->appendChild($element);
493
        return $element;
494
    }
495
496
    public function loadNode($element, $name = null)
497
    {
498
        $root = $element;
499
        $element = Util::findNode($element, 'evento');
500
        $name = is_null($name)?'infEvento':$name;
501
        $element = Util::findNode($element, $name);
502
        $this->setOrgao(
503
            Util::loadNode(
504
                $element,
505
                'cOrgao',
506
                'Tag "cOrgao" não encontrada no Evento'
507
            )
508
        );
509
        $this->setAmbiente(
510
            Util::loadNode(
511
                $element,
512
                'tpAmb',
513
                'Tag "tpAmb" não encontrada no Evento'
514
            )
515
        );
516
        if (Util::nodeExists($element, 'CNPJ')) {
517
            $this->setIdentificador(
518
                Util::loadNode(
519
                    $element,
520
                    'CNPJ',
521
                    'Tag "CNPJ" não encontrada no Evento'
522
                )
523
            );
524
        } else {
525
            $this->setIdentificador(
526
                Util::loadNode(
527
                    $element,
528
                    'CPF',
529
                    'Tag "CPF" não encontrada no Evento'
530
                )
531
            );
532
        }
533
        $this->setChave(
534
            Util::loadNode(
535
                $element,
536
                'chNFe',
537
                'Tag "chNFe" não encontrada no Evento'
538
            )
539
        );
540
        $this->setData(
541
            Util::loadNode(
542
                $element,
543
                'dhEvento',
544
                'Tag "dhEvento" não encontrada no Evento'
545
            )
546
        );
547
        $this->setTipo(
548
            Util::loadNode(
549
                $element,
550
                'tpEvento',
551
                'Tag "tpEvento" não encontrada no Evento'
552
            )
553
        );
554
        $this->setSequencia(
555
            Util::loadNode(
556
                $element,
557
                'nSeqEvento',
558
                'Tag "nSeqEvento" não encontrada no Evento'
559
            )
560
        );
561
562
        $detalhes = Util::findNode($element, 'detEvento');
563
        $this->setDescricao(
564
            Util::loadNode(
565
                $detalhes,
566
                'descEvento',
567
                'Tag "descEvento" não encontrada no Evento'
568
            )
569
        );
570
        $this->setNumero(
571
            Util::loadNode(
572
                $detalhes,
573
                'nProt',
574
                'Tag "nProt" não encontrada no Evento'
575
            )
576
        );
577
        $this->setJustificativa(
578
            Util::loadNode(
579
                $detalhes,
580
                'xJust',
581
                'Tag "xJust" não encontrada no Evento'
582
            )
583
        );
584
        $informacao = null;
585
        if (Util::nodeExists($root, 'procEventoNFe')) {
586
            $informacao = $this->loadResponse($root);
587
        }
588
        $this->setInformacao($informacao);
589
        return $element;
590
    }
591
592
    public function loadResponse($resp)
593
    {
594
        $retorno = new Evento();
595
        $retorno->loadReturnNode($resp);
596
        $this->setInformacao($retorno);
597
        return $retorno;
598
    }
599
600
    public function loadStatusNode($element, $name = null)
601
    {
602
        $name = is_null($name)?self::TAG_RETORNO_ENVIO:$name;
603
        $element = parent::loadNode($element, $name);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (loadNode() instead of loadStatusNode()). Are you sure this is correct? If so, you might want to change this to $this->loadNode().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
604
        $this->setOrgao(
605
            Util::loadNode(
606
                $element,
607
                'cOrgao',
608
                'Tag "cOrgao" do campo "Orgao" não encontrada'
609
            )
610
        );
611
        return $element;
612
    }
613
614
    public function getReturnNode()
615
    {
616
        $outros = parent::getNode('infEvento');
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getNode() instead of getReturnNode()). Are you sure this is correct? If so, you might want to change this to $this->getNode().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
617
        $element = $this->getNode(self::TAG_RETORNO);
618
        $dom = $element->ownerDocument;
619
        $element->removeAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns');
620
        $info = $dom->getElementsByTagName('infEvento')->item(0);
621
        $info->removeAttribute('Id');
622
        $remove_tags = ['detEvento', 'verEvento', 'dhEvento', 'CNPJ', 'CPF', 'cOrgao'];
623
        foreach ($remove_tags as $key) {
624
            $_fields = $info->getElementsByTagName($key);
625
            if ($_fields->length == 0) {
626
                continue;
627
            }
628
            $node = $_fields->item(0);
629
            $info->removeChild($node);
630
        }
631
        $chave = $info->getElementsByTagName('chNFe')->item(0);
632
        foreach ($outros->childNodes as $node) {
633
            $node = $dom->importNode($node, true);
634
            $list = $info->getElementsByTagName($node->nodeName);
635
            if ($list->length == 1) {
636
                continue;
637
            }
638
            $info->insertBefore($node, $chave);
639
        }
640
        $status = $info->getElementsByTagName('cStat')->item(0);
641
        Util::appendNode($info, 'cOrgao', $this->getOrgao(true), $status);
642
        $sequencia = $info->getElementsByTagName('nSeqEvento')->item(0);
643
        Util::appendNode($info, 'xEvento', $this->getDescricao(true), $sequencia);
644
        if (!is_null($this->getIdentificador())) {
645
            if ($this->isCNPJ()) {
646
                Util::appendNode($info, 'CNPJDest', $this->getIdentificador(true));
647
            } else {
648
                Util::appendNode($info, 'CPFDest', $this->getIdentificador(true));
649
            }
650
        }
651
        if (!is_null($this->getEmail())) {
652
            Util::appendNode($info, 'emailDest', $this->getEmail(true));
653
        }
654
        Util::appendNode($info, 'dhRegEvento', $this->getData(true));
655
        Util::appendNode($info, 'nProt', $this->getNumero(true));
656
        return $element;
657
    }
658
659
    public function loadReturnNode($element, $name = null)
660
    {
661
        $element = Util::findNode($element, Evento::TAG_RETORNO);
662
        $name = is_null($name)?'infEvento':$name;
663
        $element = parent::loadNode($element, $name);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (loadNode() instead of loadReturnNode()). Are you sure this is correct? If so, you might want to change this to $this->loadNode().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
664
        $this->setOrgao(
665
            Util::loadNode(
666
                $element,
667
                'cOrgao',
668
                'Tag "cOrgao" do campo "Orgao" não encontrada'
669
            )
670
        );
671
        $this->setChave(Util::loadNode($element, 'chNFe'));
672
        $this->setTipo(Util::loadNode($element, 'tpEvento'));
673
        $this->setDescricao(Util::loadNode($element, 'xEvento'));
674
        $this->setSequencia(Util::loadNode($element, 'nSeqEvento'));
675
        if ($element->getElementsByTagName('CNPJDest')->length > 0) {
676
            $this->setIdentificador(Util::loadNode($element, 'CNPJDest'));
677
        } else {
678
            $this->setIdentificador(Util::loadNode($element, 'CPFDest'));
679
        }
680
        $this->setEmail(Util::loadNode($element, 'emailDest'));
681
        $this->setData(
682
            Util::loadNode(
683
                $element,
684
                'dhRegEvento',
685
                'Tag "dhRegEvento" do campo "Data" não encontrada'
686
            )
687
        );
688
        $this->setNumero(Util::loadNode($element, 'nProt'));
689
        return $element;
690
    }
691
692
    private function getConteudo($dom)
693
    {
694
        $config = SEFAZ::getInstance()->getConfiguracao();
0 ignored issues
show
Unused Code introduced by
$config is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
695
        $dob = new \DOMDocument('1.0', 'UTF-8');
696
        $envio = $dob->createElement('envEvento');
697
        $envio->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', Nota::PORTAL);
698
        $versao = $dob->createAttribute('versao');
699
        $versao->value = self::VERSAO;
700
        $envio->appendChild($versao);
701
        Util::appendNode($envio, 'idLote', self::genLote());
702
        // Corrige xmlns:default
703
        // $data = $dob->importNode($dom->documentElement, true);
704
        // $envio->appendChild($data);
705
        Util::appendNode($envio, 'evento', 0);
706
        $dob->appendChild($envio);
707
        // Corrige xmlns:default
708
        // return $dob;
709
        $xml = $dob->saveXML($dob->documentElement);
710
        return str_replace('<evento>0</evento>', $dom->saveXML($dom->documentElement), $xml);
711
    }
712
713
    public function envia($dom)
714
    {
715
        $envio = new Envio();
716
        $envio->setServico(Envio::SERVICO_EVENTO);
717
        $envio->setAmbiente($this->getAmbiente());
718
        $envio->setModelo($this->getModelo());
719
        $envio->setEmissao(Nota::EMISSAO_NORMAL);
720
        $this->setVersao($envio->getVersao());
721
        $dom = $this->validar($dom);
722
        $envio->setConteudo($this->getConteudo($dom));
723
        $resp = $envio->envia();
724
        $this->loadStatusNode($resp);
725
        if (!$this->isProcessado()) {
726
            throw new \Exception($this->getMotivo(), $this->getStatus());
727
        }
728
        return $this->loadResponse($resp);
729
    }
730
731
    /**
732
     * Adiciona a informação no XML do evento
733
     */
734
    public function addInformacao($dom)
735
    {
736
        if (is_null($this->getInformacao())) {
737
            throw new \Exception('A informação não foi informado no evento "'.$this->getID().'"', 404);
738
        }
739
        $evento = $dom->getElementsByTagName('evento')->item(0);
740
        // Corrige xmlns:default
741
        $evento_xml = $dom->saveXML($evento);
742
743
        $element = $dom->createElement('procEventoNFe');
744
        $element->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', Nota::PORTAL);
745
        $versao = $dom->createAttribute('versao');
746
        $versao->value = self::VERSAO;
747
        $element->appendChild($versao);
748
        $dom->removeChild($evento);
749
        // Corrige xmlns:default
750
        $evento = $dom->createElement('evento', 0);
751
752
        $element->appendChild($evento);
753
        $info = $this->getInformacao()->getReturnNode();
754
        $info = $dom->importNode($info, true);
755
        $element->appendChild($info);
756
        $dom->appendChild($element);
757
        // Corrige xmlns:default
758
        $xml = $dom->saveXML();
759
        $xml = str_replace('<evento>0</evento>', $evento_xml, $xml);
760
        $dom->loadXML($xml);
761
762
        return $dom;
763
    }
764
765
    /**
766
     * Assina o XML com a assinatura eletrônica do tipo A1
767
     */
768
    public function assinar($dom = null)
769
    {
770
        if (is_null($dom)) {
771
            $xml = $this->getNode();
772
            $dom = $xml->ownerDocument;
773
        }
774
        $config = SEFAZ::getInstance()->getConfiguracao();
775
        $config->verificaValidadeCertificado();
776
777
        $adapter = new XmlseclibsAdapter();
778
        $adapter->setPrivateKey($config->getChavePrivada());
779
        $adapter->setPublicKey($config->getChavePublica());
780
        $adapter->addTransform(AdapterInterface::ENVELOPED);
781
        $adapter->addTransform(AdapterInterface::XML_C14N);
782
        $adapter->sign($dom, 'infEvento');
783
        return $dom;
784
    }
785
786
    /**
787
     * Valida o documento após assinar
788
     */
789
    public function validar($dom)
790
    {
791
        $dom->loadXML($dom->saveXML());
792
        $xsd_path = dirname(__DIR__) . '/Core/schema';
793
        $xsd_file = $xsd_path . '/cancelamento/eventoCancNFe_v1.00.xsd';
794
        if (!file_exists($xsd_file)) {
795
            throw new \Exception(sprintf('O arquivo "%s" de esquema XSD não existe!', $xsd_file), 404);
796
        }
797
        // Enable user error handling
798
        $save = libxml_use_internal_errors(true);
799
        if ($dom->schemaValidate($xsd_file)) {
800
            libxml_use_internal_errors($save);
801
            return $dom;
802
        }
803
        $msg = [];
804
        $errors = libxml_get_errors();
805
        foreach ($errors as $error) {
806
            $msg[] = 'Não foi possível validar o XML: '.$error->message;
807
        }
808
        libxml_clear_errors();
809
        libxml_use_internal_errors($save);
810
        throw new ValidationException($msg);
811
    }
812
}
813