Completed
Push — master ( 87e5e7...0e505d )
by Roberto
02:54
created

Tools::addCancelamento()   C

Complexity

Conditions 12
Paths 20

Size

Total Lines 83
Code Lines 50

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 156

Importance

Changes 0
Metric Value
dl 0
loc 83
ccs 0
cts 47
cp 0
rs 5.034
c 0
b 0
f 0
cc 12
eloc 50
nc 20
nop 3
crap 156

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
     * erros
48
     *
49
     * @var string
50
     */
51
    public $erros = array();
52
53
    /**
54
     * modelo 57 (CTE-e) é um documento fiscal eletrônico,
55
     * instituído pelo AJUSTE SINIEF 09/07 (25/10/2007)
56
     *
57
     * @var modelo
58
     */
59
    protected $modelo = '57';
60
61
    /**
62
     * assina
63
     *
64
     * @param  string  $xml
65
     * @param  boolean $saveFile
66
     * @return string
67
     * @throws Exception\RuntimeException
68
     */
69
    public function assina($xml = '', $saveFile = false)
70
    {
71
        return $this->assinaDoc($xml, 'cte', 'infCte', $saveFile);
72
    }
73
74
    /**
75
     * Transmite o xml para a sefaz
76
     *
77
     * @param type $aXml
78
     * @param type $tpAmb
79
     * @param type $idLote
80
     * @param type $aRetorno
81
     * @param int $indSinc
82
     * @param type $compactarZip
83
     * @return type
84
     * @throws Exception\InvalidArgumentException
85
     * @throws Exception\RuntimeException
86
     */
87
    public function sefazEnvia(
88
        $aXml,
89
        $tpAmb = '2',
90
        $idLote = '',
91
        &$aRetorno = array(),
92
        $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...
93
        $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...
94
    ) {
95
        $sxml = $aXml;
96
        if (empty($aXml)) {
97
            $msg = "Pelo menos uma CTe deve ser informada.";
98
            throw new Exception\InvalidArgumentException($msg);
99
        }
100
        if (is_array($aXml)) {
101
            if (count($aXml) > 1) {
102
                //multiplas cte, não pode ser sincrono
103
                $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...
104
            }
105
            $sxml = implode("", $sxml);
106
        }
107
        $sxml = preg_replace("/<\?xml.*\?>/", "", $sxml);
108
        $siglaUF = $this->aConfig['siglaUF'];
109
110
        if ($tpAmb == '') {
111
            $tpAmb = $this->aConfig['tpAmb'];
112
        }
113
        if ($idLote == '') {
114
            $idLote = LotNumber::geraNumLote(15);
115
        }
116
        //carrega serviço
117
        $servico = 'CteRecepcao';
118
        $this->zLoadServico(
119
            'cte',
120
            $servico,
121
            $siglaUF,
122
            $tpAmb
123
        );
124
125
        if ($this->urlService == '') {
126
            $msg = "O envio de lote não está disponível na SEFAZ $siglaUF!!!";
127
            throw new Exception\RuntimeException($msg);
128
        }
129
130
        // Montagem dos dados da mensagem SOAP
131
        $dados = "<cteDadosMsg xmlns=\"$this->urlNamespace\">"
132
            . "<enviCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
133
            . "<idLote>$idLote</idLote>"
134
            . "$sxml"
135
            . "</enviCTe>"
136
            . "</cteDadosMsg>";
137
        // Envia dados via SOAP
138
        $retorno = $this->oSoap->send(
139
            $this->urlService,
140
            $this->urlNamespace,
141
            $this->urlHeader,
142
            $dados,
143
            $this->urlMethod
144
        );
145
146
        $lastMsg = $this->oSoap->lastMsg;
147
        $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...
148
        //salva mensagens
149
        $filename = "$idLote-enviCTe.xml";
150
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
151
        $filename = "$idLote-retEnviCTe.xml";
152
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
153
        //tratar dados de retorno
154
155
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
156
        //caso o envio seja recebido com sucesso mover a CTe da pasta
157
        //das assinadas para a pasta das enviadas
158
        return (string) $retorno;
159
    }
160
161
    /**
162
     * Consulta o recibo na sefaz
163
     *
164
     * @param type $recibo
165
     * @param type $tpAmb
166
     * @param type $aRetorno
167
     * @return type
168
     * @throws Exception\InvalidArgumentException
169
     * @throws Exception\RuntimeException
170
     */
171
    public function sefazConsultaRecibo($recibo = '', $tpAmb = '2', &$aRetorno = array())
172
    {
173
        if ($recibo == '') {
174
            $msg = "Deve ser informado um recibo.";
175
            throw new Exception\InvalidArgumentException($msg);
176
        }
177
        if ($tpAmb == '') {
178
            $tpAmb = $this->aConfig['tpAmb'];
179
        }
180
        $siglaUF = $this->aConfig['siglaUF'];
181
        //carrega serviço
182
        $servico = 'CteRetRecepcao';
183
        $this->zLoadServico(
184
            'cte',
185
            $servico,
186
            $siglaUF,
187
            $tpAmb
188
        );
189
        if ($this->urlService == '') {
190
            $msg = "A consulta de CTe não está disponível na SEFAZ $siglaUF!!!";
191
            throw new Exception\RuntimeException($msg);
192
        }
193
        $cons = "<consReciCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
194
            . "<tpAmb>$tpAmb</tpAmb>"
195
            . "<nRec>$recibo</nRec>"
196
            . "</consReciCTe>";
197
        //montagem dos dados da mensagem SOAP
198
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$cons</cteDadosMsg>";
199
        //envia a solicitação via SOAP
200
        $retorno = $this->oSoap->send(
201
            $this->urlService,
202
            $this->urlNamespace,
203
            $this->urlHeader,
204
            $body,
205
            $this->urlMethod
206
        );
207
        $lastMsg = $this->oSoap->lastMsg;
208
        $this->soapDebug = $this->oSoap->soapDebug;
209
        //salva mensagens
210
        $filename = "$recibo-consReciCTe.xml";
211
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
212
        $filename = "$recibo-retConsReciCTe.xml";
213
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
214
        //tratar dados de retorno
215
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
216
        //podem ser retornados nenhum, um ou vários protocolos
217
        //caso existam protocolos protocolar as CTe e movelas-las para a
218
        //pasta enviadas/aprovadas/anomes
219
        return (string) $retorno;
220
    }
221
222
    /**
223
     * consulta a chave de acesso do CT-e
224
     *
225
     * @param type $chave
226
     * @param type $tpAmb
227
     * @param type $aRetorno
228
     * @return type
229
     * @throws Exception\InvalidArgumentException
230
     * @throws Exception\RuntimeException
231
     */
232
    public function sefazConsultaChave($chave = '', $tpAmb = '2', &$aRetorno = array())
233
    {
234
        $chCTe = preg_replace('/[^0-9]/', '', $chave);
235
        if (strlen($chCTe) != 44) {
236
            $msg = "Uma chave de 44 dígitos da CTe deve ser passada.";
237
            throw new Exception\InvalidArgumentException($msg);
238
        }
239
        if ($tpAmb == '') {
240
            $tpAmb = $this->aConfig['tpAmb'];
241
        }
242
        $cUF = substr($chCTe, 0, 2);
243
        $siglaUF = $this->zGetSigla($cUF);
244
        //carrega serviço
245
        $servico = 'CteConsultaProtocolo';
246
        $this->zLoadServico(
247
            'cte',
248
            $servico,
249
            $siglaUF,
250
            $tpAmb
251
        );
252
        if ($this->urlService == '') {
253
            $msg = "A consulta de CTe não está disponível na SEFAZ $siglaUF!!!";
254
            throw new Exception\RuntimeException($msg);
255
        }
256
        $cons = "<consSitCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
257
            . "<tpAmb>$tpAmb</tpAmb>"
258
            . "<xServ>CONSULTAR</xServ>"
259
            . "<chCTe>$chCTe</chCTe>"
260
            . "</consSitCTe>";
261
        //montagem dos dados da mensagem SOAP
262
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$cons</cteDadosMsg>";
263
        //envia a solicitação via SOAP
264
        $retorno = $this->oSoap->send(
265
            $this->urlService,
266
            $this->urlNamespace,
267
            $this->urlHeader,
268
            $body,
269
            $this->urlMethod
270
        );
271
        $lastMsg = $this->oSoap->lastMsg;
272
        $this->soapDebug = $this->oSoap->soapDebug;
273
        //salva mensagens
274
        $filename = "$chCTe-consSitCTe.xml";
275
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
276
        $filename = "$chCTe-retConsSitCTe.xml";
277
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
278
        //tratar dados de retorno
279
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
280
        return (string) $retorno;
281
    }
282
283
    /**
284
     * consulta disponibilidade do serviço web service da sefaz
285
     *
286
     * @param type $siglaUF
287
     * @param type $tpAmb
288
     * @param type $aRetorno
289
     * @return type
290
     * @throws Exception\RuntimeException
291
     */
292
    public function sefazStatus($siglaUF = '', $tpAmb = '2', &$aRetorno = array())
293
    {
294
        if ($tpAmb == '') {
295
            $tpAmb = $this->aConfig['tpAmb'];
296
        }
297
        if ($siglaUF == '') {
298
            $siglaUF = $this->aConfig['siglaUF'];
299
        }
300
        //carrega serviço
301
        $servico = 'CteStatusServico';
302
        $this->zLoadServico(
303
            'cte',
304
            $servico,
305
            $siglaUF,
306
            $tpAmb
307
        );
308
        if ($this->urlService == '') {
309
            $msg = "O status não está disponível na SEFAZ $siglaUF!!!";
310
            throw new Exception\RuntimeException($msg);
311
        }
312
        $cons = "<consStatServCte xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
313
            . "<tpAmb>$tpAmb</tpAmb>"
314
            . "<xServ>STATUS</xServ></consStatServCte>";
315
        //montagem dos dados da mensagem SOAP
316
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$cons</cteDadosMsg>";
317
        //consome o webservice e verifica o retorno do SOAP
318
        $retorno = $this->oSoap->send(
319
            $this->urlService,
320
            $this->urlNamespace,
321
            $this->urlHeader,
322
            $body,
323
            $this->urlMethod
324
        );
325
        $lastMsg = $this->oSoap->lastMsg;
326
        $this->soapDebug = $this->oSoap->soapDebug;
327
        $datahora = date('Ymd_His');
328
        $filename = $siglaUF."_"."$datahora-consStatServCte.xml";
329
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
330
        $filename = $siglaUF."_"."$datahora-retConsStatServCte.xml";
331
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
332
        //tratar dados de retorno
333
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
334
        return (string) $retorno;
335
    }
336
337
    /**
338
     * Inutiza sequencia de numeracao
339
     *
340
     * @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...
341
     * @param type $nSerie
342
     * @param type $nIni
343
     * @param type $nFin
344
     * @param type $xJust
345
     * @param type $tpAmb
346
     * @param type $aRetorno
347
     * @return boolean
348
     * @throws Exception\RuntimeException
349
     * @throws Exception\InvalidArgumentException
350
     */
351
    public function sefazInutiliza(
352
        $nSerie = '1',
353
        $nIni = '',
354
        $nFin = '',
355
        $xJust = '',
356
        $tpAmb = '2',
357
        &$aRetorno = array(),
358
        $salvarMensagens = true
359
    ) {
360
        $nSerie = (integer) $nSerie;
361
        $nIni = (integer) $nIni;
362
        $nFin = (integer) $nFin;
363
        $xJust = Strings::cleanString($xJust);
364
        $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...
365
        if ($tpAmb == '') {
366
            $tpAmb = $this->aConfig['tpAmb'];
367
        }
368
        // Identificação do serviço
369
        $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...
370
        //monta serviço
371
        $siglaUF = $this->aConfig['siglaUF'];
372
        //carrega serviço
373
        $servico = 'CteInutilizacao';
374
        $this->zLoadServico(
375
            'cte',
376
            $servico,
377
            $siglaUF,
378
            $tpAmb
379
        );
380
        if ($this->urlService == '') {
381
            $msg = "A inutilização não está disponível na SEFAZ $siglaUF!!!";
382
            throw new Exception\RuntimeException($msg);
383
        }
384
        //montagem dos dados da mensagem SOAP
385
        $cnpj = $this->aConfig['cnpj'];
386
        $sAno = (string) date('y');
387
        $sSerie = str_pad($nSerie, 3, '0', STR_PAD_LEFT);
388
        $sInicio = str_pad($nIni, 9, '0', STR_PAD_LEFT);
389
        $sFinal = str_pad($nFin, 9, '0', STR_PAD_LEFT);
390
        //limpa os caracteres indesejados da justificativa
391
        $xJust = Strings::cleanString($xJust);
392
        // Identificador da TAG a ser assinada formada com Código da UF +
393
        // precedida do literal “ID”
394
        // 41 posições
395
        $id = 'ID'.$this->urlcUF.$cnpj.'57'.$sSerie.$sInicio.$sFinal;
396
        // Montagem do corpo da mensagem
397
        $dXML = "<inutCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
398
            ."<infInut Id=\"$id\">"
399
            ."<tpAmb>$tpAmb</tpAmb>"
400
            ."<xServ>INUTILIZAR</xServ>"
401
            ."<cUF>$this->urlcUF</cUF>"
402
            ."<ano>$sAno</ano>"
403
            ."<CNPJ>$cnpj</CNPJ>"
404
            ."<mod>57</mod>"
405
            ."<serie>$nSerie</serie>"
406
            ."<nCTIni>$nIni</nCTIni>"
407
            ."<nCTFin>$nFin</nCTFin>"
408
            ."<xJust>$xJust</xJust>"
409
            ."</infInut></inutCTe>";
410
        //assina a solicitação de inutilização
411
        $signedMsg = $this->oCertificate->signXML($dXML, 'infInut');
412
        $signedMsg = Strings::clearXml($signedMsg, true);
413
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$signedMsg</cteDadosMsg>";
414
        //envia a solicitação via SOAP
415
        $retorno = $this->oSoap->send(
416
            $this->urlService,
417
            $this->urlNamespace,
418
            $this->urlHeader,
419
            $body,
420
            $this->urlMethod
421
        );
422
        $lastMsg = $this->oSoap->lastMsg;
423
        $this->soapDebug = $this->oSoap->soapDebug;
424
        //salva mensagens
425
        if ($salvarMensagens) {
426
            $filename = "$sAno-$this->modelo-$sSerie-".$sInicio."_".$sFinal."-inutCTe.xml";
427
            $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
428
            $filename = "$sAno-$this->modelo-$sSerie-".$sInicio."_".$sFinal."-retInutCTe.xml";
429
            $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
430
        }
431
        //tratar dados de retorno
432
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
433
        if ($aRetorno['cStat'] == '102') {
434
            $retorno = $this->zAddProtMsg('ProcInutCTe', 'inutCTe', $signedMsg, 'retInutCTe', $retorno);
0 ignored issues
show
Bug introduced by
The method zAddProtMsg() 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...
435
            if ($salvarMensagens) {
436
                $filename = "$sAno-$this->modelo-$sSerie-".$sInicio."_".$sFinal."-procInutCTe.xml";
437
                $this->zGravaFile('cte', $tpAmb, $filename, $retorno, 'inutilizadas');
438
            }
439
        }
440
        return (string) $retorno;
441
    }
442
443
    /**
444
     * Cancelamento de numero CT-e
445
     *
446
     * @param type $chCTe
447
     * @param type $tpAmb
448
     * @param type $xJust
449
     * @param type $nProt
450
     * @param type $aRetorno
451
     * @return type
452
     * @throws Exception\InvalidArgumentException
453
     */
454
    public function sefazCancela($chCTe = '', $tpAmb = '2', $xJust = '', $nProt = '', &$aRetorno = array())
455
    {
456
        $chCTe = preg_replace('/[^0-9]/', '', $chCTe);
457
        $nProt = preg_replace('/[^0-9]/', '', $nProt);
458
        $xJust = Strings::cleanString($xJust);
459
        //validação dos dados de entrada
460
        if (strlen($chCTe) != 44) {
461
            $msg = "Uma chave de CTe válida não foi passada como parâmetro $chCTe.";
462
            throw new Exception\InvalidArgumentException($msg);
463
        }
464
        if ($nProt == '') {
465
            $msg = "Não foi passado o numero do protocolo!!";
466
            throw new Exception\InvalidArgumentException($msg);
467
        }
468
        if (strlen($xJust) < 15 || strlen($xJust) > 255) {
469
            $msg = "A justificativa deve ter pelo menos 15 digitos e no máximo 255!!";
470
            throw new Exception\InvalidArgumentException($msg);
471
        }
472
        $siglaUF = $this->zGetSigla(substr($chCTe, 0, 2));
473
474
        //estabelece o codigo do tipo de evento CANCELAMENTO
475
        $tpEvento = '110111';
476
        $descEvento = 'Cancelamento';
477
        $nSeqEvento = 1;
478
        //monta mensagem
479
        $tagAdic = "<evCancCTe>"
480
            . "<descEvento>$descEvento</descEvento>"
481
            . "<nProt>$nProt</nProt>"
482
            . "<xJust>$xJust</xJust>"
483
            . "</evCancCTe>";
484
        $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 456 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...
485
        $aRetorno = $this->aLastRetEvent;
0 ignored issues
show
Bug introduced by
The property aLastRetEvent 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...
486
        return $retorno;
487
    }
488
489
    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...
490
    {
491
        $mail = new Mail($this->aMailConf);
492
        // Se não for informado o caminho do PDF, monta um através do XML
493
        /*
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...
494
        if ($comPdf && $this->modelo == '55' && $pathPdf == '') {
495
            $docxml = Files\FilesFolders::readFile($pathXml);
496
            $danfe = new Extras\Danfe($docxml, 'P', 'A4', $this->aDocFormat['pathLogoFile'], 'I', '');
497
            $id = $danfe->montaDANFE();
498
            $pathPdf = $this->aConfig['pathNFeFiles']
499
                . DIRECTORY_SEPARATOR
500
                . $this->ambiente
501
                . DIRECTORY_SEPARATOR
502
                . 'pdf'
503
                . DIRECTORY_SEPARATOR
504
                . $id . '-danfe.pdf';
505
            $pdf = $danfe->printDANFE($pathPdf, 'F');
506
        }
507
         *
508
         */
509
        if ($mail->envia($pathXml, $aMails, $comPdf, $pathPdf) === false) {
510
            throw new Exception\RuntimeException('Email não enviado. '.$mail->error);
511
        }
512
        return true;
513
    }
514
515
    /**
516
     * zSefazEvento
517
     *
518
     * @param    string $siglaUF
519
     * @param    string $chCTe
520
     * @param    string $tpAmb
521
     * @param    string $tpEvento
522
     * @param    string $nSeqEvento
523
     * @param    string $tagAdic
524
     * @return   string
525
     * @throws   Exception\RuntimeException
526
     * @internal function zLoadServico (Common\Base\BaseTools)
527
     */
528
    protected function zSefazEvento(
529
        $siglaUF = '',
530
        $chCTe = '',
531
        $tpAmb = '2',
532
        $tpEvento = '',
533
        $nSeqEvento = '1',
534
        $tagAdic = ''
535
    ) {
536
        if ($tpAmb == '') {
537
            $tpAmb = $this->aConfig['tpAmb'];
538
        }
539
        //carrega serviço
540
        $servico = 'CteRecepcaoEvento';
541
        $this->zLoadServico(
542
            'cte',
543
            $servico,
544
            $siglaUF,
545
            $tpAmb
546
        );
547
        if ($this->urlService == '') {
548
            $msg = "A recepção de eventos não está disponível na SEFAZ $siglaUF!!!";
549
            throw new Exception\RuntimeException($msg);
550
        }
551
        $aRet = $this->zTpEv($tpEvento);
552
        $aliasEvento = $aRet['alias'];
553
        $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...
554
        $cnpj = $this->aConfig['cnpj'];
555
        $dhEvento = (string) str_replace(' ', 'T', date('Y-m-d H:i:s'));
556
        $sSeqEvento = str_pad($nSeqEvento, 2, "0", STR_PAD_LEFT);
557
        $eventId = "ID".$tpEvento.$chCTe.$sSeqEvento;
558
        $cOrgao = $this->urlcUF;
559
        if ($siglaUF == 'AN') {
560
            $cOrgao = '91';
561
        }
562
        $mensagem = "<infEvento Id=\"$eventId\">"
563
            . "<cOrgao>$cOrgao</cOrgao>"
564
            . "<tpAmb>$tpAmb</tpAmb>"
565
            . "<CNPJ>$cnpj</CNPJ>"
566
            . "<chCTe>$chCTe</chCTe>"
567
            . "<dhEvento>$dhEvento</dhEvento>"
568
            . "<tpEvento>$tpEvento</tpEvento>"
569
            . "<nSeqEvento>$nSeqEvento</nSeqEvento>"
570
            . "<detEvento versaoEvento=\"$this->urlVersion\">"
571
            . "$tagAdic"
572
            . "</detEvento>"
573
            . "</infEvento>";
574
575
        $cons = "<eventoCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
576
            . "$mensagem"
577
            . "</eventoCTe>";
578
579
        $signedMsg = $this->oCertificate->signXML($cons, 'infEvento');
580
        //limpa o xml
581
        $signedMsg = preg_replace("/<\?xml.*\?>/", "", $signedMsg);
582
        //montagem dos dados da mensagem SOAP
583
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$signedMsg</cteDadosMsg>";
584
585
        $retorno = $this->oSoap->send(
586
            $this->urlService,
587
            $this->urlNamespace,
588
            $this->urlHeader,
589
            $body,
590
            $this->urlMethod
591
        );
592
        $lastMsg = $this->oSoap->lastMsg;
593
        $this->soapDebug = $this->oSoap->soapDebug;
594
        //salva mensagens
595
        $filename = "$chCTe-$aliasEvento-envEvento.xml";
596
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
597
        $filename = "$chCTe-$aliasEvento-retEnvEvento.xml";
598
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
599
        //tratar dados de retorno
600
        $this->aLastRetEvent = Response::readReturnSefaz($servico, $retorno);
601
        if ($this->aLastRetEvent['cStat'] == '128') {
602
            if ($this->aLastRetEvent['evento'][0]['cStat'] == '135' ||
603
                $this->aLastRetEvent['evento'][0]['cStat'] == '136' ||
604
                $this->aLastRetEvent['evento'][0]['cStat'] == '155'
605
            ) {
606
                $pasta = 'eventos'; //default
607
                if ($aliasEvento == 'CanCTe') {
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', 'evento', $signedMsg, 'retEvento', $retorno);
0 ignored issues
show
Bug introduced by
The method zAddProtMsg() 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...
615
                $this->zGravaFile('cte', $tpAmb, $filename, $retorno, $pasta);
616
            }
617
        }
618
        return (string) $retorno;
619
    }
620
621
622
    /**
623
     * zTpEv
624
     *
625
     * @param  string $tpEvento
626
     * @return array
627
     * @throws Exception\RuntimeException
628
     */
629
    private function zTpEv($tpEvento = '')
630
    {
631
        //montagem dos dados da mensagem SOAP
632
        switch ($tpEvento) {
633
            case '110110':
634
                //CCe
635
                $aliasEvento = 'CCe';
636
                $descEvento = 'Carta de Correcao';
637
                break;
638
            case '110111':
639
                //cancelamento
640
                $aliasEvento = 'CancCTe';
641
                $descEvento = 'Cancelamento';
642
                break;
643
            case '110140':
644
                //EPEC
645
                //emissão em contingência EPEC
646
                $aliasEvento = 'EPEC';
647
                $descEvento = 'EPEC';
648
                break;
649
            case '111500':
650
            case '111501':
651
                //EPP
652
                //Pedido de prorrogação
653
                $aliasEvento = 'EPP';
654
                $descEvento = 'Pedido de Prorrogacao';
655
                break;
656
            case '111502':
657
            case '111503':
658
                //ECPP
659
                //Cancelamento do Pedido de prorrogação
660
                $aliasEvento = 'ECPP';
661
                $descEvento = 'Cancelamento de Pedido de Prorrogacao';
662
                break;
663
            case '210200':
664
                //Confirmacao da Operacao
665
                $aliasEvento = 'EvConfirma';
666
                $descEvento = 'Confirmacao da Operacao';
667
                break;
668
            case '210210':
669
                //Ciencia da Operacao
670
                $aliasEvento = 'EvCiencia';
671
                $descEvento = 'Ciencia da Operacao';
672
                break;
673
            case '210220':
674
                //Desconhecimento da Operacao
675
                $aliasEvento = 'EvDesconh';
676
                $descEvento = 'Desconhecimento da Operacao';
677
                break;
678
            case '210240':
679
                //Operacao não Realizada
680
                $aliasEvento = 'EvNaoRealizada';
681
                $descEvento = 'Operacao nao Realizada';
682
                break;
683
            default:
684
                $msg = "O código do tipo de evento informado não corresponde a "
685
                    . "nenhum evento estabelecido.";
686
                throw new Exception\RuntimeException($msg);
687
        }
688
        return array('alias' => $aliasEvento, 'desc' => $descEvento);
689
    }
690
691
    /**
692
     * validarXml
693
     * Valida qualquer xml do sistema CTe com seu xsd
694
     * NOTA: caso não exista um arquivo xsd apropriado retorna false
695
     *
696
     * @param  string $xml path ou conteudo do xml
697
     * @return boolean
698
     */
699
    public function validarXml($xml = '')
700
    {
701
        $aResp = array();
702
        $schem = IdentifyCTe::identificar($xml, $aResp);
703
        if ($schem == '') {
704
            return true;
705
        }
706
        $xsdFile = $aResp['Id'].'_v'.$aResp['versao'].'.xsd';
707
        $xsdPath = NFEPHP_ROOT.DIRECTORY_SEPARATOR .
708
            'schemas' .
709
            DIRECTORY_SEPARATOR .
710
            $this->aConfig['schemasCTe'] .
711
            DIRECTORY_SEPARATOR .
712
            $xsdFile;
713
        if (! is_file($xsdPath)) {
714
            $this->erros[] = "O arquivo XSD $xsdFile não foi localizado.";
715
            return false;
716
        }
717
        if (! ValidXsd::validar($aResp['xml'], $xsdPath)) {
718
            $this->erros[] = ValidXsd::$errors;
719
            return false;
720
        }
721
        return true;
722
    }
723
724
    /**
725
     * Transmite a correção
726
     * conforme o MOC(Manual de Orientações do Contribuinte)
727
     * Art. 58-B Fica permitida a utilização de carta de correção,
728
     * para regularização de erro ocorrido na emissão de documentos
729
     * fiscais relativos à prestação de serviço de transporte, desde que o
730
     * erro não esteja relacionado com:
731
     * I - as variáveis que determinam o valor do imposto tais como:
732
     *  base de cálculo, alíquota, diferença de preço, quantidade, valor da prestação
733
     * II - a correção de dados cadastrais que implique mudança do emitente,
734
     *  tomador, remetente ou do destinatário;
735
     * III - a data de emissão ou de saída.
736
     *
737
     * @param type $siglaUF
738
     * @param type $tpAmb
739
     * @param type $cnpj
740
     * @param type $chave
741
     * @param type $nSeqEvento
742
     * @param type $grupoAlterado
743
     * @param type $campoAlterado
744
     * @param type $valorAlterado
745
     * @param type $nroItemAlterado
746
     * @param type $aRetorno
747
     * @return type
748
     * @throws Exception\InvalidArgumentException
749
     */
750
    public function sefazCartaCorrecao(
751
        $siglaUF = '',
752
        $tpAmb = '2',
753
        $cnpj = '',
754
        $chave = '',
755
        $nSeqEvento = '1',
756
        $grupoAlterado = '',
757
        $campoAlterado = '',
758
        $valorAlterado = '',
759
        $nroItemAlterado = '01',
760
        &$aRetorno = array()
761
    ) {
762
        $chCTe = preg_replace('/[^0-9]/', '', $chave);
763
764
        //validação dos dados de entrada
765
        if (strlen($chCTe) != 44) {
766
            $msg = "Uma chave de CTe válida não foi passada como parâmetro $chCTe.";
767
            throw new Exception\InvalidArgumentException($msg);
768
        }
769
        if ($siglaUF == '' || $cnpj == '' || $chave == '' ||
770
            $grupoAlterado == '' || $campoAlterado == '' || $valorAlterado == ''
771
        ) {
772
            $msg = "Preencha os campos obrigatórios!";
773
            throw new Exception\InvalidArgumentException($msg);
774
        }
775
776
        //estabelece o codigo do tipo de evento CARTA DE CORRECAO
777
        $tpEvento = '110110';
778
        $descEvento = 'Carta de Correcao';
779
780
        //monta mensagem
781
        $tagAdic =
782
            "<evCCeCTe>"
783
            . "<descEvento>$descEvento</descEvento>"
784
            . "<infCorrecao>"
785
            . "<grupoAlterado>$grupoAlterado</grupoAlterado>"
786
            . "<campoAlterado>$campoAlterado</campoAlterado>"
787
            . "<valorAlterado>$valorAlterado</valorAlterado>"
788
            . "<nroItemAlterado>$nroItemAlterado</nroItemAlterado>"
789
            . "</infCorrecao>"
790
            . "<xCondUso>"
791
            . "A Carta de Correcao e disciplinada pelo Art. 58-B do "
792
            . "CONVENIO/SINIEF 06/89: Fica permitida a utilizacao de carta de "
793
            . "correcao, para regularizacao de erro ocorrido na emissao de "
794
            . "documentos fiscais relativos a prestacao de servico de transporte, "
795
            . "desde que o erro nao esteja relacionado com: I - as variaveis que "
796
            . "determinam o valor do imposto tais como: base de calculo, "
797
            . "aliquota, diferenca de preco, quantidade, valor da prestacao;II - "
798
            . "a correcao de dados cadastrais que implique mudanca do emitente, "
799
            . "tomador, remetente ou do destinatario;III - a data de emissao ou "
800
            . "de saida."
801
            . "</xCondUso>"
802
            ."</evCCeCTe>";
803
        $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]/', '', $chave) on line 762 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...
804
        $aRetorno = $this->aLastRetEvent;
805
        return $retorno;
806
    }
807
808
    public function addProtocolo($pathCTeFile = '', $pathProtfile = '', $saveFile = false)
809
    {
810
        //carrega a CTe
811
        $docCte = new Dom();
812
813
        if (file_exists($pathCTeFile)) {
814
            //carrega o XML pelo caminho do arquivo informado
815
            $docCte->loadXMLFile($pathCTeFile);
816
        } else {
817
            //carrega o XML pelo conteúdo
818
            $docCte->loadXMLString($pathCTeFile);
819
        }
820
821
        $nodecte = $docCte->getNode('CTe', 0);
822
        if ($nodecte == '') {
823
            $msg = "O arquivo indicado como CTe não é um xml de CTe!";
824
            throw new Exception\RuntimeException($msg);
825
        }
826
        if ($docCte->getNode('Signature') == '') {
827
            $msg = "A CTe não está assinada!";
828
            throw new Exception\RuntimeException($msg);
829
        }
830
        //carrega o protocolo
831
        $docprot = new Dom();
832
833
        if (file_exists($pathProtfile)) {
834
            //carrega o XML pelo caminho do arquivo informado
835
            $docprot->loadXMLFile($pathProtfile);
836
        } else {
837
            //carrega o XML pelo conteúdo
838
            $docprot->loadXMLString($pathProtfile);
839
        }
840
841
        $nodeprots = $docprot->getElementsByTagName('protCTe');
842
        if ($nodeprots->length == 0) {
843
            $msg = "O arquivo indicado não contem um protocolo de autorização!";
844
            throw new Exception\RuntimeException($msg);
845
        }
846
        //carrega dados da CTe
847
        $tpAmb = $docCte->getNodeValue('tpAmb');
848
        $anomes = date(
849
            'Ym',
850
            DateTime::convertSefazTimeToTimestamp($docCte->getNodeValue('dhEmi'))
851
        );
852
//        $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...
853
//        $versao = $infCTe->getAttribute("versao");
854
//        $chaveId = $infCTe->getAttribute("Id");
855
//        $chaveCTe = preg_replace('/[^0-9]/', '', $chaveId);
856
        $digValueCTe = $docCte->getNodeValue('DigestValue');
857
        //carrega os dados do protocolo
858
        for ($i = 0; $i < $nodeprots->length; $i++) {
859
            $nodeprot = $nodeprots->item($i);
860
            $protver = $nodeprot->getAttribute("versao");
861
            $chaveProt = $nodeprot->getElementsByTagName("chCTe")->item(0)->nodeValue;
862
            $digValueProt = ($nodeprot->getElementsByTagName("digVal")->length)
863
                ? $nodeprot->getElementsByTagName("digVal")->item(0)->nodeValue
864
                : '';
865
            $infProt = $nodeprot->getElementsByTagName("infProt")->item(0);
866
//            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...
867
//                break;
868
//            }
869
        }
870
        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...
871
            $msg = "Inconsistência! O DigestValue da CTe não combina com o do digVal do protocolo indicado!";
872
            throw new Exception\RuntimeException($msg);
873
        }
874
//        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...
875
//            $msg = "O protocolo indicado pertence a outra CTe. Os números das chaves não combinam !";
876
//            throw new Exception\RuntimeException($msg);
877
//        }
878
        //cria a CTe processada com a tag do protocolo
879
        $procCte = new \DOMDocument('1.0', 'utf-8');
880
        $procCte->formatOutput = false;
881
        $procCte->preserveWhiteSpace = false;
882
        //cria a tag cteProc
883
        $cteProc = $procCte->createElement('cteProc');
884
        $procCte->appendChild($cteProc);
885
        //estabele o atributo de versão
886
        $cteProcAtt1 = $cteProc->appendChild($procCte->createAttribute('versao'));
887
        $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...
888
        //estabelece o atributo xmlns
889
        $cteProcAtt2 = $cteProc->appendChild($procCte->createAttribute('xmlns'));
890
        $cteProcAtt2->appendChild($procCte->createTextNode($this->urlPortal));
891
        //inclui a tag CTe
892
        $node = $procCte->importNode($nodecte, true);
893
        $cteProc->appendChild($node);
894
        //cria tag protCTe
895
        $protCTe = $procCte->createElement('protCTe');
896
        $cteProc->appendChild($protCTe);
897
        //estabele o atributo de versão
898
        $protCTeAtt1 = $protCTe->appendChild($procCte->createAttribute('versao'));
899
        $protCTeAtt1->appendChild($procCte->createTextNode($protver));
900
        //cria tag infProt
901
        $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...
902
        $protCTe->appendChild($nodep);
903
        //salva o xml como string em uma variável
904
        $procXML = $procCte->saveXML();
905
        //remove as informações indesejadas
906
        $procXML = Strings::clearProt($procXML);
907
        if ($saveFile) {
908
//            $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...
909
            $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...
910
            $this->zGravaFile(
911
                'cte',
912
                $tpAmb,
913
                $filename,
914
                $procXML,
915
                'enviadas'.DIRECTORY_SEPARATOR.'aprovadas',
916
                $anomes
917
            );
918
        }
919
        return $procXML;
920
    }
921
922
923
    /**
924
     * addCancelamento
925
     * Adiciona a tga de cancelamento a uma CTe já autorizada
926
     * NOTA: não é requisito da SEFAZ, mas auxilia na identificação das CTe que foram canceladas
927
     * @param string $pathCTefile
928
     * @param string $pathCancfile
929
     * @param bool $saveFile
930
     * @return string
931
     * @throws Exception\RuntimeException
932
     */
933
    public function addCancelamento($pathCTefile = '', $pathCancfile = '', $saveFile = false)
934
    {
935
        $procXML = '';
936
        //carrega a CTe
937
        $docCTe = new Dom();
938
        
939
        if (file_exists($pathCTefile)) {
940
            //carrega o XML pelo caminho do arquivo informado
941
            $docCTe->loadXMLFile($pathCTefile);
942
        } else {
943
            //carrega o XML pelo conteúdo
944
            $docCTe->loadXMLString($pathCTefile);
945
        }
946
        
947
        $nodeCTe = $docCTe->getNode('CTe', 0);
948
        if ($nodeCTe == '') {
949
            $msg = "O arquivo indicado como CTe não é um xml de CTe!";
950
            throw new Exception\RuntimeException($msg);
951
        }
952
        $proCTe = $docCTe->getNode('protCTe');
953
        if ($proCTe == '') {
954
            $msg = "A CTe não está protocolada ainda!!";
955
            throw new Exception\RuntimeException($msg);
956
        }
957
        $chaveCTe = $proCTe->getElementsByTagName('chCTe')->item(0)->nodeValue;
958
        //$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...
959
        $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...
960
        $anomes = date(
961
            'Ym',
962
            DateTime::convertSefazTimeToTimestamp($docCTe->getNodeValue('dhEmi'))
963
        );
964
        //carrega o cancelamento
965
        //pode ser um evento ou resultado de uma consulta com multiplos eventos
966
        $doccanc = new Dom();
967
        
968
        if (file_exists($pathCancfile)) {
969
            //carrega o XML pelo caminho do arquivo informado
970
            $doccanc->loadXMLFile($pathCancfile);
971
        } else {
972
            //carrega o XML pelo conteúdo
973
            $doccanc->loadXMLString($pathCancfile);
974
        }
975
        $retEvento = $doccanc->getElementsByTagName('retEventoCTe')->item(0);
976
        $eventos = $retEvento->getElementsByTagName('infEvento');
977
        foreach ($eventos as $evento) {
978
            //evento
979
            $cStat = $evento->getElementsByTagName('cStat')->item(0)->nodeValue;
980
            $tpAmb = $evento->getElementsByTagName('tpAmb')->item(0)->nodeValue;
981
            $chaveEvento = $evento->getElementsByTagName('chCTe')->item(0)->nodeValue;
982
            $tpEvento = $evento->getElementsByTagName('tpEvento')->item(0)->nodeValue;
983
            //$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...
984
            //verifica se conferem os dados
985
            //cStat = 135 ==> evento homologado
986
            //cStat = 136 ==> vinculação do evento à respectiva NF-e prejudicada
987
            //cStat = 155 ==> Cancelamento homologado fora de prazo
988
            //tpEvento = 110111 ==> Cancelamento
989
            //chave do evento == chave da CTe
990
            //protocolo do evneto ==  protocolo da CTe
991
            if (($cStat == '135' || $cStat == '136' || $cStat == '155') &&
992
                $tpEvento == '110111' &&
993
                $chaveEvento == $chaveCTe
994
            ) {
995
                $proCTe->getElementsByTagName('cStat')->item(0)->nodeValue = '101';
996
                $proCTe->getElementsByTagName('xMotivo')->item(0)->nodeValue = 'Cancelamento de CT-e homologado';
997
                $procXML = $docCTe->saveXML();
998
                //remove as informações indesejadas
999
                $procXML = Strings::clearProt($procXML);
1000
                if ($saveFile) {
1001
                    $filename = "$chaveCTe-protCTe.xml";
1002
                    $this->zGravaFile(
1003
                        'cte',
1004
                        $tpAmb,
1005
                        $filename,
1006
                        $procXML,
1007
                        'canceladas',
1008
                        $anomes
1009
                    );
1010
                }
1011
                break;
1012
            }
1013
        }
1014
        return (string) $procXML;
1015
    }
1016
}
1017