Completed
Push — master ( 7fa6ac...fa7fd6 )
by Roberto
07:15
created

Tools::sefazInutiliza()   B

Complexity

Conditions 6
Paths 14

Size

Total Lines 83
Code Lines 62

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 83
ccs 0
cts 71
cp 0
rs 8.3634
cc 6
eloc 62
nc 14
nop 7
crap 42

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
namespace NFePHP\CTe;
4
5
/**
6
 * Classe principal para a comunicação com a SEFAZ
7
 *
8
 * @category  Library
9
 * @package   nfephp-org/sped-cte
10
 * @copyright 2009-2016 NFePHP
11
 * @license   http://www.gnu.org/licenses/lesser.html LGPL v3
12
 * @link      http://github.com/nfephp-org/sped-cte for the canonical source repository
13
 * @author    Roberto L. Machado <linux.rlm at gmail dot com>
14
 *
15
 *        CONTRIBUIDORES (em ordem alfabetica):
16
 *
17
 *          Maison K. Sakamoto <maison.sakamoto at gmail do com>
18
 */
19
20
//use NFePHP\Common\Base\BaseTools;
21
use NFePHP\CTe\BaseTools;
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
30
if (!defined('NFEPHP_ROOT')) {
31
    define('NFEPHP_ROOT', dirname(dirname(__FILE__)));
32
}
33
34
class Tools extends BaseTools
35
{
36
    /**
37
     * urlPortal
38
     * Instância do WebService
39
     *
40
     * @var string
41
     */
42
    protected $urlPortal = 'http://www.portalfiscal.inf.br/cte';
43
44
    /**
45
     * erros
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
     *
55
     * @var modelo
56
     */
57
    protected $modelo = '57';
58
    
59
    /**
60
     * assina
61
     *
62
     * @param  string  $xml
63
     * @param  boolean $saveFile
64
     * @return string
65
     * @throws Exception\RuntimeException
66
     */
67
    public function assina($xml = '', $saveFile = false)
68
    {
69
        return $this->assinaDoc($xml, 'cte', 'infCte', $saveFile);
70
    }
71
72
    /**
73
     * Transmite o xml para a sefaz
74
     *
75
     * @param type $aXml
76
     * @param type $tpAmb
77
     * @param type $idLote
78
     * @param type $aRetorno
79
     * @param int $indSinc
80
     * @param type $compactarZip
81
     * @return type
82
     * @throws Exception\InvalidArgumentException
83
     * @throws Exception\RuntimeException
84
     */
85
    public function sefazEnvia(
86
        $aXml,
87
        $tpAmb = '2',
88
        $idLote = '',
89
        &$aRetorno = array(),
90
        $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...
91
        $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...
92
    ) {
93
        $sxml = $aXml;
94
        if (empty($aXml)) {
95
            $msg = "Pelo menos uma NFe deve ser informada.";
96
            throw new Exception\InvalidArgumentException($msg);
97
        }
98
        if (is_array($aXml)) {
99
            if (count($aXml) > 1) {
100
                //multiplas cte, não pode ser sincrono
101
                $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...
102
            }
103
            $sxml = implode("", $sxml);
104
        }
105
        $sxml = preg_replace("/<\?xml.*\?>/", "", $sxml);
106
        $siglaUF = $this->aConfig['siglaUF'];
107
        
108
        if ($tpAmb == '') {
109
            $tpAmb = $this->aConfig['tpAmb'];
110
        }
111
        if ($idLote == '') {
112
            $idLote = LotNumber::geraNumLote(15);
113
        }
114
        //carrega serviço
115
        $servico = 'CteRecepcao';
116
        $this->zLoadServico(
117
            'cte',
118
            $servico,
119
            $siglaUF,
120
            $tpAmb
121
        );
122
        
123
        if ($this->urlService == '') {
124
            $msg = "O envio de lote não está disponível na SEFAZ $siglaUF!!!";
125
            throw new Exception\RuntimeException($msg);
126
        }
127
        
128
        // Montagem dos dados da mensagem SOAP
129
        $dados = "<cteDadosMsg xmlns=\"$this->urlNamespace\">"
130
            . "<enviCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
131
            . "<idLote>$idLote</idLote>"
132
            . "$sxml"
133
            . "</enviCTe>"
134
            . "</cteDadosMsg>";
135
        // Envia dados via SOAP
136
        $retorno = $this->oSoap->send(
137
            $this->urlService,
138
            $this->urlNamespace,
139
            $this->urlHeader,
140
            $dados,
141
            $this->urlMethod
142
        );
143
144
        $lastMsg = $this->oSoap->lastMsg;
145
        $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...
146
        //salva mensagens
147
        $filename = "$idLote-enviCTe.xml";
148
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
149
        $filename = "$idLote-retEnviCTe.xml";
150
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
151
        //tratar dados de retorno
152
153
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
154
        //caso o envio seja recebido com sucesso mover a NFe da pasta
155
        //das assinadas para a pasta das enviadas
156
        return (string) $retorno;
157
    }
158
159
    /**
160
     * Consulta o recibo na sefaz
161
     *
162
     * @param type $recibo
163
     * @param type $tpAmb
164
     * @param type $aRetorno
165
     * @return type
166
     * @throws Exception\InvalidArgumentException
167
     * @throws Exception\RuntimeException
168
     */
169
    public function sefazConsultaRecibo($recibo = '', $tpAmb = '2', &$aRetorno = array())
170
    {
171
        if ($recibo == '') {
172
            $msg = "Deve ser informado um recibo.";
173
            throw new Exception\InvalidArgumentException($msg);
174
        }
175
        if ($tpAmb == '') {
176
            $tpAmb = $this->aConfig['tpAmb'];
177
        }
178
        $siglaUF = $this->aConfig['siglaUF'];
179
        //carrega serviço
180
        $servico = 'CteRetRecepcao';
181
        $this->zLoadServico(
182
            'cte',
183
            $servico,
184
            $siglaUF,
185
            $tpAmb
186
        );
187
        if ($this->urlService == '') {
188
            $msg = "A consulta de NFe não está disponível na SEFAZ $siglaUF!!!";
189
            throw new Exception\RuntimeException($msg);
190
        }
191
        $cons = "<consReciCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
192
            . "<tpAmb>$tpAmb</tpAmb>"
193
            . "<nRec>$recibo</nRec>"
194
            . "</consReciCTe>";
195
        //montagem dos dados da mensagem SOAP
196
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$cons</cteDadosMsg>";
197
             
198
        //envia a solicitação via SOAP
199
        $retorno = $this->oSoap->send(
200
            $this->urlService,
201
            $this->urlNamespace,
202
            $this->urlHeader,
203
            $body,
204
            $this->urlMethod
205
        );
206
        $lastMsg = $this->oSoap->lastMsg;
207
        $this->soapDebug = $this->oSoap->soapDebug;
208
        //salva mensagens
209
        $filename = "$recibo-consReciCTe.xml";
210
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
211
        $filename = "$recibo-retConsReciCTe.xml";
212
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
213
        //tratar dados de retorno
214
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
215
        //podem ser retornados nenhum, um ou vários protocolos
216
        //caso existam protocolos protocolar as NFe e movelas-las para a
217
        //pasta enviadas/aprovadas/anomes
218
        return (string) $retorno;
219
    }
220
221
    /**
222
     * consulta a chave de acesso do CT-e
223
     *
224
     * @param type $chave
225
     * @param type $tpAmb
226
     * @param type $aRetorno
227
     * @return type
228
     * @throws Exception\InvalidArgumentException
229
     * @throws Exception\RuntimeException
230
     */
231
    public function sefazConsultaChave($chave = '', $tpAmb = '2', &$aRetorno = array())
232
    {
233
        $chNFe = preg_replace('/[^0-9]/', '', $chave);
234
        if (strlen($chNFe) != 44) {
235
            $msg = "Uma chave de 44 dígitos da NFe deve ser passada.";
236
            throw new Exception\InvalidArgumentException($msg);
237
        }
238
        if ($tpAmb == '') {
239
            $tpAmb = $this->aConfig['tpAmb'];
240
        }
241
        $cUF = substr($chNFe, 0, 2);
242
        $siglaUF = $this->zGetSigla($cUF);
243
        //carrega serviço
244
        $servico = 'CteConsultaProtocolo';
245
        $this->zLoadServico(
246
            'cte',
247
            $servico,
248
            $siglaUF,
249
            $tpAmb
250
        );
251
        if ($this->urlService == '') {
252
            $msg = "A consulta de NFe não está disponível na SEFAZ $siglaUF!!!";
253
            throw new Exception\RuntimeException($msg);
254
        }
255
        $cons = "<consSitCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
256
            . "<tpAmb>$tpAmb</tpAmb>"
257
            . "<xServ>CONSULTAR</xServ>"
258
            . "<chCTe>$chNFe</chCTe>"
259
            . "</consSitCTe>";
260
        //montagem dos dados da mensagem SOAP
261
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$cons</cteDadosMsg>";
262
        //envia a solicitação via SOAP
263
        $retorno = $this->oSoap->send(
264
            $this->urlService,
265
            $this->urlNamespace,
266
            $this->urlHeader,
267
            $body,
268
            $this->urlMethod
269
        );
270
        $lastMsg = $this->oSoap->lastMsg;
271
        $this->soapDebug = $this->oSoap->soapDebug;
272
        //salva mensagens
273
        $filename = "$chNFe-consSitCTe.xml";
274
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
275
        $filename = "$chNFe-retConsSitNFe.xml";
276
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
277
        //tratar dados de retorno
278
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
279
        return (string) $retorno;
280
    }
281
282
    /**
283
     * consulta disponibilidade do serviço web service da sefaz
284
     *
285
     * @param type $siglaUF
286
     * @param type $tpAmb
287
     * @param type $aRetorno
288
     * @return type
289
     * @throws Exception\RuntimeException
290
     */
291
    public function sefazStatus($siglaUF = '', $tpAmb = '2', &$aRetorno = array())
292
    {
293
        if ($tpAmb == '') {
294
            $tpAmb = $this->aConfig['tpAmb'];
295
        }
296
        if ($siglaUF == '') {
297
            $siglaUF = $this->aConfig['siglaUF'];
298
        }
299
        //carrega serviço
300
        $servico = 'CteStatusServico';
301
        $this->zLoadServico(
302
            'cte',
303
            $servico,
304
            $siglaUF,
305
            $tpAmb
306
        );
307
        if ($this->urlService == '') {
308
            $msg = "O status não está disponível na SEFAZ $siglaUF!!!";
309
            throw new Exception\RuntimeException($msg);
310
        }
311
        $cons = "<consStatServCte xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
312
            . "<tpAmb>$tpAmb</tpAmb>"
313
            . "<xServ>STATUS</xServ></consStatServCte>";
314
        //montagem dos dados da mensagem SOAP
315
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$cons</cteDadosMsg>";
316
        //consome o webservice e verifica o retorno do SOAP
317
        $retorno = $this->oSoap->send(
318
            $this->urlService,
319
            $this->urlNamespace,
320
            $this->urlHeader,
321
            $body,
322
            $this->urlMethod
323
        );
324
        $lastMsg = $this->oSoap->lastMsg;
325
        $this->soapDebug = $this->oSoap->soapDebug;
326
        $datahora = date('Ymd_His');
327
        $filename = $siglaUF."_"."$datahora-consStatServCte.xml";
328
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
329
        $filename = $siglaUF."_"."$datahora-retConsStatServCte.xml";
330
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
331
        //tratar dados de retorno
332
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
333
        return (string) $retorno;
334
    }
335
336
    /**
337
     * Inutiza sequencia de numeracao
338
     *
339
     * @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...
340
     * @param type $nSerie
341
     * @param type $nIni
342
     * @param type $nFin
343
     * @param type $xJust
344
     * @param type $tpAmb
345
     * @param type $aRetorno
346
     * @return boolean
347
     * @throws Exception\RuntimeException
348
     * @throws Exception\InvalidArgumentException
349
     */
350
    public function sefazInutiliza(
351
        $nSerie = '1',
352
        $nIni = '',
353
        $nFin = '',
354
        $xJust = '',
355
        $tpAmb = '2',
356
        &$aRetorno = array(),
357
        $salvarMensagens = true
358
    ) {
359
        if ($tpAmb == '') {
360
            $tpAmb = $this->aConfig['tpAmb'];
361
        }
362
        // Identificação do serviço
363
        $servico = 'CteInutilizacao';
364
        //monta serviço
365
        $siglaUF = $this->aConfig['siglaUF'];
366
        $this->zLoadServico(
367
            'cte',
368
            $servico,
369
            $siglaUF,
370
            $tpAmb
371
        );
372
        if ($this->urlService == '') {
373
            $msg = "A inutilização não está disponível na SEFAZ $siglaUF!!!";
374
            throw new Exception\RuntimeException($msg);
375
        }
376
        //montagem dos dados da mensagem SOAP
377
        $cnpj = $this->aConfig['cnpj'];
378
        $sAno = (string) date('y');
379
        $sSerie = str_pad($nSerie, 3, '0', STR_PAD_LEFT);
380
        $sInicio = str_pad($nIni, 9, '0', STR_PAD_LEFT);
381
        $sFinal = str_pad($nFin, 9, '0', STR_PAD_LEFT);
382
        
383
        // Identificador da TAG a ser assinada formada com Código da UF +
384
        // precedida do literal “ID”
385
        // 41 posições
386
        $id = 'ID'.$this->urlcUF.$cnpj.'57'.$sSerie.$sInicio.$sFinal;
387
        // Montagem do corpo da mensagem
388
        $dXML = "<inutCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
389
            ."<infInut Id=\"$id\">"
390
            ."<tpAmb>$tpAmb</tpAmb>"
391
            ."<xServ>INUTILIZAR</xServ>"
392
            ."<cUF>$this->urlcUF</cUF>"
393
            ."<ano>$sAno</ano>"
394
            ."<CNPJ>$cnpj</CNPJ>"
395
            ."<mod>57</mod>"
396
            ."<serie>$nSerie</serie>"
397
            ."<nCTIni>$nIni</nCTIni>"
398
            ."<nCTFin>$nFin</nCTFin>"
399
            ."<xJust>$xJust</xJust>"
400
            ."</infInut></inutCTe>";
401
        //assina a solicitação de inutilização
402
        $signedMsg = $this->oCertificate->signXML($dXML, 'infInut');
403
        $signedMsg = Strings::clearXml($signedMsg, true);
404
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$signedMsg</cteDadosMsg>";
405
        //envia a solicitação via SOAP
406
        $retorno = $this->oSoap->send(
407
            $this->urlService,
408
            $this->urlNamespace,
409
            $this->urlHeader,
410
            $body,
411
            $this->urlMethod
412
        );
413
        $lastMsg = $this->oSoap->lastMsg;
414
        $this->soapDebug = $this->oSoap->soapDebug;
415
        //salva mensagens
416
        if ($salvarMensagens) {
417
            $filename = "$sAno-$this->modelo-$sSerie-".$sInicio."_".$sFinal."-inutCTe.xml";
418
            $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
419
            $filename = "$sAno-$this->modelo-$sSerie-".$sInicio."_".$sFinal."-retInutCTe.xml";
420
            $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
421
        }
422
        //tratar dados de retorno
423
        $aRetorno = Response::readReturnSefaz($servico, $retorno);
424
        if ($aRetorno['cStat'] == '102') {
425
            $retorno = $this->zAddProtMsg('ProcInutCTe', 'inutCTe', $signedMsg, 'retInutCTe', $retorno);
426
            if ($salvarMensagens) {
427
                $filename = "$sAno-$this->modelo-$sSerie-".$sInicio."_".$sFinal."-procInutCTe.xml";
428
                $this->zGravaFile('cte', $tpAmb, $filename, $retorno, 'inutilizadas');
429
            }
430
        }
431
        return (string) $retorno;
432
    }
433
434
    /**
435
     * Cancelamento de numero CT-e
436
     *
437
     * @param type $chCTe
438
     * @param type $tpAmb
439
     * @param type $xJust
440
     * @param type $nProt
441
     * @param type $aRetorno
442
     * @return type
443
     * @throws Exception\InvalidArgumentException
444
     */
445
    public function sefazCancela($chCTe = '', $tpAmb = '2', $xJust = '', $nProt = '', &$aRetorno = array())
446
    {
447
        $chCTe = preg_replace('/[^0-9]/', '', $chCTe);
448
        $nProt = preg_replace('/[^0-9]/', '', $nProt);
449
        $xJust = Strings::cleanString($xJust);
450
        //validação dos dados de entrada
451
        if (strlen($chCTe) != 44) {
452
            $msg = "Uma chave de CTe válida não foi passada como parâmetro $chCTe.";
453
            throw new Exception\InvalidArgumentException($msg);
454
        }
455
        if ($nProt == '') {
456
            $msg = "Não foi passado o numero do protocolo!!";
457
            throw new Exception\InvalidArgumentException($msg);
458
        }
459
        if (strlen($xJust) < 15 || strlen($xJust) > 255) {
460
            $msg = "A justificativa deve ter pelo menos 15 digitos e no máximo 255!!";
461
            throw new Exception\InvalidArgumentException($msg);
462
        }
463
        $siglaUF = $this->zGetSigla(substr($chCTe, 0, 2));
464
465
        //estabelece o codigo do tipo de evento CANCELAMENTO
466
        $tpEvento = '110111';
467
        $descEvento = 'Cancelamento';
468
        $nSeqEvento = 1;
469
        //monta mensagem
470
        $tagAdic = "<evCancCTe>"
471
            . "<descEvento>$descEvento</descEvento>"
472
            . "<nProt>$nProt</nProt>"
473
            . "<xJust>$xJust</xJust>"
474
            . "</evCancCTe>";
475
        $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 447 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...
476
        $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...
477
        return $retorno;
478
    }
479
480
    /**
481
     * zSefazEvento
482
     *
483
     * @param    string $siglaUF
484
     * @param    string $chCTe
485
     * @param    string $tpAmb
486
     * @param    string $tpEvento
487
     * @param    string $nSeqEvento
488
     * @param    string $tagAdic
489
     * @return   string
490
     * @throws   Exception\RuntimeException
491
     * @internal function zLoadServico (Common\Base\BaseTools)
492
     */
493
    protected function zSefazEvento(
494
        $siglaUF = '',
495
        $chCTe = '',
496
        $tpAmb = '2',
497
        $tpEvento = '',
498
        $nSeqEvento = '1',
499
        $tagAdic = ''
500
    ) {
501
        if ($tpAmb == '') {
502
            $tpAmb = $this->aConfig['tpAmb'];
503
        }
504
        //carrega serviço
505
        $servico = 'CteRecepcaoEvento';
506
        $this->zLoadServico(
507
            'cte',
508
            $servico,
509
            $siglaUF,
510
            $tpAmb
511
        );
512
        if ($this->urlService == '') {
513
            $msg = "A recepção de eventos não está disponível na SEFAZ $siglaUF!!!";
514
            throw new Exception\RuntimeException($msg);
515
        }
516
        $aRet = $this->zTpEv($tpEvento);
517
        $aliasEvento = $aRet['alias'];
518
        $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...
519
        $cnpj = $this->aConfig['cnpj'];
520
        $dhEvento = (string) str_replace(' ', 'T', date('Y-m-d H:i:s'));
521
        $sSeqEvento = str_pad($nSeqEvento, 2, "0", STR_PAD_LEFT);
522
        $eventId = "ID".$tpEvento.$chCTe.$sSeqEvento;
523
        $cOrgao = $this->urlcUF;
524
        if ($siglaUF == 'AN') {
525
            $cOrgao = '91';
526
        }
527
        $mensagem = "<infEvento Id=\"$eventId\">"
528
            . "<cOrgao>$cOrgao</cOrgao>"
529
            . "<tpAmb>$tpAmb</tpAmb>"
530
            . "<CNPJ>$cnpj</CNPJ>"
531
            . "<chCTe>$chCTe</chCTe>"
532
            . "<dhEvento>$dhEvento</dhEvento>"
533
            . "<tpEvento>$tpEvento</tpEvento>"
534
            . "<nSeqEvento>$nSeqEvento</nSeqEvento>"
535
            . "<detEvento versaoEvento=\"$this->urlVersion\">"
536
            . "$tagAdic"
537
            . "</detEvento>"
538
            . "</infEvento>";
539
540
        $cons = "<eventoCTe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
541
            . "$mensagem"
542
            . "</eventoCTe>";
543
544
        $signedMsg = $this->oCertificate->signXML($cons, 'infEvento');
545
        //limpa o xml
546
        $signedMsg = preg_replace("/<\?xml.*\?>/", "", $signedMsg);
547
        //montagem dos dados da mensagem SOAP
548
        $body = "<cteDadosMsg xmlns=\"$this->urlNamespace\">$signedMsg</cteDadosMsg>";
549
        
550
        $retorno = $this->oSoap->send(
551
            $this->urlService,
552
            $this->urlNamespace,
553
            $this->urlHeader,
554
            $body,
555
            $this->urlMethod
556
        );
557
        $lastMsg = $this->oSoap->lastMsg;
558
        $this->soapDebug = $this->oSoap->soapDebug;
559
        //salva mensagens
560
        $filename = "$chCTe-$aliasEvento-envEvento.xml";
561
        $this->zGravaFile('cte', $tpAmb, $filename, $lastMsg);
562
        $filename = "$chCTe-$aliasEvento-retEnvEvento.xml";
563
        $this->zGravaFile('cte', $tpAmb, $filename, $retorno);
564
        //tratar dados de retorno
565
        $this->aLastRetEvent = Response::readReturnSefaz($servico, $retorno);
566
        if ($this->aLastRetEvent['cStat'] == '128') {
567
            if ($this->aLastRetEvent['evento'][0]['cStat'] == '135' ||
568
                $this->aLastRetEvent['evento'][0]['cStat'] == '136' ||
569
                $this->aLastRetEvent['evento'][0]['cStat'] == '155'
570
            ) {
571
                $pasta = 'eventos'; //default
572
                if ($aliasEvento == 'CanCTe') {
573
                    $pasta = 'canceladas';
574
                    $filename = "$chCTe-$aliasEvento-procEvento.xml";
575
                } elseif ($aliasEvento == 'CCe') {
576
                    $pasta = 'cartacorrecao';
577
                    $filename = "$chCTe-$aliasEvento-$nSeqEvento-procEvento.xml";
578
                }
579
                $retorno = $this->zAddProtMsg('procEventoCTe', 'evento', $signedMsg, 'retEvento', $retorno);
580
                $this->zGravaFile('cte', $tpAmb, $filename, $retorno, $pasta);
581
            }
582
        }
583
        return (string) $retorno;
584
    }
585
586
    /**
587
     * zAddProtMsg
588
     *
589
     * @param  string $tagproc
590
     * @param  string $tagmsg
591
     * @param  string $xmlmsg
592
     * @param  string $tagretorno
593
     * @param  string $xmlretorno
594
     * @return string
595
     */
596
    protected function zAddProtMsg($tagproc, $tagmsg, $xmlmsg, $tagretorno, $xmlretorno)
597
    {
598
        $doc = new Dom();
599
        $doc->loadXMLString($xmlmsg);
600
        $nodedoc = $doc->getNode($tagmsg, 0);
601
        $procver = $nodedoc->getAttribute("versao");
602
        $procns = $nodedoc->getAttribute("xmlns");
603
604
        $doc1 = new Dom();
605
        $doc1->loadXMLString($xmlretorno);
606
        $nodedoc1 = $doc1->getNode($tagretorno, 0);
607
608
        $proc = new \DOMDocument('1.0', 'utf-8');
609
        $proc->formatOutput = false;
610
        $proc->preserveWhiteSpace = false;
611
        //cria a tag nfeProc
612
        $procNode = $proc->createElement($tagproc);
613
        $proc->appendChild($procNode);
614
        //estabele o atributo de versão
615
        $procNodeAtt1 = $procNode->appendChild($proc->createAttribute('versao'));
616
        $procNodeAtt1->appendChild($proc->createTextNode($procver));
617
        //estabelece o atributo xmlns
618
        $procNodeAtt2 = $procNode->appendChild($proc->createAttribute('xmlns'));
619
        $procNodeAtt2->appendChild($proc->createTextNode($procns));
620
        //inclui a tag inutNFe
621
        $node = $proc->importNode($nodedoc, true);
622
        $procNode->appendChild($node);
623
        //inclui a tag retInutNFe
624
        $node = $proc->importNode($nodedoc1, true);
625
        $procNode->appendChild($node);
626
        //salva o xml como string em uma variável
627
        $procXML = $proc->saveXML();
628
        //remove as informações indesejadas
629
        $procXML = Strings::clearProt($procXML);
630
        return $procXML;
631
    }
632
633
    /**
634
     * zTpEv
635
     *
636
     * @param  string $tpEvento
637
     * @return array
638
     * @throws Exception\RuntimeException
639
     */
640
    private function zTpEv($tpEvento = '')
641
    {
642
        //montagem dos dados da mensagem SOAP
643
        switch ($tpEvento) {
644
            case '110110':
645
                //CCe
646
                $aliasEvento = 'CCe';
647
                $descEvento = 'Carta de Correcao';
648
                break;
649
            case '110111':
650
                //cancelamento
651
                $aliasEvento = 'CancNFe';
652
                $descEvento = 'Cancelamento';
653
                break;
654
            case '110140':
655
                //EPEC
656
                //emissão em contingência EPEC
657
                $aliasEvento = 'EPEC';
658
                $descEvento = 'EPEC';
659
                break;
660
            case '111500':
661
            case '111501':
662
                //EPP
663
                //Pedido de prorrogação
664
                $aliasEvento = 'EPP';
665
                $descEvento = 'Pedido de Prorrogacao';
666
                break;
667
            case '111502':
668
            case '111503':
669
                //ECPP
670
                //Cancelamento do Pedido de prorrogação
671
                $aliasEvento = 'ECPP';
672
                $descEvento = 'Cancelamento de Pedido de Prorrogacao';
673
                break;
674
            case '210200':
675
                //Confirmacao da Operacao
676
                $aliasEvento = 'EvConfirma';
677
                $descEvento = 'Confirmacao da Operacao';
678
                break;
679
            case '210210':
680
                //Ciencia da Operacao
681
                $aliasEvento = 'EvCiencia';
682
                $descEvento = 'Ciencia da Operacao';
683
                break;
684
            case '210220':
685
                //Desconhecimento da Operacao
686
                $aliasEvento = 'EvDesconh';
687
                $descEvento = 'Desconhecimento da Operacao';
688
                break;
689
            case '210240':
690
                //Operacao não Realizada
691
                $aliasEvento = 'EvNaoRealizada';
692
                $descEvento = 'Operacao nao Realizada';
693
                break;
694
            default:
695
                $msg = "O código do tipo de evento informado não corresponde a "
696
                    . "nenhum evento estabelecido.";
697
                throw new Exception\RuntimeException($msg);
698
        }
699
        return array('alias' => $aliasEvento, 'desc' => $descEvento);
700
    }
701
702
    /**
703
     * validarXml
704
     * Valida qualquer xml do sistema NFe com seu xsd
705
     * NOTA: caso não exista um arquivo xsd apropriado retorna false
706
     *
707
     * @param  string $xml path ou conteudo do xml
708
     * @return boolean
709
     */
710
    public function validarXml($xml = '')
711
    {
712
        $aResp = array();
713
        $schem = IdentifyCTe::identificar($xml, $aResp);
714
        if ($schem == '') {
715
            return true;
716
        }
717
        $xsdFile = $aResp['Id'].'_v'.$aResp['versao'].'.xsd';
718
        $xsdPath = NFEPHP_ROOT.DIRECTORY_SEPARATOR .
719
            'schemas' .
720
            DIRECTORY_SEPARATOR .
721
            $this->aConfig['schemesCTe'] .
722
            DIRECTORY_SEPARATOR .
723
            $xsdFile;
724
        if (! is_file($xsdPath)) {
725
            $this->erros[] = "O arquivo XSD $xsdFile não foi localizado.";
726
            return false;
727
        }
728
        if (! ValidXsd::validar($aResp['xml'], $xsdPath)) {
729
            $this->erros[] = ValidXsd::$errors;
730
            return false;
731
        }
732
        return true;
733
    }
734
    
735
    /**
736
     * Transmite a correção
737
     * conforme o MOC(Manual de Orientações do Contribuinte)
738
     * Art. 58-B Fica permitida a utilização de carta de correção,
739
     * para regularização de erro ocorrido na emissão de documentos
740
     * fiscais relativos à prestação de serviço de transporte, desde que o
741
     * erro não esteja relacionado com:
742
     * I - as variáveis que determinam o valor do imposto tais como:
743
     *  base de cálculo, alíquota, diferença de preço, quantidade, valor da prestação
744
     * II - a correção de dados cadastrais que implique mudança do emitente,
745
     *  tomador, remetente ou do destinatário;
746
     * III - a data de emissão ou de saída.
747
     *
748
     * @param type $siglaUF
749
     * @param type $tpAmb
750
     * @param type $cnpj
751
     * @param type $chave
752
     * @param type $nSeqEvento
753
     * @param type $grupoAlterado
754
     * @param type $campoAlterado
755
     * @param type $valorAlterado
756
     * @param type $nroItemAlterado
757
     * @param type $aRetorno
758
     * @return type
759
     * @throws Exception\InvalidArgumentException
760
     */
761
    public function sefazCartaCorrecao(
762
        $siglaUF = '',
763
        $tpAmb = '2',
764
        $cnpj = '',
765
        $chave = '',
766
        $nSeqEvento = '1',
767
        $grupoAlterado = '',
768
        $campoAlterado = '',
769
        $valorAlterado = '',
770
        $nroItemAlterado = '01',
771
        &$aRetorno = array()
772
    ) {
773
        $chCTe = preg_replace('/[^0-9]/', '', $chave);
774
        
775
        //validação dos dados de entrada
776
        if (strlen($chCTe) != 44) {
777
            $msg = "Uma chave de CTe válida não foi passada como parâmetro $chCTe.";
778
            throw new Exception\InvalidArgumentException($msg);
779
        }
780
        if ($siglaUF == '' || $cnpj == '' || $chave == '' ||
781
            $grupoAlterado == '' || $campoAlterado == '' || $valorAlterado == ''
782
        ) {
783
            $msg = "Preencha os campos obrigatórios!";
784
            throw new Exception\InvalidArgumentException($msg);
785
        }
786
        
787
        //estabelece o codigo do tipo de evento CARTA DE CORRECAO
788
        $tpEvento = '110110';
789
        $descEvento = 'Carta de Correcao';
790
        
791
        //monta mensagem
792
        $tagAdic =
793
            "<evCCeCTe>"
794
                . "<descEvento>$descEvento</descEvento>"
795
                . "<infCorrecao>"
796
                    . "<grupoAlterado>$grupoAlterado</grupoAlterado>"
797
                    . "<campoAlterado>$campoAlterado</campoAlterado>"
798
                    . "<valorAlterado>$valorAlterado</valorAlterado>"
799
                    . "<nroItemAlterado>$nroItemAlterado</nroItemAlterado>"
800
                . "</infCorrecao>"
801
                . "<xCondUso>"
802
                    . "A Carta de Correcao e disciplinada pelo Art. 58-B do "
803
                    . "CONVENIO/SINIEF 06/89: Fica permitida a utilizacao de carta de "
804
                    . "correcao, para regularizacao de erro ocorrido na emissao de "
805
                    . "documentos fiscais relativos a prestacao de servico de transporte, "
806
                    . "desde que o erro nao esteja relacionado com: I - as variaveis que "
807
                    . "determinam o valor do imposto tais como: base de calculo, "
808
                    . "aliquota, diferenca de preco, quantidade, valor da prestacao;II - "
809
                    . "a correcao de dados cadastrais que implique mudanca do emitente, "
810
                    . "tomador, remetente ou do destinatario;III - a data de emissao ou "
811
                    . "de saida."
812
                . "</xCondUso>"
813
            ."</evCCeCTe>";
814
        $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 773 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...
815
        $aRetorno = $this->aLastRetEvent;
816
        return $retorno;
817
    }
818
}
819