Completed
Push — master ( 065741...7fa6ac )
by Roberto
15:44 queued 13:11
created

Tools::assina()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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