Completed
Push — master ( e4a42c...744e24 )
by Roberto
03:45
created

Tools   F

Complexity

Total Complexity 87

Size/Duplication

Total Lines 1024
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 11

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 87
lcom 2
cbo 11
dl 0
loc 1024
ccs 0
cts 583
cp 0
rs 3.9999
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A assina() 0 4 1
C sefazEnvia() 0 73 7
B sefazConsultaRecibo() 0 50 4
B sefazConsultaChave() 0 50 4
B sefazStatus() 0 44 4
B sefazInutiliza() 0 91 6
B sefazCancela() 0 34 5
B enviaMail() 0 25 2
C zSefazEvento() 0 89 9
B zAddProtMsg() 0 36 1
C zTpEv() 0 61 12
B validarXml() 0 24 4
B sefazCartaCorrecao() 0 60 6
D addProtocolo() 0 113 10
C addCancelamento() 0 83 12

How to fix   Complexity   

Complex Class

Complex classes like Tools 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 Tools, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace NFePHP\CTe;
4
5
/**
6
 * Classe principal para a comunicação com a SEFAZ
7
 *
8
 * @category  Library
9
 * @package   nfephp-org/sped-cte
10
 * @copyright 2009-2016 NFePHP
11
 * @license   http://www.gnu.org/licenses/lesser.html LGPL v3
12
 * @link      http://github.com/nfephp-org/sped-cte for the canonical source repository
13
 * @author    Roberto L. Machado <linux.rlm at gmail dot com>
14
 *
15
 *        CONTRIBUIDORES (em ordem alfabetica):
16
 *
17
 *          Maison K. Sakamoto <maison.sakamoto at gmail do com>
18
 *          Samuel M Basso <samuelbasso at gmail do com>
19
 */
20
21
use NFePHP\Common\Base\BaseTools;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, NFePHP\CTe\BaseTools.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
22
use NFePHP\Common\LotNumber\LotNumber;
23
use NFePHP\Common\Strings\Strings;
24
use NFePHP\Common\Files;
25
use NFePHP\Common\Exception;
26
use NFePHP\CTe\Auxiliar\Response;
27
use NFePHP\CTe\Auxiliar\IdentifyCTe;
28
use NFePHP\Common\Dom\ValidXsd;
29
use NFePHP\Common\Dom\Dom;
30
use NFePHP\Common\DateTime\DateTime;
31
32 3
if (!defined('NFEPHP_ROOT')) {
33 3
    define('NFEPHP_ROOT', dirname(dirname(__FILE__)));
34 2
}
35
36
class Tools extends BaseTools
37
{
38
    /**
39
     * urlPortal
40
     * Instância do WebService
41
     *
42
     * @var string
43
     */
44
    protected $urlPortal = 'http://www.portalfiscal.inf.br/cte';
45
    
46
    /**
47
     * aLastRetEvent
48
     *
49
     * @var array
50
     */
51
    private $aLastRetEvent = array();
52
53
    /**
54
     * @var string
55
     */
56
    public $erros = array();
57
58
    /**
59
     * modelo 57 (CTE-e) é um documento fiscal eletrônico,
60
     * instituído pelo AJUSTE SINIEF 09/07 (25/10/2007)
61
     * @var modelo
62
     */
63
    protected $modelo = '57';
64
65
    /**
66
     * assina
67
     * @param  string  $xml
68
     * @param  boolean $saveFile
69
     * @return string
70
     * @throws Exception\RuntimeException
71
     */
72
    public function assina($xml = '', $saveFile = false)
73
    {
74
        return $this->assinaDoc($xml, 'cte', 'infCte', $saveFile);
75
    }
76
77
    /**
78
     * Transmite o xml para a sefaz
79
     * @param string|array $aXml
80
     * @param string $tpAmb
81
     * @param string $idLote
82
     * @param array $aRetorno
83
     * @param int $indSinc
84
     * @param boolean $compactarZip
85
     * @return string
86
     * @throws Exception\InvalidArgumentException
87
     * @throws Exception\RuntimeException
88
     */
89
    public function sefazEnvia(
90
        $aXml,
91
        $tpAmb = '2',
92
        $idLote = '',
93
        &$aRetorno = array(),
94
        $indSinc = 0,
0 ignored issues
show
Unused Code introduced by
The parameter $indSinc 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...
95
        $compactarZip = false
0 ignored issues
show
Unused Code introduced by
The parameter $compactarZip 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...
96
    ) {
97
        $sxml = $aXml;
98
        if (empty($aXml)) {
99
            $msg = "Pelo menos uma CTe deve ser informada.";
100
            throw new Exception\InvalidArgumentException($msg);
101
        }
102
        if (is_array($aXml)) {
103
            if (count($aXml) > 1) {
104
                //multiplas cte, não pode ser sincrono
105
                $indSinc = 0;
0 ignored issues
show
Unused Code introduced by
$indSinc 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...
106
            }
107
            $sxml = implode("", $sxml);
108
        }
109
        $sxml = preg_replace("/<\?xml.*\?>/", "", $sxml);
110
        $siglaUF = $this->aConfig['siglaUF'];
111
112
        if ($tpAmb == '') {
113
            $tpAmb = $this->aConfig['tpAmb'];
114
        }
115
        if ($idLote == '') {
116
            $idLote = LotNumber::geraNumLote(15);
117
        }
118
        //carrega serviço
119
        $servico = 'CteRecepcao';
120
        $this->zLoadServico(
121
            'cte',
122
            $servico,
123
            $siglaUF,
124
            $tpAmb
125
        );
126
127
        if ($this->urlService == '') {
128
            $msg = "O envio de lote não está disponível na SEFAZ $siglaUF!!!";
129
            throw new Exception\RuntimeException($msg);
130
        }
131
132
        // Montagem dos dados da mensagem SOAP
133
        $dados = "<cteDadosMsg xmlns=\"$this->urlNamespace\">"
134
            . "<enviCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
135
            . "<idLote>$idLote</idLote>"
136
            . "$sxml"
137
            . "</enviCTe>"
138
            . "</cteDadosMsg>";
139
        // Envia dados via SOAP
140
        $retorno = $this->oSoap->send(
141
            $this->urlService,
142
            $this->urlNamespace,
143
            $this->urlHeader,
144
            $dados,
145
            $this->urlMethod
146
        );
147
148
        $lastMsg = $this->oSoap->lastMsg;
149
        $this->soapDebug = $this->oSoap->soapDebug;
0 ignored issues
show
Bug introduced by
The property soapDebug does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
150
        //salva mensagens
151
        $filename = "$idLote-enviCTe.xml";
152
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
153
        $filename = "$idLote-retEnviCTe.xml";
154
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
155
        //tratar dados de retorno
156
157
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
158
        //caso o envio seja recebido com sucesso mover a CTe da pasta
159
        //das assinadas para a pasta das enviadas
160
        return (string) $retorno;
161
    }
162
163
    /**
164
     * Consulta o recibo na sefaz
165
     *
166
     * @param type $recibo
167
     * @param type $tpAmb
168
     * @param type $aRetorno
169
     * @return type
170
     * @throws Exception\InvalidArgumentException
171
     * @throws Exception\RuntimeException
172
     */
173
    public function sefazConsultaRecibo($recibo = '', $tpAmb = '2', &$aRetorno = array())
174
    {
175
        if ($recibo == '') {
176
            $msg = "Deve ser informado um recibo.";
177
            throw new Exception\InvalidArgumentException($msg);
178
        }
179
        if ($tpAmb == '') {
180
            $tpAmb = $this->aConfig['tpAmb'];
181
        }
182
        $siglaUF = $this->aConfig['siglaUF'];
183
        //carrega serviço
184
        $servico = 'CteRetRecepcao';
185
        $this->zLoadServico(
186
            'cte',
187
            $servico,
188
            $siglaUF,
189
            $tpAmb
190
        );
191
        if ($this->urlService == '') {
192
            $msg = "A consulta de CTe não está disponível na SEFAZ $siglaUF!!!";
193
            throw new Exception\RuntimeException($msg);
194
        }
195
        $cons = "<consReciCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
196
            . "<tpAmb>$tpAmb</tpAmb>"
197
            . "<nRec>$recibo</nRec>"
198
            . "</consReciCTe>";
199
        //montagem dos dados da mensagem SOAP
200
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$cons</cteDadosMsg>";
201
        //envia a solicitação via SOAP
202
        $retorno = $this->oSoap->send(
203
            $this->urlService,
204
            $this->urlNamespace,
205
            $this->urlHeader,
206
            $body,
207
            $this->urlMethod
208
        );
209
        $lastMsg = $this->oSoap->lastMsg;
210
        $this->soapDebug = $this->oSoap->soapDebug;
211
        //salva mensagens
212
        $filename = "$recibo-consReciCTe.xml";
213
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
214
        $filename = "$recibo-retConsReciCTe.xml";
215
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
216
        //tratar dados de retorno
217
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
218
        //podem ser retornados nenhum, um ou vários protocolos
219
        //caso existam protocolos protocolar as CTe e movelas-las para a
220
        //pasta enviadas/aprovadas/anomes
221
        return (string) $retorno;
222
    }
223
224
    /**
225
     * consulta a chave de acesso do CT-e
226
     *
227
     * @param type $chave
228
     * @param type $tpAmb
229
     * @param type $aRetorno
230
     * @return type
231
     * @throws Exception\InvalidArgumentException
232
     * @throws Exception\RuntimeException
233
     */
234
    public function sefazConsultaChave($chave = '', $tpAmb = '2', &$aRetorno = array())
235
    {
236
        $chCTe = preg_replace('/[^0-9]/', '', $chave);
237
        if (strlen($chCTe) != 44) {
238
            $msg = "Uma chave de 44 dígitos da CTe deve ser passada.";
239
            throw new Exception\InvalidArgumentException($msg);
240
        }
241
        if ($tpAmb == '') {
242
            $tpAmb = $this->aConfig['tpAmb'];
243
        }
244
        $cUF = substr($chCTe, 0, 2);
245
        $siglaUF = $this->zGetSigla($cUF);
246
        //carrega serviço
247
        $servico = 'CteConsultaProtocolo';
248
        $this->zLoadServico(
249
            'cte',
250
            $servico,
251
            $siglaUF,
252
            $tpAmb
253
        );
254
        if ($this->urlService == '') {
255
            $msg = "A consulta de CTe não está disponível na SEFAZ $siglaUF!!!";
256
            throw new Exception\RuntimeException($msg);
257
        }
258
        $cons = "<consSitCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
259
            . "<tpAmb>$tpAmb</tpAmb>"
260
            . "<xServ>CONSULTAR</xServ>"
261
            . "<chCTe>$chCTe</chCTe>"
262
            . "</consSitCTe>";
263
        //montagem dos dados da mensagem SOAP
264
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$cons</cteDadosMsg>";
265
        //envia a solicitação via SOAP
266
        $retorno = $this->oSoap->send(
267
            $this->urlService,
268
            $this->urlNamespace,
269
            $this->urlHeader,
270
            $body,
271
            $this->urlMethod
272
        );
273
        $lastMsg = $this->oSoap->lastMsg;
274
        $this->soapDebug = $this->oSoap->soapDebug;
275
        //salva mensagens
276
        $filename = "$chCTe-consSitCTe.xml";
277
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
278
        $filename = "$chCTe-retConsSitCTe.xml";
279
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
280
        //tratar dados de retorno
281
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
282
        return (string) $retorno;
283
    }
284
285
    /**
286
     * consulta disponibilidade do serviço web service da sefaz
287
     *
288
     * @param type $siglaUF
289
     * @param type $tpAmb
290
     * @param type $aRetorno
291
     * @return type
292
     * @throws Exception\RuntimeException
293
     */
294
    public function sefazStatus($siglaUF = '', $tpAmb = '2', &$aRetorno = array())
295
    {
296
        if ($tpAmb == '') {
297
            $tpAmb = $this->aConfig['tpAmb'];
298
        }
299
        if ($siglaUF == '') {
300
            $siglaUF = $this->aConfig['siglaUF'];
301
        }
302
        //carrega serviço
303
        $servico = 'CteStatusServico';
304
        $this->zLoadServico(
305
            'cte',
306
            $servico,
307
            $siglaUF,
308
            $tpAmb
309
        );
310
        if ($this->urlService == '') {
311
            $msg = "O status não está disponível na SEFAZ $siglaUF!!!";
312
            throw new Exception\RuntimeException($msg);
313
        }
314
        $cons = "<consStatServCte xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
315
            . "<tpAmb>$tpAmb</tpAmb>"
316
            . "<xServ>STATUS</xServ></consStatServCte>";
317
        //montagem dos dados da mensagem SOAP
318
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$cons</cteDadosMsg>";
319
        //consome o webservice e verifica o retorno do SOAP
320
        $retorno = $this->oSoap->send(
321
            $this->urlService,
322
            $this->urlNamespace,
323
            $this->urlHeader,
324
            $body,
325
            $this->urlMethod
326
        );
327
        $lastMsg = $this->oSoap->lastMsg;
328
        $this->soapDebug = $this->oSoap->soapDebug;
329
        $datahora = date('Ymd_His');
330
        $filename = $siglaUF."_"."$datahora-consStatServCte.xml";
331
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
332
        $filename = $siglaUF."_"."$datahora-retConsStatServCte.xml";
333
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
334
        //tratar dados de retorno
335
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
336
        return (string) $retorno;
337
    }
338
339
    /**
340
     * Inutiza sequencia de numeracao
341
     *
342
     * @param type $nAno
0 ignored issues
show
Bug introduced by
There is no parameter named $nAno. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
343
     * @param type $nSerie
344
     * @param type $nIni
345
     * @param type $nFin
346
     * @param type $xJust
347
     * @param type $tpAmb
348
     * @param type $aRetorno
349
     * @return boolean
350
     * @throws Exception\RuntimeException
351
     * @throws Exception\InvalidArgumentException
352
     */
353
    public function sefazInutiliza(
354
        $nSerie = '1',
355
        $nIni = '',
356
        $nFin = '',
357
        $xJust = '',
358
        $tpAmb = '2',
359
        &$aRetorno = array(),
360
        $salvarMensagens = true
361
    ) {
362
        $nSerie = (integer) $nSerie;
363
        $nIni = (integer) $nIni;
364
        $nFin = (integer) $nFin;
365
        $xJust = Strings::cleanString($xJust);
366
        $this->zValidParamInut($xJust, $nSerie, $nIni, $nFin);
0 ignored issues
show
Bug introduced by
The method zValidParamInut() does not seem to exist on object<NFePHP\CTe\Tools>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
367
        if ($tpAmb == '') {
368
            $tpAmb = $this->aConfig['tpAmb'];
369
        }
370
        // Identificação do serviço
371
        $servico = 'CteInutilizacao';
0 ignored issues
show
Unused Code introduced by
$servico 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...
372
        //monta serviço
373
        $siglaUF = $this->aConfig['siglaUF'];
374
        //carrega serviço
375
        $servico = 'CteInutilizacao';
376
        $this->zLoadServico(
377
            'cte',
378
            $servico,
379
            $siglaUF,
380
            $tpAmb
381
        );
382
        if ($this->urlService == '') {
383
            $msg = "A inutilização não está disponível na SEFAZ $siglaUF!!!";
384
            throw new Exception\RuntimeException($msg);
385
        }
386
        //montagem dos dados da mensagem SOAP
387
        $cnpj = $this->aConfig['cnpj'];
388
        $sAno = (string) date('y');
389
        $sSerie = str_pad($nSerie, 3, '0', STR_PAD_LEFT);
390
        $sInicio = str_pad($nIni, 9, '0', STR_PAD_LEFT);
391
        $sFinal = str_pad($nFin, 9, '0', STR_PAD_LEFT);
392
        //limpa os caracteres indesejados da justificativa
393
        $xJust = Strings::cleanString($xJust);
394
        // Identificador da TAG a ser assinada formada com Código da UF +
395
        // precedida do literal “ID”
396
        // 41 posições
397
        $id = 'ID'.$this->urlcUF.$cnpj.'57'.$sSerie.$sInicio.$sFinal;
398
        // Montagem do corpo da mensagem
399
        $dXML = "<inutCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
400
            ."<infInut Id=\"$id\">"
401
            ."<tpAmb>$tpAmb</tpAmb>"
402
            ."<xServ>INUTILIZAR</xServ>"
403
            ."<cUF>$this->urlcUF</cUF>"
404
            ."<ano>$sAno</ano>"
405
            ."<CNPJ>$cnpj</CNPJ>"
406
            ."<mod>57</mod>"
407
            ."<serie>$nSerie</serie>"
408
            ."<nCTIni>$nIni</nCTIni>"
409
            ."<nCTFin>$nFin</nCTFin>"
410
            ."<xJust>$xJust</xJust>"
411
            ."</infInut></inutCTe>";
412
        //assina a solicitação de inutilização
413
        $signedMsg = $this->oCertificate->signXML($dXML, 'infInut');
414
        $signedMsg = Strings::clearXml($signedMsg, true);
415
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$signedMsg</cteDadosMsg>";
416
        //envia a solicitação via SOAP
417
        $retorno = $this->oSoap->send(
418
            $this->urlService,
419
            $this->urlNamespace,
420
            $this->urlHeader,
421
            $body,
422
            $this->urlMethod
423
        );
424
        $lastMsg = $this->oSoap->lastMsg;
425
        $this->soapDebug = $this->oSoap->soapDebug;
426
        //salva mensagens
427
        if ($salvarMensagens) {
428
            $filename = "$sAno-$this->modelo-$sSerie-".$sInicio."_".$sFinal."-inutCTe.xml";
429
            $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
430
            $filename = "$sAno-$this->modelo-$sSerie-".$sInicio."_".$sFinal."-retInutCTe.xml";
431
            $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
432
        }
433
        //tratar dados de retorno
434
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
435
        if ($aRetorno['cStat'] == '102') {
436
            $retorno = $this->zAddProtMsg('ProcInutCTe', 'inutCTe', $signedMsg, 'retInutCTe', $retorno);
437
            if ($salvarMensagens) {
438
                $filename = "$sAno-$this->modelo-$sSerie-".$sInicio."_".$sFinal."-procInutCTe.xml";
439
                $this->zGravaFile('cte', $tpAmb, $filename, $retorno, 'inutilizadas');
440
            }
441
        }
442
        return (string) $retorno;
443
    }
444
445
    /**
446
     * Cancelamento de numero CT-e
447
     *
448
     * @param type $chCTe
449
     * @param type $tpAmb
450
     * @param type $xJust
451
     * @param type $nProt
452
     * @param type $aRetorno
453
     * @return type
454
     * @throws Exception\InvalidArgumentException
455
     */
456
    public function sefazCancela($chCTe = '', $tpAmb = '2', $xJust = '', $nProt = '', &$aRetorno = array())
457
    {
458
        $chCTe = preg_replace('/[^0-9]/', '', $chCTe);
459
        $nProt = preg_replace('/[^0-9]/', '', $nProt);
460
        $xJust = Strings::cleanString($xJust);
461
        //validação dos dados de entrada
462
        if (strlen($chCTe) != 44) {
463
            $msg = "Uma chave de CTe válida não foi passada como parâmetro $chCTe.";
464
            throw new Exception\InvalidArgumentException($msg);
465
        }
466
        if ($nProt == '') {
467
            $msg = "Não foi passado o numero do protocolo!!";
468
            throw new Exception\InvalidArgumentException($msg);
469
        }
470
        if (strlen($xJust) < 15 || strlen($xJust) > 255) {
471
            $msg = "A justificativa deve ter pelo menos 15 digitos e no máximo 255!!";
472
            throw new Exception\InvalidArgumentException($msg);
473
        }
474
        $siglaUF = $this->zGetSigla(substr($chCTe, 0, 2));
475
476
        //estabelece o codigo do tipo de evento CANCELAMENTO
477
        $tpEvento = '110111';
478
        $descEvento = 'Cancelamento';
479
        $nSeqEvento = 1;
480
        //monta mensagem
481
        $tagAdic = "<evCancCTe>"
482
            . "<descEvento>$descEvento</descEvento>"
483
            . "<nProt>$nProt</nProt>"
484
            . "<xJust>$xJust</xJust>"
485
            . "</evCancCTe>";
486
        $retorno = $this->zSefazEvento($siglaUF, $chCTe, $tpAmb, $tpEvento, $nSeqEvento, $tagAdic);
0 ignored issues
show
Bug introduced by
It seems like $chCTe defined by preg_replace('/[^0-9]/', '', $chCTe) on line 458 can also be of type array<integer,string>; however, NFePHP\CTe\Tools::zSefazEvento() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
487
        $aRetorno = $this->aLastRetEvent;
488
        return $retorno;
489
    }
490
491
    public function enviaMail($pathXml = '', $aMails = array(), $templateFile = '', $comPdf = false, $pathPdf = '')
0 ignored issues
show
Unused Code introduced by
The parameter $templateFile 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...
492
    {
493
        $mail = new Mail($this->aMailConf);
494
        // Se não for informado o caminho do PDF, monta um através do XML
495
        /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
496
        if ($comPdf && $this->modelo == '55' && $pathPdf == '') {
497
            $docxml = Files\FilesFolders::readFile($pathXml);
498
            $danfe = new Extras\Danfe($docxml, 'P', 'A4', $this->aDocFormat['pathLogoFile'], 'I', '');
499
            $id = $danfe->montaDANFE();
500
            $pathPdf = $this->aConfig['pathNFeFiles']
501
                . DIRECTORY_SEPARATOR
502
                . $this->ambiente
503
                . DIRECTORY_SEPARATOR
504
                . 'pdf'
505
                . DIRECTORY_SEPARATOR
506
                . $id . '-danfe.pdf';
507
            $pdf = $danfe->printDANFE($pathPdf, 'F');
508
        }
509
         *
510
         */
511
        if ($mail->envia($pathXml, $aMails, $comPdf, $pathPdf) === false) {
512
            throw new Exception\RuntimeException('Email não enviado. '.$mail->error);
513
        }
514
        return true;
515
    }
516
517
    /**
518
     * zSefazEvento
519
     *
520
     * @param    string $siglaUF
521
     * @param    string $chCTe
522
     * @param    string $tpAmb
523
     * @param    string $tpEvento
524
     * @param    string $nSeqEvento
525
     * @param    string $tagAdic
526
     * @return   string
527
     * @throws   Exception\RuntimeException
528
     * @internal function zLoadServico (Common\Base\BaseTools)
529
     */
530
    protected function zSefazEvento(
531
        $siglaUF = '',
532
        $chCTe = '',
533
        $tpAmb = '2',
534
        $tpEvento = '',
535
        $nSeqEvento = '1',
536
        $tagAdic = ''
537
    ) {
538
        if ($tpAmb == '') {
539
            $tpAmb = $this->aConfig['tpAmb'];
540
        }
541
        //carrega serviço
542
        $servico = 'CteRecepcaoEvento';
543
        $this->zLoadServico(
544
            'cte',
545
            $servico,
546
            $siglaUF,
547
            $tpAmb
548
        );
549
        if ($this->urlService == '') {
550
            $msg = "A recepção de eventos não está disponível na SEFAZ $siglaUF!!!";
551
            throw new Exception\RuntimeException($msg);
552
        }
553
        $aRet = $this->zTpEv($tpEvento);
554
        $aliasEvento = $aRet['alias'];
555
        $descEvento = $aRet['desc'];
0 ignored issues
show
Unused Code introduced by
$descEvento 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...
556
        $cnpj = $this->aConfig['cnpj'];
557
        $dhEvento = (string) str_replace(' ', 'T', date('Y-m-d H:i:s'));
558
        $sSeqEvento = str_pad($nSeqEvento, 2, "0", STR_PAD_LEFT);
559
        $eventId = "ID".$tpEvento.$chCTe.$sSeqEvento;
560
        $cOrgao = $this->urlcUF;
561
        if ($siglaUF == 'AN') {
562
            $cOrgao = '91';
563
        }
564
        $mensagem = "<infEvento Id=\"$eventId\">"
565
            . "<cOrgao>$cOrgao</cOrgao>"
566
            . "<tpAmb>$tpAmb</tpAmb>"
567
            . "<CNPJ>$cnpj</CNPJ>"
568
            . "<chCTe>$chCTe</chCTe>"
569
            . "<dhEvento>$dhEvento</dhEvento>"
570
            . "<tpEvento>$tpEvento</tpEvento>"
571
            . "<nSeqEvento>$nSeqEvento</nSeqEvento>"
572
            . "<detEvento versaoEvento=\"$this->urlVersion\">"
573
            . "$tagAdic"
574
            . "</detEvento>"
575
            . "</infEvento>";
576
577
        $cons = "<eventoCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
578
            . "$mensagem"
579
            . "</eventoCTe>";
580
581
        $signedMsg = $this->oCertificate->signXML($cons, 'infEvento');
582
        //limpa o xml
583
        $signedMsg = Strings::clearXml($signedMsg, true);
584
        //montagem dos dados da mensagem SOAP
585
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$signedMsg</cteDadosMsg>";
586
        
587
        $retorno = $this->oSoap->send(
588
            $this->urlService,
589
            $this->urlNamespace,
590
            $this->urlHeader,
591
            $body,
592
            $this->urlMethod
593
        );
594
        $lastMsg = $this->oSoap->lastMsg;
595
        $this->soapDebug = $this->oSoap->soapDebug;
596
        //salva mensagens
597
        $filename = "$chCTe-$aliasEvento-envEvento.xml";
598
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
599
        $filename = "$chCTe-$aliasEvento-retEnvEvento.xml";
600
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
601
        //tratar dados de retorno
602
        $this->aLastRetEvent = Response::readReturnSefaz($servico, $retorno);
603
        if ($this->aLastRetEvent['cStat'] == '134' ||
604
                $this->aLastRetEvent['cStat'] == '135' ||
605
                $this->aLastRetEvent['cStat'] == '136') {
606
            $pasta = 'eventos'; //default
607
            if ($aliasEvento == 'CancCTe') {
608
                $pasta = 'canceladas';
609
                $filename = "$chCTe-$aliasEvento-procEvento.xml";
610
            } elseif ($aliasEvento == 'CCe') {
611
                $pasta = 'cartacorrecao';
612
                $filename = "$chCTe-$aliasEvento-$nSeqEvento-procEvento.xml";
613
            }
614
            $retorno = $this->zAddProtMsg('procEventoCTe', 'eventoCTe', $signedMsg, 'retEventoCTe', $retorno);
615
            $this->zGravaFile('cte', $tpAmb, $filename, $retorno, $pasta);
616
        }
617
        return (string) $retorno;
618
    }
619
    
620
    /**
621
     * zAddProtMsg
622
     *
623
     * @param  string $tagproc
624
     * @param  string $tagmsg
625
     * @param  string $xmlmsg
626
     * @param  string $tagretorno
627
     * @param  string $xmlretorno
628
     * @return string
629
     */
630
    protected function zAddProtMsg($tagproc, $tagmsg, $xmlmsg, $tagretorno, $xmlretorno)
631
    {
632
        $doc = new Dom();
633
        $doc->loadXMLString($xmlmsg);
634
        $nodedoc = $doc->getNode($tagmsg, 0);
635
        $procver = $nodedoc->getAttribute("versao");
636
        $procns = $nodedoc->getAttribute("xmlns");
637
638
        $doc1 = new Dom();
639
        $doc1->loadXMLString($xmlretorno);
640
        $nodedoc1 = $doc1->getNode($tagretorno, 0);
641
642
        $proc = new \DOMDocument('1.0', 'utf-8');
643
        $proc->formatOutput = false;
644
        $proc->preserveWhiteSpace = false;
645
        //cria a tag nfeProc
646
        $procNode = $proc->createElement($tagproc);
647
        $proc->appendChild($procNode);
648
        //estabele o atributo de versão
649
        $procNodeAtt1 = $procNode->appendChild($proc->createAttribute('versao'));
650
        $procNodeAtt1->appendChild($proc->createTextNode($procver));
651
        //estabelece o atributo xmlns
652
        $procNodeAtt2 = $procNode->appendChild($proc->createAttribute('xmlns'));
653
        $procNodeAtt2->appendChild($proc->createTextNode($procns));
654
        //inclui a tag inutNFe
655
        $node = $proc->importNode($nodedoc, true);
656
        $procNode->appendChild($node);
657
        //inclui a tag retInutNFe
658
        $node = $proc->importNode($nodedoc1, true);
659
        $procNode->appendChild($node);
660
        //salva o xml como string em uma variável
661
        $procXML = $proc->saveXML();
662
        //remove as informações indesejadas
663
        $procXML = Strings::clearProt($procXML);
664
        return $procXML;
665
    }
666
667
    /**
668
     * zTpEv
669
     *
670
     * @param  string $tpEvento
671
     * @return array
672
     * @throws Exception\RuntimeException
673
     */
674
    private function zTpEv($tpEvento = '')
675
    {
676
        //montagem dos dados da mensagem SOAP
677
        switch ($tpEvento) {
678
            case '110110':
679
                //CCe
680
                $aliasEvento = 'CCe';
681
                $descEvento = 'Carta de Correcao';
682
                break;
683
            case '110111':
684
                //cancelamento
685
                $aliasEvento = 'CancCTe';
686
                $descEvento = 'Cancelamento';
687
                break;
688
            case '110140':
689
                //EPEC
690
                //emissão em contingência EPEC
691
                $aliasEvento = 'EPEC';
692
                $descEvento = 'EPEC';
693
                break;
694
            case '111500':
695
            case '111501':
696
                //EPP
697
                //Pedido de prorrogação
698
                $aliasEvento = 'EPP';
699
                $descEvento = 'Pedido de Prorrogacao';
700
                break;
701
            case '111502':
702
            case '111503':
703
                //ECPP
704
                //Cancelamento do Pedido de prorrogação
705
                $aliasEvento = 'ECPP';
706
                $descEvento = 'Cancelamento de Pedido de Prorrogacao';
707
                break;
708
            case '210200':
709
                //Confirmacao da Operacao
710
                $aliasEvento = 'EvConfirma';
711
                $descEvento = 'Confirmacao da Operacao';
712
                break;
713
            case '210210':
714
                //Ciencia da Operacao
715
                $aliasEvento = 'EvCiencia';
716
                $descEvento = 'Ciencia da Operacao';
717
                break;
718
            case '210220':
719
                //Desconhecimento da Operacao
720
                $aliasEvento = 'EvDesconh';
721
                $descEvento = 'Desconhecimento da Operacao';
722
                break;
723
            case '210240':
724
                //Operacao não Realizada
725
                $aliasEvento = 'EvNaoRealizada';
726
                $descEvento = 'Operacao nao Realizada';
727
                break;
728
            default:
729
                $msg = "O código do tipo de evento informado não corresponde a "
730
                    . "nenhum evento estabelecido.";
731
                throw new Exception\RuntimeException($msg);
732
        }
733
        return array('alias' => $aliasEvento, 'desc' => $descEvento);
734
    }
735
736
    /**
737
     * validarXml
738
     * Valida qualquer xml do sistema CTe com seu xsd
739
     * NOTA: caso não exista um arquivo xsd apropriado retorna false
740
     *
741
     * @param  string $xml path ou conteudo do xml
742
     * @return boolean
743
     */
744
    public function validarXml($xml = '')
745
    {
746
        $aResp = array();
747
        $schem = IdentifyCTe::identificar($xml, $aResp);
748
        if ($schem == '') {
749
            return true;
750
        }
751
        $xsdFile = $aResp['Id'].'_v'.$aResp['versao'].'.xsd';
752
        $xsdPath = NFEPHP_ROOT.DIRECTORY_SEPARATOR .
753
            'schemas' .
754
            DIRECTORY_SEPARATOR .
755
            $this->aConfig['schemasCTe'] .
756
            DIRECTORY_SEPARATOR .
757
            $xsdFile;
758
        if (! is_file($xsdPath)) {
759
            $this->erros[] = "O arquivo XSD $xsdFile não foi localizado.";
760
            return false;
761
        }
762
        if (! ValidXsd::validar($aResp['xml'], $xsdPath)) {
763
            $this->erros[] = ValidXsd::$errors;
764
            return false;
765
        }
766
        return true;
767
    }
768
769
    /**
770
     * Transmite a correção
771
     * conforme o MOC(Manual de Orientações do Contribuinte)
772
     * Art. 58-B Fica permitida a utilização de carta de correção,
773
     * para regularização de erro ocorrido na emissão de documentos
774
     * fiscais relativos à prestação de serviço de transporte, desde que o
775
     * erro não esteja relacionado com:
776
     * I - as variáveis que determinam o valor do imposto tais como:
777
     *  base de cálculo, alíquota, diferença de preço, quantidade, valor da prestação
778
     * II - a correção de dados cadastrais que implique mudança do emitente,
779
     *  tomador, remetente ou do destinatário;
780
     * III - a data de emissão ou de saída.
781
     *
782
     * @param type $chCTe
783
     * @param type $tpAmb
784
     * @param type $nSeqEvento
785
     * @param type $infCorrecao
786
     * @param type $aRetorno
787
     * @return type
788
     * @throws Exception\InvalidArgumentException
789
     */
790
    public function sefazCartaCorrecao(
791
        $chCTe = '',
792
        $tpAmb = '2',
793
        $nSeqEvento = '1',
794
        $infCorrecao = array(),
795
        &$aRetorno = array()
796
    ) {
797
        $chCTe = preg_replace('/[^0-9]/', '', $chCTe);
798
799
        //validação dos dados de entrada
800
        if (strlen($chCTe) != 44) {
801
            $msg = "Uma chave de CTe válida não foi passada como parâmetro $chCTe.";
802
            throw new Exception\InvalidArgumentException($msg);
803
        }
804
        if ($chCTe == '' || empty(array_filter($infCorrecao))) {
805
            $msg = "Preencha os campos obrigatórios!";
806
            throw new Exception\InvalidArgumentException($msg);
807
        }
808
        if ($tpAmb == '') {
809
            $tpAmb = $this->aConfig['tpAmb'];
810
        }
811
        $siglaUF = $this->zGetSigla(substr($chCTe, 0, 2));
812
813
        //estabelece o codigo do tipo de evento CARTA DE CORRECAO
814
        $tpEvento = '110110';
815
        $descEvento = 'Carta de Correcao';
816
817
        //Grupo de Informações de Correção
818
        $correcoes = '';
819
        foreach ($infCorrecao as $info) {
820
            $correcoes .=
821
                "<infCorrecao>"
822
                    ."<grupoAlterado>".$info['grupoAlterado']."</grupoAlterado>"
823
                    ."<campoAlterado>".$info['campoAlterado']."</campoAlterado>"
824
                    ."<valorAlterado>".$info['valorAlterado']."</valorAlterado>"
825
                    ."<nroItemAlterado>".$info['nroItemAlterado']."</nroItemAlterado>"
826
                ."</infCorrecao>";
827
        }
828
        //monta mensagem
829
        $tagAdic =
830
            "<evCCeCTe>"
831
                . "<descEvento>$descEvento</descEvento>"
832
                .$correcoes
833
                . "<xCondUso>"
834
                    . "A Carta de Correcao e disciplinada pelo Art. 58-B do "
835
                    . "CONVENIO/SINIEF 06/89: Fica permitida a utilizacao de carta de "
836
                    . "correcao, para regularizacao de erro ocorrido na emissao de "
837
                    . "documentos fiscais relativos a prestacao de servico de transporte, "
838
                    . "desde que o erro nao esteja relacionado com: I - as variaveis que "
839
                    . "determinam o valor do imposto tais como: base de calculo, "
840
                    . "aliquota, diferenca de preco, quantidade, valor da prestacao;II - "
841
                    . "a correcao de dados cadastrais que implique mudanca do emitente, "
842
                    . "tomador, remetente ou do destinatario;III - a data de emissao ou "
843
                    . "de saida."
844
                . "</xCondUso>"
845
            ."</evCCeCTe>";
846
        $retorno = $this->zSefazEvento($siglaUF, $chCTe, $tpAmb, $tpEvento, $nSeqEvento, $tagAdic);
0 ignored issues
show
Bug introduced by
It seems like $chCTe defined by preg_replace('/[^0-9]/', '', $chCTe) on line 797 can also be of type array<integer,string>; however, NFePHP\CTe\Tools::zSefazEvento() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
847
        $aRetorno = $this->aLastRetEvent;
848
        return $retorno;
849
    }
850
851
    public function addProtocolo($pathCTeFile = '', $pathProtfile = '', $saveFile = false)
852
    {
853
        //carrega a CTe
854
        $docCte = new Dom();
855
856
        if (file_exists($pathCTeFile)) {
857
            //carrega o XML pelo caminho do arquivo informado
858
            $docCte->loadXMLFile($pathCTeFile);
859
        } else {
860
            //carrega o XML pelo conteúdo
861
            $docCte->loadXMLString($pathCTeFile);
862
        }
863
864
        $nodecte = $docCte->getNode('CTe', 0);
865
        if ($nodecte == '') {
866
            $msg = "O arquivo indicado como CTe não é um xml de CTe!";
867
            throw new Exception\RuntimeException($msg);
868
        }
869
        if ($docCte->getNode('Signature') == '') {
870
            $msg = "A CTe não está assinada!";
871
            throw new Exception\RuntimeException($msg);
872
        }
873
        //carrega o protocolo
874
        $docprot = new Dom();
875
876
        if (file_exists($pathProtfile)) {
877
            //carrega o XML pelo caminho do arquivo informado
878
            $docprot->loadXMLFile($pathProtfile);
879
        } else {
880
            //carrega o XML pelo conteúdo
881
            $docprot->loadXMLString($pathProtfile);
882
        }
883
884
        $nodeprots = $docprot->getElementsByTagName('protCTe');
885
        if ($nodeprots->length == 0) {
886
            $msg = "O arquivo indicado não contem um protocolo de autorização!";
887
            throw new Exception\RuntimeException($msg);
888
        }
889
        //carrega dados da CTe
890
        $tpAmb = $docCte->getNodeValue('tpAmb');
891
        $anomes = date(
892
            'Ym',
893
            DateTime::convertSefazTimeToTimestamp($docCte->getNodeValue('dhEmi'))
894
        );
895
//        $infCTe = $docCte->getNode("infCTe", 0);
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
896
//        $versao = $infCTe->getAttribute("versao");
897
//        $chaveId = $infCTe->getAttribute("Id");
898
//        $chaveCTe = preg_replace('/[^0-9]/', '', $chaveId);
899
        $digValueCTe = $docCte->getNodeValue('DigestValue');
900
        //carrega os dados do protocolo
901
        for ($i = 0; $i < $nodeprots->length; $i++) {
902
            $nodeprot = $nodeprots->item($i);
903
            $protver = $nodeprot->getAttribute("versao");
904
            $chaveProt = $nodeprot->getElementsByTagName("chCTe")->item(0)->nodeValue;
905
            $digValueProt = ($nodeprot->getElementsByTagName("digVal")->length)
906
                ? $nodeprot->getElementsByTagName("digVal")->item(0)->nodeValue
907
                : '';
908
            $infProt = $nodeprot->getElementsByTagName("infProt")->item(0);
909
//            if ($digValueCTe == $digValueProt && $chaveCTe == $chaveProt) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
910
//                break;
911
//            }
912
        }
913
        if ($digValueCTe != $digValueProt) {
0 ignored issues
show
Bug introduced by
The variable $digValueProt does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
914
            $msg = "Inconsistência! O DigestValue da CTe não combina com o do digVal do protocolo indicado!";
915
            throw new Exception\RuntimeException($msg);
916
        }
917
//        if ($chaveCTe != $chaveProt) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
49% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
918
//            $msg = "O protocolo indicado pertence a outra CTe. Os números das chaves não combinam !";
919
//            throw new Exception\RuntimeException($msg);
920
//        }
921
        //cria a CTe processada com a tag do protocolo
922
        $procCte = new \DOMDocument('1.0', 'utf-8');
923
        $procCte->formatOutput = false;
924
        $procCte->preserveWhiteSpace = false;
925
        //cria a tag cteProc
926
        $cteProc = $procCte->createElement('cteProc');
927
        $procCte->appendChild($cteProc);
928
        //estabele o atributo de versão
929
        $cteProcAtt1 = $cteProc->appendChild($procCte->createAttribute('versao'));
930
        $cteProcAtt1->appendChild($procCte->createTextNode($protver));
0 ignored issues
show
Bug introduced by
The variable $protver does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
931
        //estabelece o atributo xmlns
932
        $cteProcAtt2 = $cteProc->appendChild($procCte->createAttribute('xmlns'));
933
        $cteProcAtt2->appendChild($procCte->createTextNode($this->urlPortal));
934
        //inclui a tag CTe
935
        $node = $procCte->importNode($nodecte, true);
936
        $cteProc->appendChild($node);
937
        //cria tag protCTe
938
        $protCTe = $procCte->createElement('protCTe');
939
        $cteProc->appendChild($protCTe);
940
        //estabele o atributo de versão
941
        $protCTeAtt1 = $protCTe->appendChild($procCte->createAttribute('versao'));
942
        $protCTeAtt1->appendChild($procCte->createTextNode($protver));
943
        //cria tag infProt
944
        $nodep = $procCte->importNode($infProt, true);
0 ignored issues
show
Bug introduced by
The variable $infProt does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
945
        $protCTe->appendChild($nodep);
946
        //salva o xml como string em uma variável
947
        $procXML = $procCte->saveXML();
948
        //remove as informações indesejadas
949
        $procXML = Strings::clearProt($procXML);
950
        if ($saveFile) {
951
//            $filename = "{$chaveCTe}-protCTe.xml";
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
952
            $filename = "{$chaveProt}-protCTe.xml";
0 ignored issues
show
Bug introduced by
The variable $chaveProt does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
953
            $this->zGravaFile(
954
                'cte',
955
                $tpAmb,
956
                $filename,
957
                $procXML,
958
                'enviadas'.DIRECTORY_SEPARATOR.'aprovadas',
959
                $anomes
960
            );
961
        }
962
        return $procXML;
963
    }
964
965
966
    /**
967
     * addCancelamento
968
     * Adiciona a tga de cancelamento a uma CTe já autorizada
969
     * NOTA: não é requisito da SEFAZ, mas auxilia na identificação das CTe que foram canceladas
970
     * @param string $pathCTefile
971
     * @param string $pathCancfile
972
     * @param bool $saveFile
973
     * @return string
974
     * @throws Exception\RuntimeException
975
     */
976
    public function addCancelamento($pathCTefile = '', $pathCancfile = '', $saveFile = false)
977
    {
978
        $procXML = '';
979
        //carrega a CTe
980
        $docCTe = new Dom();
981
        
982
        if (file_exists($pathCTefile)) {
983
            //carrega o XML pelo caminho do arquivo informado
984
            $docCTe->loadXMLFile($pathCTefile);
985
        } else {
986
            //carrega o XML pelo conteúdo
987
            $docCTe->loadXMLString($pathCTefile);
988
        }
989
        
990
        $nodeCTe = $docCTe->getNode('CTe', 0);
991
        if ($nodeCTe == '') {
992
            $msg = "O arquivo indicado como CTe não é um xml de CTe!";
993
            throw new Exception\RuntimeException($msg);
994
        }
995
        $proCTe = $docCTe->getNode('protCTe');
996
        if ($proCTe == '') {
997
            $msg = "A CTe não está protocolada ainda!!";
998
            throw new Exception\RuntimeException($msg);
999
        }
1000
        $chaveCTe = $proCTe->getElementsByTagName('chCTe')->item(0)->nodeValue;
1001
        //$nProtCTe = $proCTe->getElementsByTagName('nProt')->item(0)->nodeValue;
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1002
        $tpAmb = $docCTe->getNodeValue('tpAmb');
0 ignored issues
show
Unused Code introduced by
$tpAmb 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...
1003
        $anomes = date(
1004
            'Ym',
1005
            DateTime::convertSefazTimeToTimestamp($docCTe->getNodeValue('dhEmi'))
1006
        );
1007
        //carrega o cancelamento
1008
        //pode ser um evento ou resultado de uma consulta com multiplos eventos
1009
        $doccanc = new Dom();
1010
        
1011
        if (file_exists($pathCancfile)) {
1012
            //carrega o XML pelo caminho do arquivo informado
1013
            $doccanc->loadXMLFile($pathCancfile);
1014
        } else {
1015
            //carrega o XML pelo conteúdo
1016
            $doccanc->loadXMLString($pathCancfile);
1017
        }
1018
        $retEvento = $doccanc->getElementsByTagName('retEventoCTe')->item(0);
1019
        $eventos = $retEvento->getElementsByTagName('infEvento');
1020
        foreach ($eventos as $evento) {
1021
            //evento
1022
            $cStat = $evento->getElementsByTagName('cStat')->item(0)->nodeValue;
1023
            $tpAmb = $evento->getElementsByTagName('tpAmb')->item(0)->nodeValue;
1024
            $chaveEvento = $evento->getElementsByTagName('chCTe')->item(0)->nodeValue;
1025
            $tpEvento = $evento->getElementsByTagName('tpEvento')->item(0)->nodeValue;
1026
            //$nProtEvento = $evento->getElementsByTagName('nProt')->item(0)->nodeValue;
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1027
            //verifica se conferem os dados
1028
            //cStat = 135 ==> evento homologado
1029
            //cStat = 136 ==> vinculação do evento à respectiva NF-e prejudicada
1030
            //cStat = 155 ==> Cancelamento homologado fora de prazo
1031
            //tpEvento = 110111 ==> Cancelamento
1032
            //chave do evento == chave da CTe
1033
            //protocolo do evneto ==  protocolo da CTe
1034
            if (($cStat == '135' || $cStat == '136' || $cStat == '155') &&
1035
                $tpEvento == '110111' &&
1036
                $chaveEvento == $chaveCTe
1037
            ) {
1038
                $proCTe->getElementsByTagName('cStat')->item(0)->nodeValue = '101';
1039
                $proCTe->getElementsByTagName('xMotivo')->item(0)->nodeValue = 'Cancelamento de CT-e homologado';
1040
                $procXML = $docCTe->saveXML();
1041
                //remove as informações indesejadas
1042
                $procXML = Strings::clearProt($procXML);
1043
                if ($saveFile) {
1044
                    $filename = "$chaveCTe-protCTe.xml";
1045
                    $this->zGravaFile(
1046
                        'cte',
1047
                        $tpAmb,
1048
                        $filename,
1049
                        $procXML,
1050
                        'canceladas',
1051
                        $anomes
1052
                    );
1053
                }
1054
                break;
1055
            }
1056
        }
1057
        return (string) $procXML;
1058
    }
1059
}
1060