Completed
Push — master ( 5f2082...2ea8e4 )
by
unknown
9s
created

Tools::zTpEv()   C

Complexity

Conditions 12
Paths 12

Size

Total Lines 61
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 156

Importance

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