Completed
Push — master ( 95335a...1db124 )
by Roberto
05:09
created

Tools   F

Complexity

Total Complexity 89

Size/Duplication

Total Lines 976
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 11

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 89
lcom 2
cbo 11
dl 0
loc 976
ccs 0
cts 655
cp 0
rs 3.9999
c 0
b 0
f 0

14 Methods

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

How to fix   Complexity   

Complex Class

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

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

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

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

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

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

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

// Bar.php
namespace OtherDir;

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

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

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

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

// Bar.php
namespace OtherDir;

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