Passed
Push — master ( eb8237...9d55e5 )
by Roberto
04:42 queued 02:34
created

Tools::sefazEPP()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 28
ccs 0
cts 17
cp 0
rs 9.472
c 0
b 0
f 0
cc 3
nc 4
nop 5
crap 12
1
<?php
2
3
namespace NFePHP\NFe;
4
5
/**
6
 * Class responsible for communication with SEFAZ extends
7
 * NFePHP\NFe\Common\Tools
8
 *
9
 * @category  NFePHP
10
 * @package   NFePHP\NFe\Tools
11
 * @copyright NFePHP Copyright (c) 2008-2020
12
 * @license   http://www.gnu.org/licenses/lgpl.txt LGPLv3+
13
 * @license   https://opensource.org/licenses/MIT MIT
14
 * @license   http://www.gnu.org/licenses/gpl.txt GPLv3+
15
 * @author    Roberto L. Machado <linux.rlm at gmail dot com>
16
 * @link      http://github.com/nfephp-org/sped-nfe for the canonical source repository
17
 */
18
19
use NFePHP\Common\Strings;
20
use NFePHP\Common\Signer;
21
use NFePHP\Common\UFList;
22
use NFePHP\NFe\Common\Tools as ToolsCommon;
23
use RuntimeException;
24
use InvalidArgumentException;
25
26
class Tools extends ToolsCommon
27
{
28
    const EVT_CONFIRMACAO = 210200; //only one per nfe seq=n
29
    const EVT_CIENCIA = 210210; //only one per nfe seq=1
30
    const EVT_DESCONHECIMENTO = 210220; //only one per nfe seq=n
31
    const EVT_NAO_REALIZADA = 210240; //only one per nfe but seq=n
32
    const EVT_CCE = 110110; //many seq=n
33
    const EVT_CANCELA = 110111; //only seq=1
34
    const EVT_CANCELASUBSTITUICAO = 110112;
35
    const EVT_EPEC = 110140; //only seq=1
36
    const EVT_ATORINTERESSADO = 110150;
37
38
    /**
39
     * Request authorization to issue NFe in batch with one or more documents
40
     * @param array $aXml array of nfe's xml
41
     * @param string $idLote lote number
42
     * @param int $indSinc flag to use synchronous communication
43
     * @param bool $compactar flag to compress data with gzip
44
     * @param array $xmls array with xmls substitutes if contigency is on
45
     * @return string soap response xml
46
     * @throws InvalidArgumentException
47
     */
48
    public function sefazEnviaLote(
49
        $aXml,
50
        $idLote = '',
51
        $indSinc = 0,
52
        $compactar = false,
53
        &$xmls = []
54
    ) {
55
        if (!is_array($aXml)) {
56
            throw new InvalidArgumentException('Envia Lote: XMLs de NF-e deve ser um array!');
57
        }
58
        if ($indSinc == 1 && count($aXml) > 1) {
59
            throw new InvalidArgumentException('Envio sincrono deve ser usado para enviar '
60
                . 'uma UNICA nota por vez. Você está tentando enviar varias.');
61
        }
62
        $servico = 'NfeAutorizacao';
63
        $this->checkContingencyForWebServices($servico);
64
        if ($this->contingency->type != '') {
65
            // Em modo de contingencia esses XMLs deverão ser modificados e re-assinados e retornados
66
            // no parametro $xmls para serem armazenados pelo aplicativo pois serão alterados.
67
            foreach ($aXml as $doc) {
68
                //corrigir o xml para o tipo de contigência setado
69
                $xmls[] = $this->correctNFeForContingencyMode($doc);
70
            }
71
            $aXml = $xmls;
72
        }
73
        $ax = [];
74
        $check = true;
75
        foreach ($aXml as $xml) {
76
            //verifica se o modelo do XML é o mesmo setado na classe
77
            $check = $check && $this->checkModelFromXml($xml);
78
            $ax[] = trim(preg_replace("/<\?xml.*?\?>/", "", $xml));
79
        }
80
        if (!$check) {
81
            $correct = $this->modelo == 55 ? 65 : 55;
82
            throw new InvalidArgumentException('Você passou um XML de modelo incorreto. '
83
                . "Use o método \$tools->model({$correct}), para selecionar o "
84
                . 'modelo correto a ser usado');
85
        }
86
        $sxml = trim(implode("", $ax));
87
        $this->servico($servico, $this->config->siglaUF, $this->tpAmb);
88
        $request = "<enviNFe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
89
            . "<idLote>$idLote</idLote>"
90
            . "<indSinc>$indSinc</indSinc>"
91
            . "$sxml"
92
            . "</enviNFe>";
93
        $this->isValid($this->urlVersion, $request, 'enviNFe');
94
        $this->lastRequest = $request;
95
        //montagem dos dados da mensagem SOAP
96
        $parameters = ['nfeDadosMsg' => $request];
97
        $body = "<nfeDadosMsg xmlns=\"$this->urlNamespace\">$request</nfeDadosMsg>";
98
        if ($compactar) {
99
            $gzdata = base64_encode(gzencode($request, 9, FORCE_GZIP));
100
            $parameters = ['nfeDadosMsgZip' => $gzdata];
101
            $body = "<nfeDadosMsgZip xmlns=\"$this->urlNamespace\">$gzdata</nfeDadosMsgZip>";
102
        }
103
        $this->lastResponse = $this->sendRequest($body, $parameters);
104
        return $this->lastResponse;
105
    }
106
107
    /**
108
     * Check status of Batch of NFe sent by receipt of this shipment
109
     * @param string $recibo
110
     * @param int $tpAmb
111
     * @return string
112
     * @throws InvalidArgumentException
113
     */
114 1
    public function sefazConsultaRecibo($recibo, $tpAmb = null)
115
    {
116 1
        if (empty($recibo)) {
117 1
            throw new InvalidArgumentException('Consulta Recibo: numero do recibo vazio!');
118
        }
119
        if (empty($tpAmb)) {
120
            $tpAmb = $this->tpAmb;
121
        }
122
        //carrega serviço
123
        $servico = 'NfeRetAutorizacao';
124
        $this->checkContingencyForWebServices($servico);
125
        $this->servico($servico, $this->config->siglaUF, $tpAmb);
126
        if ($this->urlService == '') {
127
            $msg = "A consulta de NFe nao esta disponivel na SEFAZ {$this->config->siglaUF}!";
128
            throw new RuntimeException($msg);
129
        }
130
        $request = "<consReciNFe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
131
            . "<tpAmb>$tpAmb</tpAmb>"
132
            . "<nRec>$recibo</nRec>"
133
            . "</consReciNFe>";
134
        $this->isValid($this->urlVersion, $request, 'consReciNFe');
135
        $this->lastRequest = $request;
136
        $parameters = ['nfeDadosMsg' => $request];
137
        $body = "<nfeDadosMsg xmlns=\"$this->urlNamespace\">$request</nfeDadosMsg>";
138
        $this->lastResponse = $this->sendRequest($body, $parameters);
139
        return $this->lastResponse;
140
    }
141
142
    /**
143
     * Check the NFe status for the 44-digit key and retrieve the protocol
144
     * @param string $chave
145
     * @param int $tpAmb
146
     * @return string
147
     * @throws InvalidArgumentException
148
     */
149 3
    public function sefazConsultaChave($chave, $tpAmb = null)
150
    {
151 3
        if (empty($chave)) {
152 1
            throw new InvalidArgumentException('Consulta chave: a chave esta vazia!');
153
        }
154 2
        if (strlen($chave) != 44 || !is_numeric($chave)) {
155 2
            throw new InvalidArgumentException("Consulta chave: chave \"$chave\" invalida!");
156
        }
157
        $uf = UFList::getUFByCode(substr($chave, 0, 2));
158
        if (empty($tpAmb)) {
159
            $tpAmb = $this->tpAmb;
160
        }
161
        //carrega serviço
162
        $servico = 'NfeConsultaProtocolo';
163
        $this->checkContingencyForWebServices($servico);
164
        $this->servico($servico, $uf, $tpAmb);
165
        $request = "<consSitNFe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
166
            . "<tpAmb>$tpAmb</tpAmb>"
167
            . "<xServ>CONSULTAR</xServ>"
168
            . "<chNFe>$chave</chNFe>"
169
            . "</consSitNFe>";
170
        $this->isValid($this->urlVersion, $request, 'consSitNFe');
171
        $this->lastRequest = $request;
172
        $parameters = ['nfeDadosMsg' => $request];
173
        $body = "<nfeDadosMsg xmlns=\"$this->urlNamespace\">$request</nfeDadosMsg>";
174
        $this->lastResponse = $this->sendRequest($body, $parameters);
175
        return $this->lastResponse;
176
    }
177
178
    /**
179
     * Request to disable one or an NFe sequence of a given series
180
     * @param int $nSerie
181
     * @param int $nIni
182
     * @param int $nFin
183
     * @param string $xJust
184
     * @param int $tpAmb
185
     * @param string $ano
186
     * @return string
187
     * @throws InvalidArgumentException
188
     */
189
    public function sefazInutiliza($nSerie, $nIni, $nFin, $xJust, $tpAmb = null, $ano = null)
190
    {
191
        if (empty($nIni) || empty($nFin) || empty($xJust)) {
192
            throw new InvalidArgumentException('Inutilizacao: parametros incompletos!');
193
        }
194
        if (empty($tpAmb)) {
195
            $tpAmb = $this->tpAmb;
196
        }
197
        $xJust = Strings::replaceUnacceptableCharacters($xJust);
198
        $servico = 'NfeInutilizacao';
199
        $this->checkContingencyForWebServices($servico);
200
        //carrega serviço
201
        $this->servico($servico, $this->config->siglaUF, $tpAmb);
202
        $cnpj = $this->config->cnpj;
203
        $strAno = $ano;
204
        if (empty($ano)) {
205
            $strAno = (string) date('y');
206
        }
207
        $strSerie = str_pad($nSerie, 3, '0', STR_PAD_LEFT);
208
        $strInicio = str_pad($nIni, 9, '0', STR_PAD_LEFT);
209
        $strFinal = str_pad($nFin, 9, '0', STR_PAD_LEFT);
210
        $idInut = "ID"
211
            . $this->urlcUF
212
            . $strAno
213
            . $cnpj
214
            . $this->modelo
215
            . $strSerie
216
            . $strInicio
217
            . $strFinal;
218
        //limpa os caracteres indesejados da justificativa
219
        $xJust = Strings::replaceUnacceptableCharacters($xJust);
220
        //montagem do corpo da mensagem
221
        $msg = "<inutNFe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">" .
222
            "<infInut Id=\"$idInut\">" .
223
            "<tpAmb>$tpAmb</tpAmb>" .
224
            "<xServ>INUTILIZAR</xServ>" .
225
            "<cUF>$this->urlcUF</cUF>" .
226
            "<ano>$strAno</ano>" .
227
            "<CNPJ>$cnpj</CNPJ>" .
228
            "<mod>$this->modelo</mod>" .
229
            "<serie>$nSerie</serie>" .
230
            "<nNFIni>$nIni</nNFIni>" .
231
            "<nNFFin>$nFin</nNFFin>" .
232
            "<xJust>$xJust</xJust>" .
233
            "</infInut></inutNFe>";
234
        //assina a solicitação
235
        $request = Signer::sign(
236
            $this->certificate,
237
            $msg,
238
            'infInut',
239
            'Id',
240
            $this->algorithm,
241
            $this->canonical
242
        );
243
        $request = Strings::clearXmlString($request, true);
244
        $this->isValid($this->urlVersion, $request, 'inutNFe');
245
        $this->lastRequest = $request;
246
        $parameters = ['nfeDadosMsg' => $request];
247
        $body = "<nfeDadosMsg xmlns=\"$this->urlNamespace\">$request</nfeDadosMsg>";
248
        $this->lastResponse = $this->sendRequest($body, $parameters);
249
        return $this->lastResponse;
250
    }
251
252
    /**
253
     * Search for the registration data of an NFe issuer,
254
     * if in contingency mode this service will cause a
255
     * Exception and remember not all Sefaz have this service available,
256
     * so it will not work in some cases.
257
     * @param string $uf federation unit (abbreviation)
258
     * @param string $cnpj CNPJ number (optional)
259
     * @param string $iest IE number (optional)
260
     * @param string $cpf CPF number (optional)
261
     * @return string xml soap response
262
     * @throws InvalidArgumentException
263
     */
264
    public function sefazCadastro($uf, $cnpj = '', $iest = '', $cpf = '')
265
    {
266
        $filter = '';
267
        if (!empty($cnpj)) {
268
            $filter = "<CNPJ>$cnpj</CNPJ>";
269
        } elseif (!empty($iest)) {
270
            $filter = "<IE>$iest</IE>";
271
        } elseif (!empty($cpf)) {
272
            $filter = "<CPF>$cpf</CPF>";
273
        }
274
        if (empty($uf) || empty($filter)) {
275
            throw new InvalidArgumentException('Sigla UF esta vazia ou CNPJ+IE+CPF vazios!');
276
        }
277
        //carrega serviço
278
        $servico = 'NfeConsultaCadastro';
279
        $this->checkContingencyForWebServices($servico);
280
        $this->servico($servico, $uf, $this->tpAmb, true);
281
        $request = "<ConsCad xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
282
            . "<infCons>"
283
            . "<xServ>CONS-CAD</xServ>"
284
            . "<UF>$uf</UF>"
285
            . "$filter"
286
            . "</infCons>"
287
            . "</ConsCad>";
288
        if (strtoupper($uf) == 'MT') {
289
            $request = "<nfeDadosMsg>$request</nfeDadosMsg>" ;
290
        }
291
        $this->isValid($this->urlVersion, $request, 'consCad');
292
        $this->lastRequest = $request;
293
        $parameters = ['nfeDadosMsg' => $request];
294
        if ($this->urlVersion === '2.00') {
295
            $this->objHeader = new \SOAPHeader(
296
                $this->urlNamespace,
297
                'nfeCabecMsg',
298
                ['cUF' => $this->urlcUF, 'versaoDados' => $this->urlVersion]
299
            );
300
        }
301
        $body = "<nfeDadosMsg xmlns=\"$this->urlNamespace\">$request</nfeDadosMsg>";
302
        $this->lastResponse = $this->sendRequest($body, $parameters);
303
        return $this->lastResponse;
304
    }
305
306
    /**
307
     * Check services status SEFAZ/SVC
308
     * If $uf is empty use normal check with contingency
309
     * If $uf is NOT empty ignore contingency mode
310
     * @param string $uf  initials of federation unit
311
     * @param int $tpAmb
312
     * @return string xml soap response
313
     */
314
    public function sefazStatus($uf = '', $tpAmb = null)
315
    {
316
        if (empty($tpAmb)) {
317
            $tpAmb = $this->tpAmb;
318
        }
319
        $ignoreContingency = true;
320
        if (empty($uf)) {
321
            $uf = $this->config->siglaUF;
322
            $ignoreContingency = false;
323
        }
324
        $servico = 'NfeStatusServico';
325
        $this->checkContingencyForWebServices($servico);
326
        $this->servico($servico, $uf, $tpAmb, $ignoreContingency);
327
        $request = "<consStatServ xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
328
            . "<tpAmb>$tpAmb</tpAmb>"
329
            . "<cUF>$this->urlcUF</cUF>"
330
            . "<xServ>STATUS</xServ>"
331
            . "</consStatServ>";
332
        $this->isValid($this->urlVersion, $request, 'consStatServ');
333
        $this->lastRequest = $request;
334
        $parameters = ['nfeDadosMsg' => $request];
335
        $body = "<nfeDadosMsg xmlns=\"$this->urlNamespace\">$request</nfeDadosMsg>";
336
        $this->lastResponse = $this->sendRequest($body, $parameters);
337
        return $this->lastResponse;
338
    }
339
340
    /**
341
     * Service for the distribution of summary information and
342
     * electronic tax documents of interest to an actor.
343
     * @param integer $ultNSU  last NSU number recived
344
     * @param integer $numNSU  NSU number you wish to consult
345
     * @param string $fonte data source 'AN' and for some cases it may be 'RS'
346
     * @return string
347
     */
348
    public function sefazDistDFe($ultNSU = 0, $numNSU = 0, $fonte = 'AN')
349
    {
350
        //carrega serviço
351
        $servico = 'NfeDistribuicaoDFe';
352
        $this->checkContingencyForWebServices($servico);
353
        $this->servico($servico, $fonte, $this->tpAmb, true);
354
        $cUF = UFList::getCodeByUF($this->config->siglaUF);
355
        $cnpj = $this->config->cnpj;
356
        $ultNSU = str_pad($ultNSU, 15, '0', STR_PAD_LEFT);
357
        $tagNSU = "<distNSU><ultNSU>$ultNSU</ultNSU></distNSU>";
358
        if ($numNSU != 0) {
359
            $numNSU = str_pad($numNSU, 15, '0', STR_PAD_LEFT);
360
            $tagNSU = "<consNSU><NSU>$numNSU</NSU></consNSU>";
361
        }
362
        //monta a consulta
363
        $consulta = "<distDFeInt xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
364
            . "<tpAmb>".$this->tpAmb."</tpAmb>"
365
            . "<cUFAutor>$cUF</cUFAutor>";
366
        if ($this->typePerson === 'J') {
367
            $consulta .= "<CNPJ>$cnpj</CNPJ>";
368
        } else {
369
            $consulta .= "<CPF>$cnpj</CPF>";
370
        }
371
        $consulta .= "$tagNSU"
372
            . "</distDFeInt>";
373
        //valida o xml da requisição
374
        $this->isValid($this->urlVersion, $consulta, 'distDFeInt');
375
        $this->lastRequest = $consulta;
376
        //montagem dos dados da mensagem SOAP
377
        $request = "<nfeDadosMsg xmlns=\"$this->urlNamespace\">$consulta</nfeDadosMsg>";
378
        $parameters = ['nfeDistDFeInteresse' => $request];
379
        $body = "<nfeDistDFeInteresse xmlns=\"$this->urlNamespace\">"
380
            . $request
381
            . "</nfeDistDFeInteresse>";
382
        //este webservice não requer cabeçalho
383
        $this->objHeader = null;
384
        $this->lastResponse = $this->sendRequest($body, $parameters);
385
        return $this->lastResponse;
386
    }
387
388
    /**
389
     * Request authorization for Letter of Correction
390
     * @param string $chave
391
     * @param string $xCorrecao
392
     * @param int $nSeqEvento
393
     * @return string
394
     * @throws InvalidArgumentException
395
     */
396
    public function sefazCCe($chave, $xCorrecao, $nSeqEvento = 1)
397
    {
398
        if (empty($chave) || empty($xCorrecao)) {
399
            throw new InvalidArgumentException('CC-e: chave ou motivo da correcao vazio!');
400
        }
401
        $uf = $this->validKeyByUF($chave);
402
        $xCorrecao = Strings::replaceUnacceptableCharacters(substr(trim($xCorrecao), 0, 1000));
403
        $xCondUso = 'A Carta de Correcao e disciplinada pelo paragrafo '
404
            . '1o-A do art. 7o do Convenio S/N, de 15 de dezembro de 1970 '
405
            . 'e pode ser utilizada para regularizacao de erro ocorrido '
406
            . 'na emissao de documento fiscal, desde que o erro nao esteja '
407
            . 'relacionado com: I - as variaveis que determinam o valor '
408
            . 'do imposto tais como: base de calculo, aliquota, '
409
            . 'diferenca de preco, quantidade, valor da operacao ou da '
410
            . 'prestacao; II - a correcao de dados cadastrais que implique '
411
            . 'mudanca do remetente ou do destinatario; III - a data de '
412
            . 'emissao ou de saida.';
413
        $tagAdic = "<xCorrecao>"
414
            . $xCorrecao
415
            . "</xCorrecao><xCondUso>$xCondUso</xCondUso>";
416
        return $this->sefazEvento($uf, $chave, self::EVT_CCE, $nSeqEvento, $tagAdic);
417
    }
418
    
419
    /**
420
     * Evento do Ator Interessado
421
     * NOTA: NT2020.007
422
     * @param string $chave
423
     * @param int $tpAutor
424
     * @param string $verAplic
425
     * @param int $nSeqEvento
426
     * @param array $interessados
427
     * @return string
428
     */
429
    public function sefazAtorInteressado(
430
        $chave,
431
        $tpAutor,
432
        $verAplic,
433
        $nSeqEvento = 1,
434
        $interessados = []
435
    ) {
436
        $xCondUso = 'O emitente ou destinatário da NF-e, declara que permite o '
437
            . 'transportador declarado no campo CNPJ/CPF deste evento a '
438
            . 'autorizar os transportadores subcontratados ou redespachados '
439
            . 'a terem acesso ao download da NFe';
440
        $tagAdic = "<cOrgaoAutor>{$this->urlcUF}</cOrgaoAutor>"
441
            . "<tpAutor>{$tpAutor}</tpAutor>"
442
            . "<verAplic>{$verAplic}</verAplic>";
443
        foreach ($interessados as $aut) {
444
            $obj = (object) $aut;
445
            $tagAdic .= "<autXML>";
446
            $tagAdic .=  !empty($obj->CNPJ)
447
                ? "<CNPJ>{$obj->CNPJ}</CNPJ>"
448
                : "<CPF>{$obj->CPF}</CPF>";
449
            $tagAdic .= "<tpAutorizacao>{$obj->tpAutorizacao}</tpAutorizacao>"
450
                . "</autXML>";
451
        }
452
        $tagAdic .= "<xCondUso>$xCondUso</xCondUso>";
453
        return $this->sefazEvento($uf, $chave, self::EVT_ATORINTERESSADO, $nSeqEvento, $tagAdic);
0 ignored issues
show
Bug introduced by
The variable $uf does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
454
    }
455
456
    /**
457
     * Request extension of the term of return of products of an NF-e of
458
     * consignment for industrialization to order with suspension of ICMS
459
     * in interstate operations
460
     * @param  string  $chNFe
461
     * @param  string  $nProt
462
     * @param  integer $tipo 1-primerio prazo, 2-segundo prazo
463
     * @param  array   $itens
464
     * @param  integer $nSeqEvento
465
     * @return string
466
     */
467
    public function sefazEPP(
468
        $chNFe,
469
        $nProt,
470
        $itens = array(),
471
        $tipo = 1,
472
        $nSeqEvento = 1
473
    ) {
474
        $uf = UFList::getUFByCode(substr($chNFe, 0, 2));
475
        $tpEvento = 111500;
476
        if ($tipo == 2) {
477
            $tpEvento = 111501;
478
        }
479
        $tagAdic = "<nProt>$nProt</nProt>";
480
        foreach ($itens as $item) {
481
            $tagAdic .= "<itemPedido numItem=\""
482
                . $item[0]
483
                . "\"><qtdeItem>"
484
                . $item[1]
485
                ."</qtdeItem></itemPedido>";
486
        }
487
        return $this->sefazEvento(
488
            $uf,
489
            $chNFe,
490
            $tpEvento,
491
            $nSeqEvento,
492
            $tagAdic
493
        );
494
    }
495
496
    /**
497
     * Request the cancellation of the request for an extension of the term
498
     * of return of products of an NF-e of consignment for industrialization
499
     * by order with suspension of ICMS in interstate operations
500
     * @param string $chave
501
     * @param string $nProt
502
     * @param integer $nSeqEvento
503
     * @return string
504
     * @throws InvalidArgumentException
505
     */
506
    public function sefazECPP($chave, $nProt, $nSeqEvento = 1)
507
    {
508
        if (empty($chave) || empty($nProt)) {
509
            throw new InvalidArgumentException('A chave ou o numero do protocolo estao vazios!');
510
        }
511
        $uf = UFList::getUFByCode(substr($chave, 0, 2));
512
        $tpEvento = 111502;
513
        $origEvent = 111500;
514
        if ($nSeqEvento == 2) {
515
            $tpEvento = 111503;
516
            $origEvent = 111501;
517
        }
518
        $sSeqEvento = str_pad($nSeqEvento, 2, "0", STR_PAD_LEFT);
519
        $idPedidoCancelado = "ID$origEvent$chave$sSeqEvento";
520
        $tagAdic = "<idPedidoCancelado>"
521
                . "$idPedidoCancelado"
522
                . "</idPedidoCancelado>"
523
                . "<nProt>$nProt</nProt>";
524
        return $this->sefazEvento($uf, $chave, $tpEvento, $nSeqEvento, $tagAdic);
525
    }
526
527
    /**
528
     * Requires nfe cancellation
529
     * @param  string $chave key of NFe
530
     * @param  string $xJust justificative 255 characters max
531
     * @param  string $nProt protocol number
532
     * @return string
533
     * @throws InvalidArgumentException
534
     */
535
    public function sefazCancela($chave, $xJust, $nProt)
536
    {
537
        if (empty($chave) || empty($xJust) || empty($nProt)) {
538
            throw new InvalidArgumentException('Cancelamento: chave, just ou numprot vazio!');
539
        }
540
        $uf = $this->validKeyByUF($chave);
541
        $xJust = Strings::replaceUnacceptableCharacters(substr(trim($xJust), 0, 255));
542
        $nSeqEvento = 1;
543
        $tagAdic = "<nProt>$nProt</nProt><xJust>$xJust</xJust>";
544
        return $this->sefazEvento($uf, $chave, self::EVT_CANCELA, $nSeqEvento, $tagAdic);
545
    }
546
547
    /**
548
     * Requires nfe cancellation by substitution
549
     * @param  string $chave key of NFe
550
     * @param  string $xJust justificative 255 characters max
551
     * @param  string $nProt protocol number
552
     * @param  string $chNFeRef key of New NFe
553
     * @param  string $verAplic version of applicative
554
     * @return string
555
     * @throws InvalidArgumentException
556
     */
557
    public function sefazCancelaPorSubstituicao($chave, $xJust, $nProt, $chNFeRef, $verAplic)
558
    {
559
        if ($this->modelo != 65) {
560
            throw new InvalidArgumentException(
561
                'Cancelamento pro Substituição deve ser usado apenas para '
562
                . 'operações com modelo 65 NFCe'
563
            );
564
        }
565
        if (empty($chave) || empty($xJust) || empty($nProt)
566
            || empty($chNFeRef) || empty($verAplic)) {
567
            throw new InvalidArgumentException(
568
                'CancelamentoPorSubs: chave da NFCe cancelada, justificativa, '
569
                . 'protocolo, chave da NFCe substituta, ou versão do aplicativo '
570
                . 'emissor não podem ser vazios!'
571
            );
572
        }
573
        $uf = $this->validKeyByUF($chave);
574
        $xJust = Strings::replaceUnacceptableCharacters(substr(trim($xJust), 0, 255));
575
        $nSeqEvento = 1;
576
        $cOrgao = substr($chave, 0, 2);
577
        $tagAdic = "<cOrgaoAutor>$cOrgao</cOrgaoAutor>"
578
            . "<tpAutor>1</tpAutor>"
579
            . "<verAplic>$verAplic</verAplic>"
580
            . "<nProt>$nProt</nProt>"
581
            . "<xJust>$xJust</xJust>"
582
            . "<chNFeRef>$chNFeRef</chNFeRef>";
583
        return $this->sefazEvento($uf, $chave, self::EVT_CANCELASUBSTITUICAO, $nSeqEvento, $tagAdic);
584
    }
585
586
    /**
587
     * Request the registration of the manifestation of recipient
588
     * @param string $chave
589
     * @param int $tpEvento
590
     * @param string $xJust Justification for not carrying out the operation
591
     * @param int $nSeqEvento
592
     * @return string
593
     * @throws InvalidArgumentException
594
     */
595
    public function sefazManifesta($chave, $tpEvento, $xJust = '', $nSeqEvento = 1)
596
    {
597
        if (empty($chave) || empty($tpEvento)) {
598
            throw new InvalidArgumentException('Manifestacao: chave ou tipo de evento vazio!');
599
        }
600
        $tagAdic = '';
601
        if ($tpEvento == self::EVT_NAO_REALIZADA) {
602
            $xJust = Strings::replaceUnacceptableCharacters(substr(trim($xJust), 0, 255));
603
            $tagAdic = "<xJust>$xJust</xJust>";
604
        }
605
        return $this->sefazEvento('AN', $chave, $tpEvento, $nSeqEvento, $tagAdic);
606
    }
607
608
    /**
609
     * Request the registration of the manifestation of recipient in batch
610
     * @param \stdClass $std
611
     * @return string
612
     * @throws InvalidArgumentException
613
     * @throws RuntimeException
614
     */
615
    public function sefazManifestaLote(\stdClass $std)
616
    {
617
        $allowed = [
618
            self::EVT_CONFIRMACAO,
619
            self::EVT_CIENCIA,
620
            self::EVT_DESCONHECIMENTO,
621
            self::EVT_NAO_REALIZADA,
622
        ];
623
        if (empty($std) || empty($std->evento)) {
624
            throw new InvalidArgumentException('Manifestacao: parametro "std" ou evento estao vazios!');
625
        }
626
        if (count($std->evento) > 20) {
627
            throw new RuntimeException('Manifestacao: o lote de eventos esta limitado a 20!');
628
        }
629
        $evt = new \stdClass();
630
        $i = 0;
631
        foreach ($std->evento as $s) {
632
            if (!in_array($s->tpEvento, $allowed)) { // se o evento não estiver entre os permitidos ignore
633
                continue;
634
            }
635
            $tagAdic = '';
636
            if ($s->tpEvento == self::EVT_NAO_REALIZADA) {
637
                $xJust = Strings::replaceUnacceptableCharacters(substr(trim($s->xJust), 0, 255));
638
                $tagAdic = "<xJust>$xJust</xJust>";
639
            }
640
            $evt->evento[$i] = new \stdClass();
641
            $evt->evento[$i]->chave = $s->chNFe;
642
            $evt->evento[$i]->tpEvento = $s->tpEvento;
643
            $evt->evento[$i]->nSeqEvento = $s->nSeqEvento;
644
            $evt->evento[$i]->tagAdic = $tagAdic;
645
            $i++;
646
        }
647
        return $this->sefazEventoLote('AN', $evt);
648
    }
649
650
    /**
651
     * Send event to SEFAZ in batch
652
     * @param string $uf
653
     * @param \stdClass $std
654
     * @return string
655
     * @throws RuntimeException
656
     * @throws InvalidArgumentException
657
     */
658
    public function sefazEventoLote($uf, \stdClass $std)
659
    {
660
        if (empty($uf) || empty($std)) {
661
            throw new InvalidArgumentException('Evento Lote: UF ou parametro "std" vazio!');
662
        }
663
        if (count($std->evento) > 20) {
664
            throw new RuntimeException('Evento Lote: o lote de eventos esta limitado a 20!');
665
        }
666
        $servico = 'RecepcaoEvento';
667
        $this->checkContingencyForWebServices($servico);
668
        $this->servico($servico, $uf, $this->tpAmb, false);
669
        $batchRequest = '';
670
        foreach ($std->evento as $evt) {
671
            if ($evt->tpEvento == self::EVT_EPEC) {
672
                continue; //não é possivel enviar EPEC com outros eventos
673
            }
674
            $ev = $this->tpEv($evt->tpEvento);
675
            $descEvento = $ev->desc;
676
            $cnpj = $this->config->cnpj;
677
            $dt = new \DateTime('now', new \DateTimeZone($this->timezone));
678
            $dhEvento = $dt->format('Y-m-d\TH:i:sP');
679
            $sSeqEvento = str_pad($evt->nSeqEvento, 2, "0", STR_PAD_LEFT);
680
            $eventId = "ID".$evt->tpEvento.$evt->chave.$sSeqEvento;
681
            $cOrgao = UFList::getCodeByUF($uf);
682
            $request = "<evento xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
683
                . "<infEvento Id=\"$eventId\">"
684
                . "<cOrgao>$cOrgao</cOrgao>"
685
                . "<tpAmb>$this->tpAmb</tpAmb>";
686
            if ($this->typePerson === 'J') {
687
                $request .= "<CNPJ>$cnpj</CNPJ>";
688
            } else {
689
                $request .= "<CPF>$cnpj</CPF>";
690
            }
691
            $request .= "<chNFe>$evt->chave</chNFe>"
692
                . "<dhEvento>$dhEvento</dhEvento>"
693
                . "<tpEvento>$evt->tpEvento</tpEvento>"
694
                . "<nSeqEvento>$evt->nSeqEvento</nSeqEvento>"
695
                . "<verEvento>$this->urlVersion</verEvento>"
696
                . "<detEvento versao=\"$this->urlVersion\">"
697
                . "<descEvento>$descEvento</descEvento>"
698
                . "$evt->tagAdic"
699
                . "</detEvento>"
700
                . "</infEvento>"
701
                . "</evento>";
702
            //assinatura dos dados
703
            $request = Signer::sign(
704
                $this->certificate,
705
                $request,
706
                'infEvento',
707
                'Id',
708
                $this->algorithm,
709
                $this->canonical
710
            );
711
            $batchRequest .= Strings::clearXmlString($request, true);
712
        }
713
        $dt = new \DateTime('now', new \DateTimeZone($this->timezone));
714
        $lote = $dt->format('YmdHis') . rand(0, 9);
715
        $request = "<envEvento xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
716
            . "<idLote>$lote</idLote>"
717
            . $batchRequest
718
            . "</envEvento>";
719
        $this->isValid($this->urlVersion, $request, 'envEvento');
720
        $this->lastRequest = $request;
721
        $parameters = ['nfeDadosMsg' => $request];
722
        $body = "<nfeDadosMsg xmlns=\"$this->urlNamespace\">$request</nfeDadosMsg>";
723
        $this->lastResponse = $this->sendRequest($body, $parameters);
724
        return $this->lastResponse;
725
    }
726
727
    /**
728
     * Request authorization for issuance in contingency EPEC
729
     * @param  string $xml
730
     * @return string
731
     * @throws InvalidArgumentException
732
     * @throws RuntimeException
733
     */
734
    public function sefazEPEC(&$xml)
735
    {
736
        if (empty($xml)) {
737
            throw new InvalidArgumentException('EPEC: parametro xml esta vazio!');
738
        }
739
        $nSeqEvento = 1;
740
        if ($this->contingency->type !== 'EPEC') {
741
            throw new RuntimeException('A contingencia EPEC deve estar ativada!');
742
        }
743
        $xml = $this->correctNFeForContingencyMode($xml);
744
        $dom = new \DOMDocument('1.0', 'UTF-8');
745
        $dom->preserveWhiteSpace = false;
746
        $dom->formatOutput = false;
747
        $dom->loadXML($xml);
748
        $infNFe = $dom->getElementsByTagName('infNFe')->item(0);
749
        $emit = $dom->getElementsByTagName('emit')->item(0);
750
        $dest = $dom->getElementsByTagName('dest')->item(0);
751
        $cOrgaoAutor = UFList::getCodeByUF($this->config->siglaUF);
752
        $chNFe = substr($infNFe->getAttribute('Id'), 3, 44);
753
        // EPEC
754
        $dhEmi = $dom->getElementsByTagName('dhEmi')->item(0)->nodeValue;
755
        $tpNF = $dom->getElementsByTagName('tpNF')->item(0)->nodeValue;
756
        $emitIE = $emit->getElementsByTagName('IE')->item(0)->nodeValue;
757
        $destUF = $dest->getElementsByTagName('UF')->item(0)->nodeValue;
758
        $total = $dom->getElementsByTagName('total')->item(0);
759
        $vNF = $total->getElementsByTagName('vNF')->item(0)->nodeValue;
760
        $vICMS = $total->getElementsByTagName('vICMS')->item(0)->nodeValue;
761
        $vST = $total->getElementsByTagName('vST')->item(0)->nodeValue;
762
        $dID = !empty($dest->getElementsByTagName('CNPJ')->item(0)) ?
763
                $dest->getElementsByTagName('CNPJ')->item(0)->nodeValue : null;
764
        if (!empty($dID)) {
765
            $destID = "<CNPJ>$dID</CNPJ>";
766
        } else {
767
            $dID = $dest->getElementsByTagName('CPF')->item(0)->nodeValue;
768
            if (!empty($dID)) {
769
                $destID = "<CPF>$dID</CPF>";
770
            } else {
771
                $dID = $dest->getElementsByTagName('idEstrangeiro')
772
                    ->item(0)
773
                    ->nodeValue;
774
                $destID = "<idEstrangeiro>$dID</idEstrangeiro>";
775
            }
776
        }
777
        $dIE = !empty($dest->getElementsByTagName('IE')->item(0)->nodeValue) ?
778
                $dest->getElementsByTagName('IE')->item(0)->nodeValue : '';
779
        $destIE = '';
780
        if (!empty($dIE)) {
781
            $destIE = "<IE>$dIE</IE>";
782
        }
783
        $tagAdic = "<cOrgaoAutor>$cOrgaoAutor</cOrgaoAutor>"
784
            . "<tpAutor>1</tpAutor>"
785
            . "<verAplic>$this->verAplic</verAplic>"
786
            . "<dhEmi>$dhEmi</dhEmi>"
787
            . "<tpNF>$tpNF</tpNF>"
788
            . "<IE>$emitIE</IE>"
789
            . "<dest>"
790
            . "<UF>$destUF</UF>"
791
            . $destID
792
            . $destIE
793
            . "<vNF>$vNF</vNF>"
794
            . "<vICMS>$vICMS</vICMS>"
795
            . "<vST>$vST</vST>"
796
            . "</dest>";
797
798
        return $this->sefazEvento('AN', $chNFe, self::EVT_EPEC, $nSeqEvento, $tagAdic);
799
    }
800
801
    /**
802
     * Send event to SEFAZ
803
     * @param string $uf
804
     * @param string $chave
805
     * @param int $tpEvento
806
     * @param int $nSeqEvento
807
     * @param string $tagAdic
808
     * @return string
809
     */
810
    public function sefazEvento(
811
        $uf,
812
        $chave,
813
        $tpEvento,
814
        $nSeqEvento = 1,
815
        $tagAdic = ''
816
    ) {
817
        $ignore = $tpEvento == self::EVT_EPEC;
818
        $servico = 'RecepcaoEvento';
819
        $this->checkContingencyForWebServices($servico);
820
        $this->servico($servico, $uf, $this->tpAmb, $ignore);
821
        $ev = $this->tpEv($tpEvento);
822
        $descEvento = $ev->desc;
823
        $cnpj = isset($this->config->cnpj) ? $this->config->cnpj : '';
824
        $dt = new \DateTime(date("Y-m-d H:i:sP"), new \DateTimeZone($this->timezone));
825
        $dhEvento = $dt->format('Y-m-d\TH:i:sP');
826
        $sSeqEvento = str_pad($nSeqEvento, 2, "0", STR_PAD_LEFT);
827
        $eventId = "ID".$tpEvento.$chave.$sSeqEvento;
828
        $cOrgao = UFList::getCodeByUF($uf);
829
        $request = "<evento xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
830
            . "<infEvento Id=\"$eventId\">"
831
            . "<cOrgao>$cOrgao</cOrgao>"
832
            . "<tpAmb>$this->tpAmb</tpAmb>";
833
        if ($this->typePerson === 'J') {
834
            $request .= "<CNPJ>$cnpj</CNPJ>";
835
        } else {
836
            $request .= "<CPF>$cnpj</CPF>";
837
        }
838
        $request .= "<chNFe>$chave</chNFe>"
839
            . "<dhEvento>$dhEvento</dhEvento>"
840
            . "<tpEvento>$tpEvento</tpEvento>"
841
            . "<nSeqEvento>$nSeqEvento</nSeqEvento>"
842
            . "<verEvento>$this->urlVersion</verEvento>"
843
            . "<detEvento versao=\"$this->urlVersion\">"
844
            . "<descEvento>$descEvento</descEvento>"
845
            . "$tagAdic"
846
            . "</detEvento>"
847
            . "</infEvento>"
848
            . "</evento>";
849
        //assinatura dos dados
850
        $request = Signer::sign(
851
            $this->certificate,
852
            $request,
853
            'infEvento',
854
            'Id',
855
            $this->algorithm,
856
            $this->canonical
857
        );
858
        $request = Strings::clearXmlString($request, true);
859
        $lote = $dt->format('YmdHis').rand(0, 9);
860
        $request = "<envEvento xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
861
            . "<idLote>$lote</idLote>"
862
            . $request
863
            . "</envEvento>";
864
        $this->isValid($this->urlVersion, $request, 'envEvento');
865
        $this->lastRequest = $request;
866
        //return $request;
867
        $parameters = ['nfeDadosMsg' => $request];
868
        $body = "<nfeDadosMsg xmlns=\"$this->urlNamespace\">$request</nfeDadosMsg>";
869
        $this->lastResponse = $this->sendRequest($body, $parameters);
870
        return $this->lastResponse;
871
    }
872
873
    /**
874
     * Request the NFe download already manifested by its recipient, by the key
875
     * using new service in NfeDistribuicaoDFe
876
     * NOTA: NfeDownloadNF is deactivated
877
     * @param  string $chave
878
     * @return string
879
     * @throws InvalidArgumentException
880
     */
881
    public function sefazDownload($chave)
882
    {
883
        if (empty($chave)) {
884
            throw new InvalidArgumentException('Download: chave esta vazia!');
885
        }
886
        //carrega serviço
887
        $servico = 'NfeDistribuicaoDFe';
888
        $this->checkContingencyForWebServices($servico);
889
        $this->servico($servico, 'AN', $this->tpAmb, true);
890
        $cUF = UFList::getCodeByUF($this->config->siglaUF);
891
        $tagChave = "<consChNFe><chNFe>$chave</chNFe></consChNFe>";
892
        $cnpj = $this->config->cnpj;
893
        //monta a consulta
894
        $request = "<distDFeInt xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">"
895
            . "<tpAmb>".$this->tpAmb."</tpAmb>"
896
            . "<cUFAutor>$cUF</cUFAutor>";
897
        if ($this->typePerson === 'J') {
898
            $request .= "<CNPJ>$cnpj</CNPJ>";
899
        } else {
900
            $request .= "<CPF>$cnpj</CPF>";
901
        }
902
        $request .= "$tagChave"
903
            . "</distDFeInt>";
904
        //valida o xml da requisição
905
        $this->isValid($this->urlVersion, $request, 'distDFeInt');
906
        $this->lastRequest = $request;
907
        //montagem dos dados da mensagem SOAP
908
        $request = "<nfeDadosMsg xmlns=\"$this->urlNamespace\">$request</nfeDadosMsg>";
909
        $parameters = ['nfeDistDFeInteresse' => $request];
910
        $body = "<nfeDistDFeInteresse xmlns=\"$this->urlNamespace\">"
911
            . $request
912
            . "</nfeDistDFeInteresse>";
913
        //este webservice não requer cabeçalho
914
        $this->objHeader = null;
915
        $this->lastResponse = $this->sendRequest($body, $parameters);
916
        return $this->lastResponse;
917
    }
918
919
    /**
920
     * Maintenance of the Taxpayer Security Code - CSC (Old Token)
921
     * @param int $indOp Identificador do tipo de operação:
922
     *                   1 - Consulta CSC Ativos;
923
     *                   2 - Solicita novo CSC;
924
     *                   3 - Revoga CSC Ativo
925
     * @return string
926
     * @throws InvalidArgumentException
927
     * @throws RuntimeException
928
     */
929
    public function sefazCsc($indOp)
930
    {
931
        if (empty($indOp) || $indOp < 1 || $indOp > 3) {
932
            throw new InvalidArgumentException('CSC: identificador operacao invalido!');
933
        }
934
        if ($this->modelo != 65) {
935
            throw new RuntimeException('CSC: modelo diferente de 65!');
936
        }
937
        $raizCNPJ = substr($this->config->cnpj, 0, -6);
938
        //carrega serviço
939
        $servico = 'CscNFCe';
940
        $this->checkContingencyForWebServices($servico);
941
        $this->servico($servico, $this->config->siglaUF, $this->tpAmb);
942
        $request = "<admCscNFCe versao=\"$this->urlVersion\" xmlns=\"$this->urlPortal\">"
943
            . "<tpAmb>$this->tpAmb</tpAmb>"
944
            . "<indOp>$indOp</indOp>"
945
            . "<raizCNPJ>$raizCNPJ</raizCNPJ>"
946
            . "</admCscNFCe>";
947
        if ($indOp == 3) {
948
            $request = "<admCscNFCe versao=\"$this->urlVersion\" xmlns=\"$this->urlPortal\">"
949
            . "<tpAmb>$this->tpAmb</tpAmb>"
950
            . "<indOp>$indOp</indOp>"
951
            . "<raizCNPJ>$raizCNPJ</raizCNPJ>"
952
            . "<dadosCsc>"
953
            . "<idCsc>".$this->config->CSCid."</idCsc>"
954
            . "<codigoCsc>".$this->config->CSC."</codigoCsc>"
955
            . "</dadosCsc>"
956
            . "</admCscNFCe>";
957
        }
958
        //o xsd não está disponivel
959
        //$this->isValid($this->urlVersion, $request, 'cscNFCe');
960
        $this->lastRequest = $request;
961
        $parameters = ['nfeDadosMsg' => $request];
962
        $body = "<nfeDadosMsg xmlns=\"$this->urlNamespace\">$request</nfeDadosMsg>";
963
        $this->lastResponse = $this->sendRequest($body, $parameters);
964
        return $this->lastResponse;
965
    }
966
967
    /**
968
     * Checks the validity of an NFe, normally used for received NFe
969
     * @param string $nfe
970
     * @return bool
971
     * @throws InvalidArgumentException
972
     */
973
    public function sefazValidate($nfe)
974
    {
975
        if (empty($nfe)) {
976
            throw new InvalidArgumentException('Validacao NF-e: a string da NF-e esta vazia!');
977
        }
978
        //verifica a assinatura da NFe, exception caso de falha
979
        Signer::isSigned($nfe);
980
        $dom = new \DOMDocument('1.0', 'utf-8');
981
        $dom->formatOutput = false;
982
        $dom->preserveWhiteSpace = false;
983
        $dom->loadXML($nfe);
984
        //verifica a validade no webservice da SEFAZ
985
        $tpAmb = $dom->getElementsByTagName('tpAmb')->item(0)->nodeValue;
986
        $infNFe  = $dom->getElementsByTagName('infNFe')->item(0);
987
        $chNFe = preg_replace('/[^0-9]/', '', $infNFe->getAttribute("Id"));
988
        $protocol = $dom->getElementsByTagName('nProt')->item(0)->nodeValue;
989
        $digval = $dom->getElementsByTagName('DigestValue')->item(0)->nodeValue;
990
        //consulta a NFe
991
        $response = $this->sefazConsultaChave($chNFe, $tpAmb);
992
        $ret = new \DOMDocument('1.0', 'UTF-8');
993
        $ret->preserveWhiteSpace = false;
994
        $ret->formatOutput = false;
995
        $ret->loadXML($response);
996
        $retProt = $ret->getElementsByTagName('protNFe')->item(0);
997
        if (!isset($retProt)) {
998
            $xMotivo = $ret->getElementsByTagName('xMotivo')->item(0);
999
            if (isset($xMotivo)) {
1000
                throw new InvalidArgumentException('Validacao NF-e: ' . $xMotivo->nodeValue);
1001
            } else {
1002
                throw new InvalidArgumentException('O documento de resposta nao contem o node "protNFe".');
1003
            }
1004
        }
1005
        $infProt = $ret->getElementsByTagName('infProt')->item(0);
1006
        $dig = $infProt->getElementsByTagName("digVal")->item(0);
1007
        $digProt = '000';
1008
        if (isset($dig)) {
1009
            $digProt = $dig->nodeValue;
1010
        }
1011
        $chProt = $infProt->getElementsByTagName("chNFe")->item(0)->nodeValue;
1012
        $nProt = $infProt->getElementsByTagName("nProt")->item(0)->nodeValue;
1013
        if ($protocol == $nProt && $digval == $digProt && $chNFe == $chProt) {
1014
            return true;
1015
        }
1016
        return false;
1017
    }
1018
1019
    /**
1020
     * Returns alias and description event from event code.
1021
     * @param  int $tpEvento
1022
     * @return \stdClass
1023
     * @throws \RuntimeException
1024
     */
1025
    private function tpEv($tpEvento)
1026
    {
1027
        $std = new \stdClass();
1028
        $std->alias = '';
1029
        $std->desc = '';
1030
        switch ($tpEvento) {
1031
            case self::EVT_CCE:
1032
                $std->alias = 'CCe';
1033
                $std->desc = 'Carta de Correcao';
1034
                break;
1035
            case self::EVT_CANCELA:
1036
                $std->alias = 'CancNFe';
1037
                $std->desc = 'Cancelamento';
1038
                break;
1039
            case self::EVT_CANCELASUBSTITUICAO:
1040
                $std->alias = 'CancNFe';
1041
                $std->desc = 'Cancelamento por substituicao';
1042
                break;
1043
            case self::EVT_EPEC: // Emissão em contingência EPEC
1044
                $std->alias = 'EPEC';
1045
                $std->desc = 'EPEC';
1046
                break;
1047
            case 111500:
1048
            case 111501:
1049
                //EPP
1050
                //Pedido de prorrogação
1051
                $std->alias = 'EPP';
1052
                $std->desc = 'Pedido de Prorrogacao';
1053
                break;
1054
            case 111502:
1055
            case 111503:
1056
                //ECPP
1057
                //Cancelamento do Pedido de prorrogação
1058
                $std->alias = 'ECPP';
1059
                $std->desc = 'Cancelamento de Pedido de Prorrogacao';
1060
                break;
1061
            case self::EVT_CONFIRMACAO: // Manifestação Confirmacao da Operação
1062
                $std->alias = 'EvConfirma';
1063
                $std->desc = 'Confirmacao da Operacao';
1064
                break;
1065
            case self::EVT_CIENCIA: // Manifestação Ciencia da Operação
1066
                $std->alias = 'EvCiencia';
1067
                $std->desc = 'Ciencia da Operacao';
1068
                $std->tpAutor = 2;
1069
                break;
1070
            case self::EVT_DESCONHECIMENTO: // Manifestação Desconhecimento da Operação
1071
                $std->alias = 'EvDesconh';
1072
                $std->desc = 'Desconhecimento da Operacao';
1073
                break;
1074
            case self::EVT_NAO_REALIZADA: // Manifestação Operacao não Realizada
1075
                $std->alias = 'EvNaoRealizada';
1076
                $std->desc = 'Operacao nao Realizada';
1077
                break;
1078
            case self::EVT_ATORINTERESSADO: //ator interessado
1079
                $std->alias = 'EvAtorInteressado';
1080
                $std->desc = 'Ator interessado na NF-e';
1081
                break;
1082
            default:
1083
                $msg = "O código do tipo de evento informado não corresponde a "
1084
                . "nenhum evento estabelecido.";
1085
                throw new RuntimeException($msg);
1086
        }
1087
        return $std;
1088
    }
1089
}
1090