Test Failed
Push — master ( f8eb03...8feb3a )
by Francimar
06:03
created

Nota::setEmitente()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * MIT License
4
 *
5
 * Copyright (c) 2016 MZ Desenvolvimento de Sistemas LTDA
6
 *
7
 * @author Francimar Alves <[email protected]>
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
10
 * of this software and associated documentation files (the "Software"), to deal
11
 * in the Software without restriction, including without limitation the rights
12
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
 * copies of the Software, and to permit persons to whom the Software is
14
 * furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included in all
17
 * copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
 * SOFTWARE.
26
 *
27
 */
28
namespace NFe\Core;
29
30
use NFe\Common\Util;
31
use NFe\Common\Node;
32
use NFe\Task\Protocolo;
33
use NFe\Entity\Total;
34
use NFe\Entity\Imposto;
35
use NFe\Entity\Produto;
36
use NFe\Entity\Emitente;
37
use NFe\Entity\Pagamento;
38
use NFe\Entity\Transporte;
39
use NFe\Entity\Destinatario;
40
use NFe\Exception\ValidationException;
41
use FR3D\XmlDSig\Adapter\AdapterInterface;
42
use FR3D\XmlDSig\Adapter\XmlseclibsAdapter;
43
44
/**
45
 * Classe base para a formação da nota fiscal
46
 */
47
abstract class Nota implements Node
0 ignored issues
show
Complexity introduced by
This class has 1972 lines of code which exceeds the configured maximum of 1000.

Really long classes often contain too much logic and violate the single responsibility principle.

We suggest to take a look at the “Code” section for options on how to refactor this code.

Loading history...
Complexity introduced by
This class has 29 fields which exceeds the configured maximum of 15.

Too many fields generally indicate a class which does too much and does not follow the single responsibility principle.

We suggest taking a look at the “Code” section for further suggestions on how to fix this.

Loading history...
Complexity introduced by
This class has a complexity of 262 which exceeds the configured maximum of 50.

The class complexity is the sum of the complexity of all methods. A very high value is usually an indication that your class does not follow the single reponsibility principle and does more than one job.

Some resources for further reading:

You can also find more detailed suggestions for refactoring in the “Code” section of your repository.

Loading history...
Complexity introduced by
The class Nota has a coupling between objects value of 23. Consider to reduce the number of dependencies under 13.
Loading history...
Complexity introduced by
This class has 74 public methods and attributes which exceeds the configured maximum of 45.

The number of this metric differs depending on the chosen design (inheritance vs. composition). For inheritance, the number should generally be a bit lower.

A high number indicates a reusable class. It might also make the class harder to change without breaking other classes though.

Loading history...
48
{
49
50
    /**
51
     * Versão da nota fiscal
52
     */
53
    const VERSAO = '4.00';
54
55
    /**
56
     * Versão do aplicativo gerador da nota
57
     */
58
    const APP_VERSAO = '1.0';
59
60
    /**
61
     * Portal da nota fiscal
62
     */
63
    const PORTAL = 'http://www.portalfiscal.inf.br/nfe';
64
65
    /**
66
     * Código do modelo do Documento Fiscal. 55 = NF-e; 65 = NFC-e.
67
     */
68
    const MODELO_NFE = 'nfe';
69
    const MODELO_NFCE = 'nfce';
70
71
    /**
72
     * Tipo do Documento Fiscal (0 - entrada; 1 - saída)
73
     */
74
    const TIPO_ENTRADA = 'entrada';
75
    const TIPO_SAIDA = 'saida';
76
77
    /**
78
     * Identificador de Local de destino da operação
79
     * (1-Interna;2-Interestadual;3-Exterior)
80
     */
81
    const DESTINO_INTERNA = 'interna';
82
    const DESTINO_INTERESTADUAL = 'interestadual';
83
    const DESTINO_EXTERIOR = 'exterior';
84
85
    /**
86
     * Formato de impressão do DANFE (0-sem DANFE;1-DANFe Retrato; 2-DANFe
87
     * Paisagem;3-DANFe Simplificado;4-DANFe NFC-e;5-DANFe NFC-e em mensagem
88
     * eletrônica)
89
     */
90
    const FORMATO_NENHUMA = 'nenhuma';
91
    const FORMATO_RETRATO = 'retrato';
92
    const FORMATO_PAISAGEM = 'paisagem';
93
    const FORMATO_SIMPLIFICADO = 'simplificado';
94
    const FORMATO_CONSUMIDOR = 'consumidor';
95
    const FORMATO_MENSAGEM = 'mensagem';
96
97
    /**
98
     * Forma de emissão da NF-e
99
     */
100
    const EMISSAO_NORMAL = 'normal';
101
    const EMISSAO_CONTINGENCIA = 'contingencia';
102
103
    /**
104
     * Identificação do Ambiente: 1 - Produção, 2 - Homologação
105
     */
106
    const AMBIENTE_PRODUCAO = 'producao';
107
    const AMBIENTE_HOMOLOGACAO = 'homologacao';
108
109
    /**
110
     * Finalidade da emissão da NF-e: 1 - NFe normal, 2 - NFe complementar, 3 -
111
     * NFe de ajuste, 4 - Devolução/Retorno
112
     */
113
    const FINALIDADE_NORMAL = 'normal';
114
    const FINALIDADE_COMPLEMENTAR = 'complementar';
115
    const FINALIDADE_AJUSTE = 'ajuste';
116
    const FINALIDADE_RETORNO = 'retorno';
117
118
    /**
119
     * Indicador de presença do comprador no estabelecimento comercial no
120
     * momento da operação (0-Não se aplica ex.: Nota Fiscal complementar ou de
121
     * ajuste;1-Operação presencial;2-Não presencial, internet;3-Não
122
     * presencial, teleatendimento;4-NFC-e entrega em domicílio;5-Operação
123
     * presencial, fora do estabelecimento;9-Não presencial, outros)
124
     */
125
    const PRESENCA_NENHUM = 'nenhum';
126
    const PRESENCA_PRESENCIAL = 'presencial';
127
    const PRESENCA_INTERNET = 'internet';
128
    const PRESENCA_TELEATENDIMENTO = 'teleatendimento';
129
    const PRESENCA_ENTREGA = 'entrega';
130
    const PRESENCA_AMBULANTE = 'ambulante';
131
    const PRESENCA_OUTROS = 'outros';
132
133
    /**
134
     * Chave da nota fiscal
135
     */
136
    private $id;
137
    /**
138
     * Número do Documento Fiscal
139
     */
140
    private $numero;
141
    /**
142
     * Emitente da nota fiscal
143
     */
144
    private $emitente;
145
    /**
146
     * Destinatário que receberá os produtos
147
     */
148
    private $destinatario;
149
    /**
150
     * Produtos adicionados na nota
151
     */
152
    private $produtos;
153
    /**
154
     * Informações de trasnporte da mercadoria
155
     */
156
    private $transporte;
157
    /**
158
     * Pagamentos realizados
159
     */
160
    private $pagamentos;
161
    /**
162
     * Data e Hora da saída ou de entrada da mercadoria / produto
163
     */
164
    private $data_movimentacao;
165
    /**
166
     * Informar a data e hora de entrada em contingência
167
     */
168
    private $data_contingencia;
169
    /**
170
     * Informar a Justificativa da entrada em contingência
171
     */
172
    private $justificativa;
173
    /**
174
     * Código do modelo do Documento Fiscal. 55 = NF-e; 65 = NFC-e.
175
     */
176
    private $modelo;
177
    /**
178
     * Tipo do Documento Fiscal (0 - entrada; 1 - saída)
179
     */
180
    private $tipo;
181
    /**
182
     * Identificador de Local de destino da operação
183
     * (1-Interna;2-Interestadual;3-Exterior)
184
     */
185
    private $destino;
186
    /**
187
     * Descrição da Natureza da Operação
188
     */
189
    private $natureza;
190
    /**
191
     * Código numérico que compõe a Chave de Acesso. Número aleatório gerado
192
     * pelo emitente para cada NF-e.
193
     */
194
    private $codigo;
195
    /**
196
     * Data e Hora de emissão do Documento Fiscal
197
     */
198
    private $data_emissao;
199
    /**
200
     * Série do Documento Fiscal: série normal 0-889, Avulsa Fisco 890-899,
201
     * SCAN 900-999
202
     */
203
    private $serie;
204
    /**
205
     * Formato de impressão do DANFE (0-sem DANFE;1-DANFe Retrato; 2-DANFe
206
     * Paisagem;3-DANFe Simplificado;4-DANFe NFC-e;5-DANFe NFC-e em mensagem
207
     * eletrônica)
208
     */
209
    private $formato;
210
    /**
211
     * Forma de emissão da NF-e
212
     */
213
    private $emissao;
214
    /**
215
     * Digito Verificador da Chave de Acesso da NF-e
216
     */
217
    private $digito_verificador;
218
    /**
219
     * Identificação do Ambiente: 1 - Produção, 2 - Homologação
220
     */
221
    private $ambiente;
222
    /**
223
     * Finalidade da emissão da NF-e: 1 - NFe normal, 2 - NFe complementar, 3 -
224
     * NFe de ajuste, 4 - Devolução/Retorno
225
     */
226
    private $finalidade;
227
    /**
228
     * Indica operação com consumidor final (0-Não;1-Consumidor Final)
229
     */
230
    private $consumidor_final;
231
    /**
232
     * Indicador de presença do comprador no estabelecimento comercial no
233
     * momento da oepração (0-Não se aplica, ex.: Nota Fiscal complementar ou
234
     * de ajuste;1-Operação presencial;2-Não presencial, internet;3-Não
235
     * presencial, teleatendimento;4-NFC-e entrega em domicílio;9-Não
236
     * presencial, outros)
237
     */
238
    private $presenca;
239
    /**
240
     * Dados dos totais da NF-e
241
     */
242
    private $total;
243
    /**
244
     * Informações adicionais de interesse do Fisco
245
     */
246
    private $adicionais;
247
    /**
248
     * Campo de uso livre do contribuinte informar o nome do campo no atributo
249
     * xCampo e o conteúdo do campo no xTexto
250
     */
251
    private $observacoes;
252
    /**
253
     * Campo de uso exclusivo do Fisco informar o nome do campo no atributo
254
     * xCampo e o conteúdo do campo no xTexto
255
     */
256
    private $informacoes;
257
    /**
258
     * Protocolo de autorização da nota, informado apenas quando a nota for
259
     * enviada e autorizada
260
     */
261
    private $protocolo;
262
263
    /**
264
     * Constroi uma instância de Nota vazia
265
     * @param  array $nota Array contendo dados da Nota
266
     */
267 35
    public function __construct($nota = [])
268
    {
269 35
        $this->fromArray($nota);
270 35
    }
271
272
    /**
273
     * Chave da nota fiscal
274
     * @param boolean $normalize informa se o id deve estar no formato do XML
275
     * @return mixed id da Nota
276
     */
277 33
    public function getID($normalize = false)
278
    {
279 33
        if (!$normalize) {
280 33
            return $this->id;
281
        }
282 32
        return 'NFe'.$this->id;
283
    }
284
285
    /**
286
     * Altera o valor do ID para o informado no parâmetro
287
     * @param mixed $id novo valor para ID
288
     * @return Nota A própria instância da classe
289
     */
290 35
    public function setID($id)
291
    {
292 35
        $this->id = $id;
293 35
        return $this;
294
    }
295
296
    /**
297
     * Número do Documento Fiscal
298
     * @param boolean $normalize informa se o numero deve estar no formato do XML
299
     * @return mixed numero da Nota
300
     */
301 33
    public function getNumero($normalize = false)
302
    {
303 33
        if (!$normalize) {
304 33
            return $this->numero;
305
        }
306 32
        return $this->numero;
307
    }
308
309
    /**
310
     * Altera o valor do Numero para o informado no parâmetro
311
     * @param mixed $numero novo valor para Numero
312
     * @return Nota A própria instância da classe
313
     */
314 35
    public function setNumero($numero)
315
    {
316 35
        $this->numero = $numero;
317 35
        return $this;
318
    }
319
320
    /**
321
     * Emitente da nota fiscal
322
     * @return mixed emitente da Nota
323
     */
324 33
    public function getEmitente()
325
    {
326 33
        return $this->emitente;
327
    }
328
329
    /**
330
     * Altera o valor do Emitente para o informado no parâmetro
331
     * @param mixed $emitente novo valor para Emitente
332
     * @return Nota A própria instância da classe
333
     */
334 35
    public function setEmitente($emitente)
335
    {
336 35
        $this->emitente = $emitente;
337 35
        return $this;
338
    }
339
340
    /**
341
     * Destinatário que receberá os produtos
342
     * @return mixed destinatario da Nota
343
     */
344 33
    public function getDestinatario()
345
    {
346 33
        return $this->destinatario;
347
    }
348
349
    /**
350
     * Altera o valor do Destinatario para o informado no parâmetro
351
     * @param mixed $destinatario novo valor para Destinatario
352
     * @return Nota A própria instância da classe
353
     */
354 35
    public function setDestinatario($destinatario)
355
    {
356 35
        $this->destinatario = $destinatario;
357 35
        return $this;
358
    }
359
360
    /**
361
     * Produtos adicionados na nota
362
     * @return \NFe\Entity\Produto[] produtos da Nota
363
     */
364 33
    public function getProdutos()
365
    {
366 33
        return $this->produtos;
367
    }
368
369
    /**
370
     * Altera o valor do Produtos para o informado no parâmetro
371
     * @param mixed $produtos novo valor para Produtos
372
     * @return Nota A própria instância da classe
373
     */
374 35
    public function setProdutos($produtos)
375
    {
376 35
        $this->produtos = $produtos;
377 35
        return $this;
378
    }
379
380
    /**
381
     * Adiciona um(a) Produto para a lista de produto
382
     * @param Produto $produto Instância do Produto que será adicionada
383
     * @return Nota A própria instância da classe
384
     */
385 6
    public function addProduto($produto)
386
    {
387 6
        $this->produtos[] = $produto;
388 6
        return $this;
389
    }
390
391
    /**
392
     * Informações de trasnporte da mercadoria
393
     * @return mixed transporte da Nota
394
     */
395 33
    public function getTransporte()
396
    {
397 33
        return $this->transporte;
398
    }
399
400
    /**
401
     * Altera o valor da Transporte para o informado no parâmetro
402
     * @param mixed $transporte novo valor para Transporte
403
     * @return Nota A própria instância da classe
404
     */
405 35
    public function setTransporte($transporte)
406
    {
407 35
        $this->transporte = $transporte;
408 35
        return $this;
409
    }
410
411
    /**
412
     * Pagamentos realizados
413
     * @return mixed pagamentos da Nota
414
     */
415 33
    public function getPagamentos()
416
    {
417 33
        return $this->pagamentos;
418
    }
419
420
    /**
421
     * Altera o valor do Pagamentos para o informado no parâmetro
422
     * @param mixed $pagamentos novo valor para Pagamentos
423
     * @return Nota A própria instância da classe
424
     */
425 35
    public function setPagamentos($pagamentos)
426
    {
427 35
        $this->pagamentos = $pagamentos;
428 35
        return $this;
429
    }
430
431
    /**
432
     * Adiciona um(a) Pagamento para a lista de pagamento
433
     * @param Pagamento $pagamento Instância do Pagamento que será adicionada
434
     * @return Nota A própria instância da classe
435
     */
436 5
    public function addPagamento($pagamento)
437
    {
438 5
        $this->pagamentos[] = $pagamento;
439 5
        return $this;
440
    }
441
442
    /**
443
     * Data e Hora da saída ou de entrada da mercadoria / produto
444
     * @param boolean $normalize informa se a data_movimentacao deve estar no formato do XML
445
     * @return mixed data_movimentacao da Nota
446
     */
447 33
    public function getDataMovimentacao($normalize = false)
448
    {
449 33
        if (!$normalize || is_null($this->data_movimentacao)) {
450 33
            return $this->data_movimentacao;
451
        }
452
        return Util::toDateTime($this->data_movimentacao);
453
    }
454
455
    /**
456
     * Altera o valor da DataMovimentacao para o informado no parâmetro
457
     * @param mixed $data_movimentacao novo valor para DataMovimentacao
458
     * @return Nota A própria instância da classe
459
     */
460 35
    public function setDataMovimentacao($data_movimentacao)
461
    {
462 35
        if (!is_null($data_movimentacao) && !is_numeric($data_movimentacao)) {
463
            $data_movimentacao = strtotime($data_movimentacao);
464
        }
465 35
        $this->data_movimentacao = $data_movimentacao;
466 35
        return $this;
467
    }
468
469
    /**
470
     * Informar a data e hora de entrada em contingência
471
     * @param boolean $normalize informa se a data_contingencia deve estar no formato do XML
472
     * @return mixed data_contingencia da Nota
473
     */
474 8
    public function getDataContingencia($normalize = false)
475
    {
476 8
        if (!$normalize || is_null($this->data_contingencia)) {
477 8
            return $this->data_contingencia;
478
        }
479 1
        return Util::toDateTime($this->data_contingencia);
480
    }
481
482
    /**
483
     * Altera o valor da DataContingencia para o informado no parâmetro
484
     * @param mixed $data_contingencia novo valor para DataContingencia
485
     * @return Nota A própria instância da classe
486
     */
487 35
    public function setDataContingencia($data_contingencia)
488
    {
489 35
        if (!is_null($data_contingencia) && !is_numeric($data_contingencia)) {
490
            $data_contingencia = strtotime($data_contingencia);
491
        }
492 35
        $this->data_contingencia = $data_contingencia;
493 35
        return $this;
494
    }
495
496
    /**
497
     * Informar a Justificativa da entrada em contingência
498
     * @param boolean $normalize informa se a justificativa deve estar no formato do XML
499
     * @return mixed justificativa da Nota
500
     */
501 10
    public function getJustificativa($normalize = false)
502
    {
503 10
        if (!$normalize) {
504 10
            return $this->justificativa;
505
        }
506 1
        return $this->justificativa;
507
    }
508
509
    /**
510
     * Altera o valor da Justificativa para o informado no parâmetro
511
     * @param mixed $justificativa novo valor para Justificativa
512
     * @return Nota A própria instância da classe
513
     */
514 35
    public function setJustificativa($justificativa)
515
    {
516 35
        $this->justificativa = $justificativa;
517 35
        return $this;
518
    }
519
520
    /**
521
     * Código do modelo do Documento Fiscal. 55 = NF-e; 65 = NFC-e.
522
     * @param boolean $normalize informa se o modelo deve estar no formato do XML
523
     * @return mixed modelo da Nota
524
     */
525 33
    public function getModelo($normalize = false)
526
    {
527 33
        if (!$normalize) {
528 32
            return $this->modelo;
529
        }
530 32
        switch ($this->modelo) {
531 32
            case self::MODELO_NFE:
532 1
                return '55';
533 31
            case self::MODELO_NFCE:
534 31
                return '65';
535
        }
536
        return $this->modelo;
537
    }
538
539
    /**
540
     * Altera o valor do Modelo para o informado no parâmetro
541
     * @param mixed $modelo novo valor para Modelo
542
     * @return Nota A própria instância da classe
543
     */
544 35
    public function setModelo($modelo)
545
    {
546
        switch ($modelo) {
547 35
            case '55':
548
                $modelo = self::MODELO_NFE;
549
                break;
550 35
            case '65':
551 27
                $modelo = self::MODELO_NFCE;
552 27
                break;
553
        }
554 35
        $this->modelo = $modelo;
555 35
        return $this;
556
    }
557
558
    /**
559
     * Tipo do Documento Fiscal (0 - entrada; 1 - saída)
560
     * @param boolean $normalize informa se o tipo deve estar no formato do XML
561
     * @return mixed tipo da Nota
562
     */
563 33
    public function getTipo($normalize = false)
564
    {
565 33
        if (!$normalize) {
566 8
            return $this->tipo;
567
        }
568 32
        switch ($this->tipo) {
569 32
            case self::TIPO_ENTRADA:
570
                return '0';
571 32
            case self::TIPO_SAIDA:
572 32
                return '1';
573
        }
574
        return $this->tipo;
575
    }
576
577
    /**
578
     * Altera o valor do Tipo para o informado no parâmetro
579
     * @param mixed $tipo novo valor para Tipo
580
     * @return Nota A própria instância da classe
581
     */
582 35
    public function setTipo($tipo)
583
    {
584
        switch ($tipo) {
585 35
            case '0':
586
                $tipo = self::TIPO_ENTRADA;
587
                break;
588 35
            case '1':
589 27
                $tipo = self::TIPO_SAIDA;
590 27
                break;
591
        }
592 35
        $this->tipo = $tipo;
593 35
        return $this;
594
    }
595
596
    /**
597
     * Identificador de Local de destino da operação
598
     * (1-Interna;2-Interestadual;3-Exterior)
599
     * @param boolean $normalize informa se o destino deve estar no formato do XML
600
     * @return mixed destino da Nota
601
     */
602 33
    public function getDestino($normalize = false)
603
    {
604 33
        if (!$normalize) {
605 8
            return $this->destino;
606
        }
607 32
        switch ($this->destino) {
608 32
            case self::DESTINO_INTERNA:
609 32
                return '1';
610
            case self::DESTINO_INTERESTADUAL:
611
                return '2';
612
            case self::DESTINO_EXTERIOR:
613
                return '3';
614
        }
615
        return $this->destino;
616
    }
617
618
    /**
619
     * Altera o valor do Destino para o informado no parâmetro
620
     * @param mixed $destino novo valor para Destino
621
     * @return Nota A própria instância da classe
622
     */
623 35
    public function setDestino($destino)
624
    {
625
        switch ($destino) {
626 35
            case '1':
627 27
                $destino = self::DESTINO_INTERNA;
628 27
                break;
629 35
            case '2':
630
                $destino = self::DESTINO_INTERESTADUAL;
631
                break;
632 35
            case '3':
633
                $destino = self::DESTINO_EXTERIOR;
634
                break;
635
        }
636 35
        $this->destino = $destino;
637 35
        return $this;
638
    }
639
640
    /**
641
     * Descrição da Natureza da Operação
642
     * @param boolean $normalize informa se a natureza deve estar no formato do XML
643
     * @return mixed natureza da Nota
644
     */
645 33
    public function getNatureza($normalize = false)
646
    {
647 33
        if (!$normalize) {
648 8
            return $this->natureza;
649
        }
650 32
        return $this->natureza;
651
    }
652
653
    /**
654
     * Altera o valor da Natureza para o informado no parâmetro
655
     * @param mixed $natureza novo valor para Natureza
656
     * @return Nota A própria instância da classe
657
     */
658 35
    public function setNatureza($natureza)
659
    {
660 35
        $this->natureza = $natureza;
661 35
        return $this;
662
    }
663
664
    /**
665
     * Código numérico que compõe a Chave de Acesso. Número aleatório gerado
666
     * pelo emitente para cada NF-e.
667
     * @param boolean $normalize informa se o codigo deve estar no formato do XML
668
     * @return mixed codigo da Nota
669
     */
670 33
    public function getCodigo($normalize = false)
671
    {
672 33
        if (!$normalize) {
673 33
            return $this->codigo;
674
        }
675 32
        return Util::padDigit($this->codigo % 100000000, 8);
676
    }
677
678
    /**
679
     * Altera o valor do Codigo para o informado no parâmetro
680
     * @param mixed $codigo novo valor para Codigo
681
     * @return Nota A própria instância da classe
682
     */
683 35
    public function setCodigo($codigo)
684
    {
685 35
        $this->codigo = $codigo;
686 35
        return $this;
687
    }
688
689
    /**
690
     * Data e Hora de emissão do Documento Fiscal
691
     * @param boolean $normalize informa se o data_emissao deve estar no formato do XML
692
     * @return mixed data_emissao da Nota
693
     */
694 33
    public function getDataEmissao($normalize = false)
695
    {
696 33
        if (!$normalize) {
697 32
            return $this->data_emissao;
698
        }
699 33
        return Util::toDateTime($this->data_emissao);
700
    }
701
702
    /**
703
     * Altera o valor do DataEmissao para o informado no parâmetro
704
     * @param mixed $data_emissao novo valor para DataEmissao
705
     * @return Nota A própria instância da classe
706
     */
707 35
    public function setDataEmissao($data_emissao)
708
    {
709 35
        if (!is_numeric($data_emissao)) {
710 35
            $data_emissao = strtotime($data_emissao);
711
        }
712 35
        $this->data_emissao = $data_emissao;
713 35
        return $this;
714
    }
715
716
    /**
717
     * Série do Documento Fiscal: série normal 0-889, Avulsa Fisco 890-899,
718
     * SCAN 900-999
719
     * @param boolean $normalize informa se o serie deve estar no formato do XML
720
     * @return mixed serie da Nota
721
     */
722 33
    public function getSerie($normalize = false)
723
    {
724 33
        if (!$normalize) {
725 33
            return $this->serie;
726
        }
727 32
        return $this->serie;
728
    }
729
730
    /**
731
     * Altera o valor do Serie para o informado no parâmetro
732
     * @param mixed $serie novo valor para Serie
733
     * @return Nota A própria instância da classe
734
     */
735 35
    public function setSerie($serie)
736
    {
737 35
        $this->serie = $serie;
738 35
        return $this;
739
    }
740
741
    /**
742
     * Formato de impressão do DANFE (0-sem DANFE;1-DANFe Retrato; 2-DANFe
743
     * Paisagem;3-DANFe Simplificado;4-DANFe NFC-e;5-DANFe NFC-e em mensagem
744
     * eletrônica)
745
     * @param boolean $normalize informa se o formato deve estar no formato do XML
746
     * @return mixed formato da Nota
747
     */
748 33
    public function getFormato($normalize = false)
749
    {
750 33
        if (!$normalize) {
751 8
            return $this->formato;
752
        }
753 32
        switch ($this->formato) {
754 32
            case self::FORMATO_NENHUMA:
755 1
                return '0';
756 31
            case self::FORMATO_RETRATO:
757
                return '1';
758 31
            case self::FORMATO_PAISAGEM:
759
                return '2';
760 31
            case self::FORMATO_SIMPLIFICADO:
761
                return '3';
762 31
            case self::FORMATO_CONSUMIDOR:
763 31
                return '4';
764
            case self::FORMATO_MENSAGEM:
765
                return '5';
766
        }
767
        return $this->formato;
768
    }
769
770
    /**
771
     * Altera o valor do Formato para o informado no parâmetro
772
     * @param mixed $formato novo valor para Formato
773
     * @return Nota A própria instância da classe
774
     */
775 35
    public function setFormato($formato)
776
    {
777
        switch ($formato) {
778 35
            case '0':
779
                $formato = self::FORMATO_NENHUMA;
780
                break;
781 35
            case '1':
782
                $formato = self::FORMATO_RETRATO;
783
                break;
784 35
            case '2':
785
                $formato = self::FORMATO_PAISAGEM;
786
                break;
787 35
            case '3':
788
                $formato = self::FORMATO_SIMPLIFICADO;
789
                break;
790 35
            case '4':
791 27
                $formato = self::FORMATO_CONSUMIDOR;
792 27
                break;
793 35
            case '5':
794
                $formato = self::FORMATO_MENSAGEM;
795
                break;
796
        }
797 35
        $this->formato = $formato;
798 35
        return $this;
799
    }
800
801
    /**
802
     * Forma de emissão da NF-e
803
     * @param boolean $normalize informa se o emissao deve estar no formato do XML
804
     * @return mixed emissao da Nota
805
     */
806 33
    public function getEmissao($normalize = false)
807
    {
808 33
        if (!$normalize) {
809 33
            return $this->emissao;
810
        }
811 32
        switch ($this->emissao) {
812 32
            case self::EMISSAO_NORMAL:
813 32
                return '1';
814 1
            case self::EMISSAO_CONTINGENCIA:
815 1
                return '9';
816
        }
817
        return $this->emissao;
818
    }
819
820
    /**
821
     * Altera o valor do Emissao para o informado no parâmetro
822
     * @param mixed $emissao novo valor para Emissao
823
     * @return Nota A própria instância da classe
824
     */
825 35
    public function setEmissao($emissao)
826
    {
827
        switch ($emissao) {
828 35
            case '1':
829 27
                $emissao = self::EMISSAO_NORMAL;
830 27
                break;
831 35
            case '9':
832
                $emissao = self::EMISSAO_CONTINGENCIA;
833
                break;
834
        }
835 35
        $this->emissao = $emissao;
836 35
        return $this;
837
    }
838
839
    /**
840
     * Digito Verificador da Chave de Acesso da NF-e
841
     * @param boolean $normalize informa se o digito_verificador deve estar no formato do XML
842
     * @return mixed digito_verificador da Nota
843
     */
844 33
    public function getDigitoVerificador($normalize = false)
845
    {
846 33
        if (!$normalize) {
847 8
            return $this->digito_verificador;
848
        }
849 32
        return $this->digito_verificador;
850
    }
851
852
    /**
853
     * Altera o valor do DigitoVerificador para o informado no parâmetro
854
     * @param mixed $digito_verificador novo valor para DigitoVerificador
855
     * @return Nota A própria instância da classe
856
     */
857 35
    public function setDigitoVerificador($digito_verificador)
858
    {
859 35
        $this->digito_verificador = $digito_verificador;
860 35
        return $this;
861
    }
862
863
    /**
864
     * Identificação do Ambiente: 1 - Produção, 2 - Homologação
865
     * @param boolean $normalize informa se o ambiente deve estar no formato do XML
866
     * @return mixed ambiente da Nota
867
     */
868 33
    public function getAmbiente($normalize = false)
869
    {
870 33
        if (!$normalize) {
871 33
            return $this->ambiente;
872
        }
873 32
        switch ($this->ambiente) {
874 32
            case self::AMBIENTE_PRODUCAO:
875
                return '1';
876 32
            case self::AMBIENTE_HOMOLOGACAO:
877 32
                return '2';
878
        }
879
        return $this->ambiente;
880
    }
881
882
    /**
883
     * Altera o valor do Ambiente para o informado no parâmetro
884
     * @param mixed $ambiente novo valor para Ambiente
885
     * @return Nota A própria instância da classe
886
     */
887 35
    public function setAmbiente($ambiente)
888
    {
889
        switch ($ambiente) {
890 35
            case '1':
891
                $ambiente = self::AMBIENTE_PRODUCAO;
892
                break;
893 35
            case '2':
894 27
                $ambiente = self::AMBIENTE_HOMOLOGACAO;
895 27
                break;
896
        }
897 35
        $this->ambiente = $ambiente;
898 35
        return $this;
899
    }
900
901
    /**
902
     * Finalidade da emissão da NF-e: 1 - NFe normal, 2 - NFe complementar, 3 -
903
     * NFe de ajuste, 4 - Devolução/Retorno
904
     * @param boolean $normalize informa se a finalidade deve estar no formato do XML
905
     * @return mixed finalidade da Nota
906
     */
907 33
    public function getFinalidade($normalize = false)
908
    {
909 33
        if (!$normalize) {
910 8
            return $this->finalidade;
911
        }
912 32
        switch ($this->finalidade) {
913 32
            case self::FINALIDADE_NORMAL:
914 32
                return '1';
915
            case self::FINALIDADE_COMPLEMENTAR:
916
                return '2';
917
            case self::FINALIDADE_AJUSTE:
918
                return '3';
919
            case self::FINALIDADE_RETORNO:
920
                return '4';
921
        }
922
        return $this->finalidade;
923
    }
924
925
    /**
926
     * Altera o valor da Finalidade para o informado no parâmetro
927
     * @param mixed $finalidade novo valor para Finalidade
928
     * @return Nota A própria instância da classe
929
     */
930 35
    public function setFinalidade($finalidade)
931
    {
932
        switch ($finalidade) {
933 35
            case '1':
934 27
                $finalidade = self::FINALIDADE_NORMAL;
935 27
                break;
936 35
            case '2':
937
                $finalidade = self::FINALIDADE_COMPLEMENTAR;
938
                break;
939 35
            case '3':
940
                $finalidade = self::FINALIDADE_AJUSTE;
941
                break;
942 35
            case '4':
943
                $finalidade = self::FINALIDADE_RETORNO;
944
                break;
945
        }
946 35
        $this->finalidade = $finalidade;
947 35
        return $this;
948
    }
949
950
    /**
951
     * Indica operação com consumidor final (0-Não;1-Consumidor Final)
952
     * @param boolean $normalize informa se o consumidor_final deve estar no formato do XML
953
     * @return mixed consumidor_final da Nota
954
     */
955 33
    public function getConsumidorFinal($normalize = false)
956
    {
957 33
        if (!$normalize) {
958 8
            return $this->consumidor_final;
959
        }
960 32
        switch ($this->consumidor_final) {
961 32
            case 'N':
962
                return '0';
963 32
            case 'Y':
964 6
                return '1';
965
        }
966 27
        return $this->consumidor_final;
967
    }
968
969
    /**
970
     * Indica operação com consumidor final (0-Não;1-Consumidor Final)
971
     * @return boolean informa se o ConsumidorFinal está habilitado
972
     */
973
    public function isConsumidorFinal()
974
    {
975
        return $this->consumidor_final == 'Y';
976
    }
977
978
    /**
979
     * Altera o valor do ConsumidorFinal para o informado no parâmetro
980
     * @param mixed $consumidor_final novo valor para ConsumidorFinal
981
     * @return Nota A própria instância da classe
982
     */
983 35
    public function setConsumidorFinal($consumidor_final)
984
    {
985 35
        if (is_bool($consumidor_final)) {
986
            $consumidor_final = $consumidor_final ? 'Y': 'N';
987
        }
988 35
        $this->consumidor_final = $consumidor_final;
989 35
        return $this;
990
    }
991
992
    /**
993
     * Indicador de presença do comprador no estabelecimento comercial no
994
     * momento da oepração (0-Não se aplica (ex.: Nota Fiscal complementar ou
995
     * de ajuste;1-Operação presencial;2-Não presencial, internet;
996
     * 3-Não presencial, teleatendimento;4-NFC-e entrega em domicílio;
997
     * 5-Operação presencial, fora do estabelecimento;9-Não presencial, outros)
998
     * @param boolean $normalize informa se a presenca deve estar no formato do XML
999
     * @return mixed presenca da Nota
1000
     */
1001 33
    public function getPresenca($normalize = false)
1002
    {
1003 33
        if (!$normalize) {
1004 8
            return $this->presenca;
1005
        }
1006 32
        switch ($this->presenca) {
1007 32
            case self::PRESENCA_NENHUM:
1008
                return '0';
1009 32
            case self::PRESENCA_PRESENCIAL:
1010 32
                return '1';
1011
            case self::PRESENCA_INTERNET:
1012
                return '2';
1013
            case self::PRESENCA_TELEATENDIMENTO:
1014
                return '3';
1015
            case self::PRESENCA_ENTREGA:
1016
                return '4';
1017
            case self::PRESENCA_AMBULANTE:
1018
                return '5';
1019
            case self::PRESENCA_OUTROS:
1020
                return '9';
1021
        }
1022
        return $this->presenca;
1023
    }
1024
1025
    /**
1026
     * Altera o valor da Presenca para o informado no parâmetro
1027
     * @param mixed $presenca novo valor para Presenca
1028
     * @return Nota A própria instância da classe
1029
     */
1030 35
    public function setPresenca($presenca)
1031
    {
1032
        switch ($presenca) {
1033 35
            case '0':
1034
                $presenca = self::PRESENCA_NENHUM;
1035
                break;
1036 35
            case '1':
1037 27
                $presenca = self::PRESENCA_PRESENCIAL;
1038 27
                break;
1039 35
            case '2':
1040
                $presenca = self::PRESENCA_INTERNET;
1041
                break;
1042 35
            case '3':
1043
                $presenca = self::PRESENCA_TELEATENDIMENTO;
1044
                break;
1045 35
            case '4':
1046
                $presenca = self::PRESENCA_ENTREGA;
1047
                break;
1048 35
            case '5':
1049
                $presenca = self::PRESENCA_AMBULANTE;
1050
                break;
1051 35
            case '9':
1052
                $presenca = self::PRESENCA_OUTROS;
1053
                break;
1054
        }
1055 35
        $this->presenca = $presenca;
1056 35
        return $this;
1057
    }
1058
1059
    /**
1060
     * Dados dos totais da NF-e
1061
     * @return mixed total da Nota
1062
     */
1063 33
    public function getTotal()
1064
    {
1065 33
        return $this->total;
1066
    }
1067
    
1068
    /**
1069
     * Altera o valor do Total para o informado no parâmetro
1070
     * @param mixed $total novo valor para Total
1071
     * @return Nota A própria instância da classe
1072
     */
1073 35
    public function setTotal($total)
1074
    {
1075 35
        $this->total = $total;
1076 35
        return $this;
1077
    }
1078
1079
    /**
1080
     * Informações adicionais de interesse do Fisco
1081
     * @param boolean $normalize informa se a adicionais deve estar no formato do XML
1082
     * @return mixed adicionais da Nota
1083
     */
1084 33
    public function getAdicionais($normalize = false)
1085
    {
1086 33
        if (!$normalize) {
1087 33
            return $this->adicionais;
1088
        }
1089
        return $this->adicionais;
1090
    }
1091
    
1092
    /**
1093
     * Altera o valor da Adicionais para o informado no parâmetro
1094
     * @param mixed $adicionais novo valor para Adicionais
1095
     * @return Nota A própria instância da classe
1096
     */
1097 35
    public function setAdicionais($adicionais)
1098
    {
1099 35
        $this->adicionais = $adicionais;
1100 35
        return $this;
1101
    }
1102
1103
    /**
1104
     * Campo de uso livre do contribuinte informar o nome do campo no atributo
1105
     * xCampo e o conteúdo do campo no xTexto
1106
     * @return mixed observacoes da Nota
1107
     */
1108 33
    public function getObservacoes()
1109
    {
1110 33
        return $this->observacoes;
1111
    }
1112
    
1113
    /**
1114
     * Altera o valor da Observacoes para o informado no parâmetro
1115
     * @param mixed $observacoes novo valor para Observacoes
1116
     * @return Nota A própria instância da classe
1117
     */
1118 35
    public function setObservacoes($observacoes)
1119
    {
1120 35
        $this->observacoes = $observacoes;
1121 35
        return $this;
1122
    }
1123
1124
    /**
1125
     * Adiciona um(a) Observacao para a lista de observacao
1126
     * @param Observacao $observacao Instância da Observacao que será adicionada
1127
     * @return Nota A própria instância da classe
1128
     */
1129 6
    public function addObservacao($campo, $observacao)
1130
    {
1131 6
        $this->observacoes[] = ['campo' => $campo, 'valor' => $observacao];
1132 6
        return $this;
1133
    }
1134
1135
    /**
1136
     * Campo de uso exclusivo do Fisco informar o nome do campo no atributo
1137
     * xCampo e o conteúdo do campo no xTexto
1138
     * @return mixed informacoes da Nota
1139
     */
1140 33
    public function getInformacoes()
1141
    {
1142 33
        return $this->informacoes;
1143
    }
1144
    
1145
    /**
1146
     * Altera o valor da Informacoes para o informado no parâmetro
1147
     * @param mixed $informacoes novo valor para Informacoes
1148
     * @return Nota A própria instância da classe
1149
     */
1150 35
    public function setInformacoes($informacoes)
1151
    {
1152 35
        $this->informacoes = $informacoes;
1153 35
        return $this;
1154
    }
1155
1156
    /**
1157
     * Adiciona um(a) Informacao para a lista de informacao
1158
     * @param Informacao $informacao Instância da Informacao que será adicionada
1159
     * @return Nota A própria instância da classe
1160
     */
1161 6
    public function addInformacao($campo, $informacao)
1162
    {
1163 6
        $this->informacoes[] = ['campo' => $campo, 'valor' => $informacao];
1164 6
        return $this;
1165
    }
1166
1167
    /**
1168
     * Protocolo de autorização da nota, informado apenas quando a nota for
1169
     * enviada e autorizada
1170
     */
1171 31
    public function getProtocolo()
1172
    {
1173 31
        return $this->protocolo;
1174
    }
1175
1176 35
    public function setProtocolo($protocolo)
1177
    {
1178 35
        $this->protocolo = $protocolo;
1179 35
        return $this;
1180
    }
1181
1182 8
    public function toArray($recursive = false)
0 ignored issues
show
Complexity introduced by
This operation has 2187 execution paths which exceeds the configured maximum of 200.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

You can also find more information in the “Code” section of your repository.

Loading history...
1183
    {
1184 8
        $nota = [];
1185 8
        $nota['id'] = $this->getID();
1186 8
        $nota['numero'] = $this->getNumero();
1187 8
        if (!is_null($this->getEmitente()) && $recursive) {
1188 2
            $nota['emitente'] = $this->getEmitente()->toArray($recursive);
1189
        } else {
1190 6
            $nota['emitente'] = $this->getEmitente();
1191
        }
1192 8
        if (!is_null($this->getDestinatario()) && $recursive) {
1193 2
            $nota['destinatario'] = $this->getDestinatario()->toArray($recursive);
1194
        } else {
1195 6
            $nota['destinatario'] = $this->getDestinatario();
1196
        }
1197 8
        if ($recursive) {
1198 2
            $produtos = [];
1199 2
            $_produtos = $this->getProdutos();
1200 2
            foreach ($_produtos as $_produto) {
1201 1
                $produtos[] = $_produto->toArray($recursive);
1202
            }
1203 2
            $nota['produtos'] = $produtos;
1204
        } else {
1205 6
            $nota['produtos'] = $this->getProdutos();
1206
        }
1207 8
        if (!is_null($this->getTransporte()) && $recursive) {
1208 2
            $nota['transporte'] = $this->getTransporte()->toArray($recursive);
1209
        } else {
1210 6
            $nota['transporte'] = $this->getTransporte();
1211
        }
1212 8
        if ($recursive) {
1213 2
            $pagamentos = [];
1214 2
            $_pagamentos = $this->getPagamentos();
1215 2
            foreach ($_pagamentos as $_pagamento) {
1216 1
                $pagamentos[] = $_pagamento->toArray($recursive);
1217
            }
1218 2
            $nota['pagamentos'] = $pagamentos;
1219
        } else {
1220 6
            $nota['pagamentos'] = $this->getPagamentos();
1221
        }
1222 8
        $nota['data_movimentacao'] = $this->getDataMovimentacao($recursive);
1223 8
        $nota['data_contingencia'] = $this->getDataContingencia($recursive);
1224 8
        $nota['justificativa'] = $this->getJustificativa();
1225 8
        $nota['modelo'] = $this->getModelo();
1226 8
        $nota['tipo'] = $this->getTipo();
1227 8
        $nota['destino'] = $this->getDestino();
1228 8
        $nota['natureza'] = $this->getNatureza();
1229 8
        $nota['codigo'] = $this->getCodigo();
1230 8
        $nota['data_emissao'] = $this->getDataEmissao($recursive);
1231 8
        $nota['serie'] = $this->getSerie();
1232 8
        $nota['formato'] = $this->getFormato();
1233 8
        $nota['emissao'] = $this->getEmissao();
1234 8
        $nota['digito_verificador'] = $this->getDigitoVerificador();
1235 8
        $nota['ambiente'] = $this->getAmbiente();
1236 8
        $nota['finalidade'] = $this->getFinalidade();
1237 8
        $nota['consumidor_final'] = $this->getConsumidorFinal();
1238 8
        $nota['presenca'] = $this->getPresenca();
1239 8
        if (!is_null($this->getTotal()) && $recursive) {
1240 2
            $nota['total'] = $this->getTotal()->toArray($recursive);
1241
        } else {
1242 6
            $nota['total'] = $this->getTotal();
1243
        }
1244 8
        $nota['adicionais'] = $this->getAdicionais();
1245 8
        $nota['observacoes'] = $this->getObservacoes();
1246 8
        $nota['informacoes'] = $this->getInformacoes();
1247 8
        if (!is_null($this->getProtocolo()) && $recursive) {
1248 1
            $nota['protocolo'] = $this->getProtocolo()->toArray($recursive);
1249
        } else {
1250 7
            $nota['protocolo'] = $this->getProtocolo();
1251
        }
1252 8
        return $nota;
1253
    }
1254
1255 35
    public function fromArray($nota = [])
0 ignored issues
show
Complexity introduced by
This operation has 62914560000 execution paths which exceeds the configured maximum of 200.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

You can also find more information in the “Code” section of your repository.

Loading history...
1256
    {
1257 35
        if ($nota instanceof Nota) {
1258
            $nota = $nota->toArray();
1259 35
        } elseif (!is_array($nota)) {
1260
            return $this;
1261
        }
1262 35
        if (isset($nota['id'])) {
1263
            $this->setID($nota['id']);
1264
        } else {
1265 35
            $this->setID(null);
1266
        }
1267 35
        if (isset($nota['numero'])) {
1268 6
            $this->setNumero($nota['numero']);
1269
        } else {
1270 35
            $this->setNumero(null);
1271
        }
1272 35
        $this->setEmitente(new Emitente(isset($nota['emitente']) ? $nota['emitente'] : []));
1273 35
        $this->setDestinatario(new Destinatario(isset($nota['destinatario']) ? $nota['destinatario'] : []));
1274 35
        if (!isset($nota['produtos'])) {
1275 35
            $this->setProdutos([]);
1276
        } else {
1277 6
            $this->setProdutos($nota['produtos']);
1278
        }
1279 35
        $this->setTransporte(new Transporte(isset($nota['transporte']) ? $nota['transporte'] : []));
1280 35
        if (!isset($nota['pagamentos'])) {
1281 35
            $this->setPagamentos([]);
1282
        } else {
1283 6
            $this->setPagamentos($nota['pagamentos']);
1284
        }
1285 35
        if (isset($nota['data_movimentacao'])) {
1286
            $this->setDataMovimentacao($nota['data_movimentacao']);
1287
        } else {
1288 35
            $this->setDataMovimentacao(null);
1289
        }
1290 35
        if (isset($nota['data_contingencia'])) {
1291
            $this->setDataContingencia($nota['data_contingencia']);
1292
        } else {
1293 35
            $this->setDataContingencia(null);
1294
        }
1295 35
        if (isset($nota['justificativa'])) {
1296
            $this->setJustificativa($nota['justificativa']);
1297
        } else {
1298 35
            $this->setJustificativa(null);
1299
        }
1300 35
        if (isset($nota['modelo'])) {
1301 6
            $this->setModelo($nota['modelo']);
1302
        } else {
1303 35
            $this->setModelo(null);
1304
        }
1305 35
        if (!isset($nota['tipo'])) {
1306 35
            $this->setTipo(self::TIPO_SAIDA);
1307
        } else {
1308 6
            $this->setTipo($nota['tipo']);
1309
        }
1310 35
        if (!isset($nota['destino'])) {
1311 35
            $this->setDestino(self::DESTINO_INTERNA);
1312
        } else {
1313 6
            $this->setDestino($nota['destino']);
1314
        }
1315 35
        if (!isset($nota['natureza'])) {
1316 35
            $this->setNatureza('VENDA PARA CONSUMIDOR FINAL');
1317
        } else {
1318 6
            $this->setNatureza($nota['natureza']);
1319
        }
1320 35
        if (isset($nota['codigo'])) {
1321 6
            $this->setCodigo($nota['codigo']);
1322
        } else {
1323 35
            $this->setCodigo(null);
1324
        }
1325 35
        if (isset($nota['data_emissao'])) {
1326 6
            $this->setDataEmissao($nota['data_emissao']);
1327
        } else {
1328 35
            $this->setDataEmissao(null);
1329
        }
1330 35
        if (isset($nota['serie'])) {
1331 6
            $this->setSerie($nota['serie']);
1332
        } else {
1333 35
            $this->setSerie(null);
1334
        }
1335 35
        if (!isset($nota['formato'])) {
1336 35
            $this->setFormato(self::FORMATO_NENHUMA);
1337
        } else {
1338 6
            $this->setFormato($nota['formato']);
1339
        }
1340 35
        if (!isset($nota['emissao'])) {
1341 35
            $this->setEmissao(self::EMISSAO_NORMAL);
1342
        } else {
1343 6
            $this->setEmissao($nota['emissao']);
1344
        }
1345 35
        if (isset($nota['digito_verificador'])) {
1346
            $this->setDigitoVerificador($nota['digito_verificador']);
1347
        } else {
1348 35
            $this->setDigitoVerificador(null);
1349
        }
1350 35
        if (!isset($nota['ambiente'])) {
1351 35
            $this->setAmbiente(self::AMBIENTE_HOMOLOGACAO);
1352
        } else {
1353 6
            $this->setAmbiente($nota['ambiente']);
1354
        }
1355 35
        if (!isset($nota['finalidade'])) {
1356 35
            $this->setFinalidade(self::FINALIDADE_NORMAL);
1357
        } else {
1358 6
            $this->setFinalidade($nota['finalidade']);
1359
        }
1360 35
        if (!isset($nota['consumidor_final'])) {
1361 35
            $this->setConsumidorFinal('Y');
1362
        } else {
1363 6
            $this->setConsumidorFinal($nota['consumidor_final']);
1364
        }
1365 35
        if (isset($nota['presenca'])) {
1366 6
            $this->setPresenca($nota['presenca']);
1367
        } else {
1368 35
            $this->setPresenca(null);
1369
        }
1370 35
        $this->setTotal(new Total(isset($nota['total']) ? $nota['total'] : []));
1371 35
        if (!array_key_exists('adicionais', $nota)) {
1372 35
            $this->setAdicionais(null);
1373
        } else {
1374 6
            $this->setAdicionais($nota['adicionais']);
1375
        }
1376 35
        if (!array_key_exists('observacoes', $nota)) {
1377 35
            $this->setObservacoes(null);
1378
        } else {
1379 6
            $this->setObservacoes($nota['observacoes']);
1380
        }
1381 35
        if (!array_key_exists('informacoes', $nota)) {
1382 35
            $this->setInformacoes(null);
1383
        } else {
1384 6
            $this->setInformacoes($nota['informacoes']);
1385
        }
1386 35
        if (isset($nota['protocolo'])) {
1387
            $this->setProtocolo($nota['protocolo']);
1388
        } else {
1389 35
            $this->setProtocolo(null);
1390
        }
1391 35
        return $this;
1392
    }
1393
1394 32
    public function gerarID()
1395
    {
1396 32
        $estado = $this->getEmitente()->getEndereco()->getMunicipio()->getEstado();
1397 32
        $estado->checkCodigos();
1398 32
        $id = sprintf(
1399 32
            '%02d%02d%02d%s%02d%03d%09d%01d%08d',
1400 32
            $estado->getCodigo(),
1401 32
            date('y', $this->getDataEmissao()), // Ano 2 dígitos
1402 32
            date('m', $this->getDataEmissao()), // Mês 2 dígitos
1403 32
            $this->getEmitente()->getCNPJ(),
1404 32
            $this->getModelo(true),
1405 32
            $this->getSerie(),
1406 32
            $this->getNumero(),
1407 32
            $this->getEmissao(true),
1408 32
            $this->getCodigo()
1409
        );
1410 32
        return $id.Util::getDAC($id, 11);
1411
    }
1412
1413 32
    public function getTotais()
1414
    {
1415 32
        $total = [];
1416 32
        $total['produtos'] = 0.00;
1417 32
        $total['desconto'] = 0.00;
1418 32
        $total['frete'] = 0.00;
1419 32
        $total['seguro'] = 0.00;
1420 32
        $total['despesas'] = 0.00;
1421 32
        $total['tributos'] = 0.00;
1422 32
        $total['icms'] = 0.00;
1423 32
        $total['icms.st'] = 0.00;
1424 32
        $total['base'] = 0.00;
1425 32
        $total['base.st'] = 0.00;
1426 32
        $total['ii'] = 0.00;
1427 32
        $total['ipi'] = 0.00;
1428 32
        $total['pis'] = 0.00;
1429 32
        $total['cofins'] = 0.00;
1430 32
        $total['desoneracao'] = 0.00;
1431 32
        $total['fundo'] = 0.00;
1432 32
        $total['fundo.st'] = 0.00;
1433 32
        $total['fundo.retido.st'] = 0.00;
1434 32
        $total['ipi.devolvido'] = 0.00;
1435 32
        $_produtos = $this->getProdutos();
1436 32
        foreach ($_produtos as $_produto) {
1437 32
            if (!$_produto->getMultiplicador()) {
1438
                continue;
1439
            }
1440 32
            $imposto_info = $_produto->getImpostoInfo();
1441 32
            $total['produtos'] += round($_produto->getPreco(), 2);
1442 32
            $total['desconto'] += round($_produto->getDesconto(), 2);
1443 32
            $total['frete'] += round($_produto->getFrete(), 2);
1444 32
            $total['seguro'] += round($_produto->getSeguro(), 2);
1445 32
            $total['despesas'] += round($_produto->getDespesas(), 2);
1446 32
            $total['tributos'] += round($imposto_info['total'], 2);
1447 32
            $_impostos = $_produto->getImpostos();
1448 32
            foreach ($_impostos as $_imposto) {
1449 32
                switch ($_imposto->getGrupo()) {
1450 32
                    case Imposto::GRUPO_ICMS:
1451 32
                        if (($_imposto instanceof \NFe\Entity\Imposto\ICMS\Cobranca) ||
1452 32
                                ($_imposto instanceof \NFe\Entity\Imposto\ICMS\Simples\Cobranca)
1453
                        ) {
1454 32
                            $total[$_imposto->getGrupo()] += round($_imposto->getNormal()->getValor(), 2);
1455 32
                            $total['base'] += round($_imposto->getNormal()->getBase(), 2);
1456
                        }
1457 32
                        if (($_imposto instanceof \NFe\Entity\Imposto\ICMS\Parcial) ||
1458 32
                                ($_imposto instanceof \NFe\Entity\Imposto\ICMS\Simples\Parcial)
1459
                        ) {
1460 32
                            $total['icms.st'] += round($_imposto->getValor(), 2);
1461 32
                            $total['base.st'] += round($_imposto->getBase(), 2);
1462
                        } else {
1463
                            $total[$_imposto->getGrupo()] += round($_imposto->getValor(), 2);
1464
                            $total['base'] += round($_imposto->getBase(), 2);
1465
                        }
1466 32
                        $fundo = $_imposto->getFundo();
1467
                        // a ordem de comparação importa pois uma classe estende da outra
1468 32
                        if ($fundo instanceof \NFe\Entity\Imposto\Fundo\Retido) {
1469 32
                            $total['fundo.retido.st'] += round($fundo->getTotal(), 2);
1470
                        } elseif ($fundo instanceof \NFe\Entity\Imposto\Fundo\Substituido) {
1471
                            $total['fundo.st'] += round($fundo->getTotal(), 2);
1472
                        } elseif ($fundo instanceof \NFe\Entity\Imposto\Fundo\Base) {
1473
                            $total['fundo'] += round($fundo->getTotal(), 2);
1474
                        }
1475 32
                        break;
1476
                    default:
1477 32
                        $total[$_imposto->getGrupo()] += round($_imposto->getValor(), 2);
1478
                }
1479
            }
1480
        }
1481 32
        $produtos = round($total['produtos'], 2) - round($total['desconto'], 2);
1482 32
        $servicos = round($total['frete'], 2) + round($total['seguro'], 2) + round($total['despesas'], 2);
1483 32
        $impostos = round($total['ii'], 2) + round($total['ipi'], 2) + round($total['icms.st'], 2);
1484 32
        $impostos = $impostos - round($total['desoneracao'], 2);
1485 32
        $total['nota'] = $produtos + $servicos + $impostos;
1486 32
        return $total;
1487
    }
1488
1489 32
    private function getNodeTotal($name = null)
1490
    {
1491 32
        $dom = new \DOMDocument('1.0', 'UTF-8');
1492 32
        $element = $dom->createElement(is_null($name)?'total':$name);
1493
1494
        // Totais referentes ao ICMS
1495 32
        $total = $this->getTotais();
1496 32
        $icms = $dom->createElement('ICMSTot');
1497 32
        Util::appendNode($icms, 'vBC', Util::toCurrency($total['base']));
1498 32
        Util::appendNode($icms, 'vICMS', Util::toCurrency($total['icms']));
1499 32
        Util::appendNode($icms, 'vICMSDeson', Util::toCurrency($total['desoneracao']));
1500 32
        Util::appendNode($icms, 'vFCP', Util::toCurrency($total['fundo']));
1501 32
        Util::appendNode($icms, 'vBCST', Util::toCurrency($total['base.st']));
1502 32
        Util::appendNode($icms, 'vST', Util::toCurrency($total['icms.st']));
1503 32
        Util::appendNode($icms, 'vFCPST', Util::toCurrency($total['fundo.st']));
1504 32
        Util::appendNode($icms, 'vFCPSTRet', Util::toCurrency($total['fundo.retido.st']));
1505 32
        Util::appendNode($icms, 'vProd', Util::toCurrency($total['produtos']));
1506 32
        Util::appendNode($icms, 'vFrete', Util::toCurrency($total['frete']));
1507 32
        Util::appendNode($icms, 'vSeg', Util::toCurrency($total['seguro']));
1508 32
        Util::appendNode($icms, 'vDesc', Util::toCurrency($total['desconto']));
1509 32
        Util::appendNode($icms, 'vII', Util::toCurrency($total['ii']));
1510 32
        Util::appendNode($icms, 'vIPI', Util::toCurrency($total['ipi']));
1511 32
        Util::appendNode($icms, 'vIPIDevol', Util::toCurrency($total['ipi.devolvido']));
1512 32
        Util::appendNode($icms, 'vPIS', Util::toCurrency($total['pis']));
1513 32
        Util::appendNode($icms, 'vCOFINS', Util::toCurrency($total['cofins']));
1514 32
        Util::appendNode($icms, 'vOutro', Util::toCurrency($total['despesas']));
1515 32
        Util::appendNode($icms, 'vNF', Util::toCurrency($total['nota']));
1516 32
        Util::appendNode($icms, 'vTotTrib', Util::toCurrency($total['tributos']));
1517 32
        $element->appendChild($icms);
1518 32
        $this->setTotal(new Total($total));
1519 32
        $this->getTotal()->setProdutos($total['produtos']);
1520
1521
        // TODO: Totais referentes ao ISSQN
1522
1523
        // TODO: Retenção de Tributos Federais
1524 32
        return $element;
1525
    }
1526
1527 32
    public function getNode($name = null)
0 ignored issues
show
Complexity introduced by
This operation has 90720 execution paths which exceeds the configured maximum of 200.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

You can also find more information in the “Code” section of your repository.

Loading history...
1528
    {
1529 32
        $this->getEmitente()->getEndereco()->checkCodigos();
1530 32
        $this->setID($this->gerarID());
1531 32
        $this->setDigitoVerificador(substr($this->getID(), -1, 1));
1532
1533 32
        $dom = new \DOMDocument('1.0', 'UTF-8');
1534 32
        $element = $dom->createElement(is_null($name)?'NFe':$name);
1535 32
        $element->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', self::PORTAL);
1536
1537 32
        $info = $dom->createElement('infNFe');
1538 32
        $id = $dom->createAttribute('Id');
1539 32
        $id->value = $this->getID(true);
1540 32
        $info->appendChild($id);
1541 32
        $versao = $dom->createAttribute('versao');
1542 32
        $versao->value = self::VERSAO;
1543 32
        $info->appendChild($versao);
1544
1545 32
        $municipio = $this->getEmitente()->getEndereco()->getMunicipio();
1546 32
        $estado = $municipio->getEstado();
1547 32
        $ident = $dom->createElement('ide');
1548 32
        Util::appendNode($ident, 'cUF', $estado->getCodigo(true));
1549 32
        Util::appendNode($ident, 'cNF', $this->getCodigo(true));
1550 32
        Util::appendNode($ident, 'natOp', $this->getNatureza(true));
1551 32
        Util::appendNode($ident, 'mod', $this->getModelo(true));
1552 32
        Util::appendNode($ident, 'serie', $this->getSerie(true));
1553 32
        Util::appendNode($ident, 'nNF', $this->getNumero(true));
1554 32
        Util::appendNode($ident, 'dhEmi', $this->getDataEmissao(true));
1555 32
        Util::appendNode($ident, 'tpNF', $this->getTipo(true));
1556 32
        Util::appendNode($ident, 'idDest', $this->getDestino(true));
1557 32
        Util::appendNode($ident, 'cMunFG', $municipio->getCodigo(true));
1558 32
        Util::appendNode($ident, 'tpImp', $this->getFormato(true));
1559 32
        Util::appendNode($ident, 'tpEmis', $this->getEmissao(true));
1560 32
        Util::appendNode($ident, 'cDV', $this->getDigitoVerificador(true));
1561 32
        Util::appendNode($ident, 'tpAmb', $this->getAmbiente(true));
1562 32
        Util::appendNode($ident, 'finNFe', $this->getFinalidade(true));
1563 32
        Util::appendNode($ident, 'indFinal', $this->getConsumidorFinal(true));
1564 32
        Util::appendNode($ident, 'indPres', $this->getPresenca(true));
1565 32
        Util::appendNode($ident, 'procEmi', 0); // emissão de NF-e com aplicativo do contribuinte
1566 32
        Util::appendNode($ident, 'verProc', self::APP_VERSAO);
1567 32
        if (!is_null($this->getDataMovimentacao())) {
1568
            Util::appendNode($ident, 'dhSaiEnt', $this->getDataMovimentacao(true));
1569
        }
1570 32
        if ($this->getEmissao() != self::EMISSAO_NORMAL) {
1571 1
            Util::appendNode($ident, 'dhCont', $this->getDataContingencia(true));
1572 1
            Util::appendNode($ident, 'xJust', $this->getJustificativa(true));
1573
        }
1574 32
        $info->appendChild($ident);
1575
1576 32
        $emitente = $this->getEmitente()->getNode();
1577 32
        $emitente = $dom->importNode($emitente, true);
1578 32
        $info->appendChild($emitente);
1579 32
        if ($this->getAmbiente() == self::AMBIENTE_HOMOLOGACAO && !is_null($this->getDestinatario())) {
1580 32
            $this->getDestinatario()->setNome('NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL');
1581
        }
1582 32
        if (!is_null($this->getDestinatario())) {
1583 32
            $destinatario = $this->getDestinatario()->getNode();
1584 32
            $destinatario = $dom->importNode($destinatario, true);
1585 32
            $info->appendChild($destinatario);
1586
        }
1587 32
        $item = 0;
1588 32
        $tributos = [];
1589 32
        $_produtos = $this->getProdutos();
1590 32
        foreach ($_produtos as $_produto) {
1591 32
            if (is_null($_produto->getItem())) {
1592 6
                $item += 1;
1593 6
                $_produto->setItem($item);
1594
            } else {
1595 28
                $item = $_produto->getItem();
1596
            }
1597 32
            if ($this->getAmbiente() == self::AMBIENTE_HOMOLOGACAO) {
1598 32
                $_produto->setDescricao('NOTA FISCAL EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL');
1599
            }
1600 32
            $produto = $_produto->getNode();
1601 32
            $produto = $dom->importNode($produto, true);
1602 32
            $info->appendChild($produto);
1603
            // Soma os tributos aproximados dos produtos
1604 32
            $imposto_info = $_produto->getImpostoInfo();
1605 32
            $tributos['info'] = $imposto_info['info'];
1606 32
            foreach ($imposto_info as $key => $value) {
1607 32
                if (!is_numeric($value)) {
1608 32
                    continue;
1609
                }
1610 32
                if (!isset($tributos[$key])) {
1611 32
                    $tributos[$key] = 0.00;
1612
                }
1613 32
                $tributos[$key] += $value;
1614
            }
1615
        }
1616 32
        $total = $this->getNodeTotal();
1617 32
        $total = $dom->importNode($total, true);
1618 32
        $info->appendChild($total);
1619 32
        $transporte = $this->getTransporte()->getNode();
1620 32
        $transporte = $dom->importNode($transporte, true);
1621 32
        $info->appendChild($transporte);
1622
        // TODO: adicionar cobrança
1623 32
        $pag = $dom->createElement('pag');
1624 32
        $_pagamentos = $this->getPagamentos();
1625 32
        foreach ($_pagamentos as $_pagamento) {
1626 31
            $pagamento = $_pagamento->getNode();
1627 31
            $pagamento = $dom->importNode($pagamento, true);
1628 31
            $pag->appendChild($pagamento);
1629
        }
1630 32
        $info->appendChild($pag);
1631 32
        $info_adic = $dom->createElement('infAdic');
1632 32
        if (!is_null($this->getAdicionais())) {
1633
            Util::appendNode($info_adic, 'infAdFisco', $this->getAdicionais(true));
1634
        }
1635
        // TODO: adicionar informações adicionais somente na NFC-e?
1636 32
        $_complemento = Produto::addNodeInformacoes($tributos, $info_adic, 'infCpl');
1637 32
        $this->getTotal()->setComplemento($_complemento);
1638 32
        if (!is_null($this->getObservacoes())) {
1639 32
            $_observacoes = $this->getObservacoes();
1640 32
            foreach ($_observacoes as $_observacao) {
0 ignored issues
show
Bug introduced by
The expression $_observacoes of type object|integer|double|string|array|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
1641 32
                $observacoes = $dom->createElement('obsCont');
1642 32
                Util::addAttribute($observacoes, 'xCampo', $_observacao['campo']);
1643 32
                Util::appendNode($observacoes, 'xTexto', $_observacao['valor']);
1644 32
                $info_adic->appendChild($observacoes);
1645
            }
1646
        }
1647 32
        if (!is_null($this->getInformacoes())) {
1648 32
            $_informacoes = $this->getInformacoes();
1649 32
            foreach ($_informacoes as $_informacao) {
0 ignored issues
show
Bug introduced by
The expression $_informacoes of type object|integer|double|string|array|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
1650 32
                $informacoes = $dom->createElement('obsFisco');
1651 32
                Util::addAttribute($informacoes, 'xCampo', $_informacao['campo']);
1652 32
                Util::appendNode($informacoes, 'xTexto', $_informacao['valor']);
1653 32
                $info_adic->appendChild($informacoes);
1654
            }
1655
        }
1656 32
        $info->appendChild($info_adic);
1657
        // TODO: adicionar exportação
1658
        // TODO: adicionar compra
1659
        // TODO: adicionar cana
1660 32
        $element->appendChild($info);
1661 32
        $dom->appendChild($element);
1662 32
        return $element;
1663
    }
1664
1665 27
    public function loadNode($element, $name = null)
0 ignored issues
show
Complexity introduced by
This operation has 215040 execution paths which exceeds the configured maximum of 200.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

You can also find more information in the “Code” section of your repository.

Loading history...
1666
    {
1667 27
        if (is_null($element)) {
1668
            throw new \Exception("Nota com XML mal formado ou vazio", 500);
1669
        }
1670 27
        $root = $element;
1671 27
        $name = is_null($name)?'NFe':$name;
1672 27
        if ($element->nodeName != $name) {
1673 3
            $_fields = $element->getElementsByTagName($name);
1674 3
            if ($_fields->length == 0) {
1675
                throw new \Exception('Tag "'.$name.'" não encontrada', 404);
1676
            }
1677 3
            $element = $_fields->item(0);
1678
        }
1679 27
        $_fields = $element->getElementsByTagName('infNFe');
1680 27
        if ($_fields->length > 0) {
1681 27
            $info = $_fields->item(0);
1682
        } else {
1683
            throw new \Exception('Tag "infNFe" não encontrada', 404);
1684
        }
1685 27
        $id = $info->getAttribute('Id');
1686 27
        if (strlen($id) != 47) {
1687
            throw new \Exception('Atributo "Id" inválido, encontrado: "'.$id.'"', 500);
1688
        }
1689 27
        $this->setID(substr($id, 3));
1690 27
        $_fields = $info->getElementsByTagName('ide');
1691 27
        if ($_fields->length > 0) {
1692 27
            $ident = $_fields->item(0);
1693
        } else {
1694
            throw new \Exception('Tag "ide" não encontrada', 404);
1695
        }
1696 27
        $emitente = new Emitente();
1697 27
        $emitente->getEndereco()->getMunicipio()->getEstado()->setCodigo(
1698 27
            Util::loadNode(
1699 27
                $ident,
1700 27
                'cUF',
1701 27
                'Tag "cUF" do campo "Codigo IBGE da UF" não encontrada'
1702
            )
1703
        );
1704 27
        $this->setCodigo(
1705 27
            Util::loadNode(
1706 27
                $ident,
1707 27
                'cNF',
1708 27
                'Tag "cNF" do campo "Codigo" não encontrada'
1709
            )
1710
        );
1711 27
        $this->setNatureza(
1712 27
            Util::loadNode(
1713 27
                $ident,
1714 27
                'natOp',
1715 27
                'Tag "natOp" do campo "Natureza" não encontrada'
1716
            )
1717
        );
1718 27
        $this->setModelo(
1719 27
            Util::loadNode(
1720 27
                $ident,
1721 27
                'mod',
1722 27
                'Tag "mod" do campo "Modelo" não encontrada'
1723
            )
1724
        );
1725 27
        $this->setSerie(
1726 27
            Util::loadNode(
1727 27
                $ident,
1728 27
                'serie',
1729 27
                'Tag "serie" do campo "Serie" não encontrada'
1730
            )
1731
        );
1732 27
        $this->setNumero(
1733 27
            Util::loadNode(
1734 27
                $ident,
1735 27
                'nNF',
1736 27
                'Tag "nNF" do campo "Numero" não encontrada'
1737
            )
1738
        );
1739 27
        $this->setDataEmissao(
1740 27
            Util::loadNode(
1741 27
                $ident,
1742 27
                'dhEmi',
1743 27
                'Tag "dhEmi" do campo "DataEmissao" não encontrada'
1744
            )
1745
        );
1746 27
        $this->setTipo(
1747 27
            Util::loadNode(
1748 27
                $ident,
1749 27
                'tpNF',
1750 27
                'Tag "tpNF" do campo "Tipo" não encontrada'
1751
            )
1752
        );
1753 27
        $this->setDestino(
1754 27
            Util::loadNode(
1755 27
                $ident,
1756 27
                'idDest',
1757 27
                'Tag "idDest" do campo "Destino" não encontrada'
1758
            )
1759
        );
1760 27
        $emitente->getEndereco()->getMunicipio()->setCodigo(
1761 27
            Util::loadNode(
1762 27
                $ident,
1763 27
                'cMunFG',
1764 27
                'Tag "cMunFG" do campo "Codigo IBGE do município" não encontrada'
1765
            )
1766
        );
1767 27
        $this->setDataMovimentacao(Util::loadNode($ident, 'dhSaiEnt'));
1768 27
        $this->setFormato(
1769 27
            Util::loadNode(
1770 27
                $ident,
1771 27
                'tpImp',
1772 27
                'Tag "tpImp" do campo "Formato" não encontrada'
1773
            )
1774
        );
1775 27
        $this->setEmissao(
1776 27
            Util::loadNode(
1777 27
                $ident,
1778 27
                'tpEmis',
1779 27
                'Tag "tpEmis" do campo "Emissao" não encontrada'
1780
            )
1781
        );
1782 27
        $this->setDigitoVerificador(
1783 27
            Util::loadNode(
1784 27
                $ident,
1785 27
                'cDV',
1786 27
                'Tag "cDV" do campo "DigitoVerificador" não encontrada'
1787
            )
1788
        );
1789 27
        $this->setAmbiente(
1790 27
            Util::loadNode(
1791 27
                $ident,
1792 27
                'tpAmb',
1793 27
                'Tag "tpAmb" do campo "Ambiente" não encontrada'
1794
            )
1795
        );
1796 27
        $this->setFinalidade(
1797 27
            Util::loadNode(
1798 27
                $ident,
1799 27
                'finNFe',
1800 27
                'Tag "finNFe" do campo "Finalidade" não encontrada'
1801
            )
1802
        );
1803 27
        $this->setConsumidorFinal(
1804 27
            Util::loadNode(
1805 27
                $ident,
1806 27
                'indFinal',
1807 27
                'Tag "indFinal" do campo "ConsumidorFinal" não encontrada'
1808
            )
1809
        );
1810 27
        $this->setPresenca(
1811 27
            Util::loadNode(
1812 27
                $ident,
1813 27
                'indPres',
1814 27
                'Tag "indPres" do campo "Presenca" não encontrada'
1815
            )
1816
        );
1817 27
        $this->setDataContingencia(Util::loadNode($ident, 'dhCont'));
1818 27
        $this->setJustificativa(Util::loadNode($ident, 'xJust'));
1819 27
        $emitente->loadNode(
1820 27
            Util::findNode(
1821 27
                $info,
1822 27
                'emit',
1823 27
                'Tag "emit" do objeto "Emitente" não encontrada'
1824
            ),
1825 27
            'emit'
1826
        );
1827 27
        $this->setEmitente($emitente);
1828 27
        $_fields = $info->getElementsByTagName('dest');
1829 27
        $destinatario = null;
1830 27
        if ($_fields->length > 0) {
1831 27
            $destinatario = new Destinatario();
1832 27
            $destinatario->loadNode($_fields->item(0), 'dest');
1833
        }
1834 27
        $this->setDestinatario($destinatario);
1835 27
        $produtos = [];
1836 27
        $_items = $info->getElementsByTagName('det');
1837 27
        foreach ($_items as $_item) {
1838 27
            $produto = new Produto();
1839 27
            $produto->loadNode($_item, 'det');
1840 27
            $produtos[] = $produto;
1841
        }
1842 27
        $this->setProdutos($produtos);
1843 27
        $_fields = $info->getElementsByTagName('transp');
1844 27
        $transporte = null;
1845 27
        if ($_fields->length > 0) {
1846 27
            $transporte = new Transporte();
1847 27
            $transporte->loadNode($_fields->item(0), 'transp');
1848
        }
1849 27
        $this->setTransporte($transporte);
1850 27
        $pagamentos = [];
1851 27
        $_items = $info->getElementsByTagName('pag');
1852 27
        foreach ($_items as $_item) {
1853 27
            $_det_items = $_item->getElementsByTagName('detPag');
1854 27
            foreach ($_det_items as $_det_item) {
1855 27
                $pagamento = new Pagamento();
1856 27
                $pagamento->loadNode($_det_item, 'detPag');
1857 27
                $pagamentos[] = $pagamento;
1858
            }
1859 27
            if (Util::nodeExists($_item, 'vTroco')) {
1860 2
                $pagamento = new Pagamento();
1861 2
                $pagamento->loadNode($_item, 'vTroco');
1862 2
                if ($pagamento->getValor() < 0) {
1863 27
                    $pagamentos[] = $pagamento;
1864
                }
1865
            }
1866
        }
1867 27
        $this->setPagamentos($pagamentos);
1868 27
        $_fields = $info->getElementsByTagName('total');
1869 27
        if ($_fields->length > 0) {
1870 27
            $total = new Total();
1871 27
            $total->loadNode($_fields->item(0), 'total');
1872 27
            $total->setComplemento(Util::loadNode($info, 'infCpl'));
1873
        } else {
1874
            throw new \Exception('Tag "total" do objeto "Total" não encontrada na Nota', 404);
1875
        }
1876 27
        $this->setTotal($total);
1877 27
        $this->setAdicionais(Util::loadNode($info, 'infAdFisco'));
1878 27
        $observacoes = [];
1879 27
        $_items = $info->getElementsByTagName('obsCont');
1880 27
        foreach ($_items as $_item) {
1881
            $observacao = [
1882 27
                'campo' => $_item->getAttribute('xCampo'),
1883 27
                'valor' => Util::loadNode(
1884 27
                    $_item,
1885 27
                    'xTexto',
1886 27
                    'Tag "xTexto" do campo "Observação" não encontrada'
1887
                )
1888
            ];
1889 27
            $observacoes[] = $observacao;
1890
        }
1891 27
        $this->setObservacoes($observacoes);
1892 27
        $informacoes = [];
1893 27
        $_items = $info->getElementsByTagName('obsFisco');
1894 27
        foreach ($_items as $_item) {
1895
            $informacao = [
1896 27
                'campo' => $_item->getAttribute('xCampo'),
1897 27
                'valor' => Util::loadNode(
1898 27
                    $_item,
1899 27
                    'xTexto',
1900 27
                    'Tag "xTexto" do campo "Informação" não encontrada'
1901
                )
1902
            ];
1903 27
            $informacoes[] = $informacao;
1904
        }
1905 27
        $this->setInformacoes($informacoes);
1906
1907 27
        $_fields = $root->getElementsByTagName('protNFe');
1908 27
        $protocolo = null;
1909 27
        if ($_fields->length > 0) {
1910 2
            $protocolo = new Protocolo();
1911 2
            $protocolo->loadNode($_fields->item(0), 'infProt');
1912
        }
1913 27
        $this->setProtocolo($protocolo);
1914 27
        return $element;
1915
    }
1916
1917
    /**
1918
     * Carrega um arquivo XML e preenche a nota com as informações dele
1919
     * @param  string $filename caminho do arquivo
1920
     * @return DOMDocument      objeto do documento carregado
1921
     */
1922 27
    public function load($filename)
1923
    {
1924 27
        $dom = new \DOMDocument();
1925 27
        if (!file_exists($filename)) {
1926 1
            throw new \Exception('Arquivo XML "'.$filename.'" não encontrado', 404);
1927
        }
1928 26
        $dom->load($filename);
1929 26
        $this->loadNode($dom->documentElement);
1930 26
        return $dom;
1931
    }
1932
1933
    /**
1934
     * Assina o XML com a assinatura eletrônica do tipo A1
1935
     */
1936 29
    public function assinar($dom = null)
1937
    {
1938 29
        if (is_null($dom)) {
1939 26
            $xml = $this->getNode();
1940 26
            $dom = $xml->ownerDocument;
1941
        }
1942 29
        $config = SEFAZ::getInstance()->getConfiguracao();
1943 29
        $config->verificaValidadeCertificado();
1944
1945 29
        $adapter = new XmlseclibsAdapter();
1946 29
        $adapter->setPrivateKey($config->getChavePrivada());
0 ignored issues
show
Deprecated Code introduced by
The method NFe\Common\Configuracao::getChavePrivada() has been deprecated with message: Use getCertificado()->getChavePrivada

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1947 29
        $adapter->setPublicKey($config->getChavePublica());
0 ignored issues
show
Deprecated Code introduced by
The method NFe\Common\Configuracao::getChavePublica() has been deprecated with message: Use getCertificado()->getChavePublica

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1948 29
        $adapter->addTransform(AdapterInterface::ENVELOPED);
1949 29
        $adapter->addTransform(AdapterInterface::XML_C14N);
1950 29
        $adapter->sign($dom, 'infNFe');
1951 29
        return $dom;
1952
    }
1953
1954
    /**
1955
     * Valida o documento após assinar
1956
     */
1957 27
    public function validar($dom)
1958
    {
1959 27
        $dom->loadXML($dom->saveXML());
1960 27
        $xsd_path = __DIR__ . '/schema';
1961 27
        if (is_null($this->getProtocolo())) {
1962 27
            $xsd_file = $xsd_path . '/nfe_v'.self::VERSAO.'.xsd';
1963
        } else {
1964
            $xsd_file = $xsd_path . '/procNFe_v'.self::VERSAO.'.xsd';
1965
        }
1966 27
        if (!file_exists($xsd_file)) {
1967
            throw new \Exception(sprintf('O arquivo "%s" de esquema XSD não existe!', $xsd_file), 404);
1968
        }
1969
        // Enable user error handling
1970 27
        $save = libxml_use_internal_errors(true);
1971 27
        if ($dom->schemaValidate($xsd_file)) {
1972 27
            libxml_use_internal_errors($save);
1973 27
            return $dom;
1974
        }
1975
        $msg = [];
1976
        $errors = libxml_get_errors();
1977
        foreach ($errors as $error) {
1978
            $msg[] = 'Não foi possível validar o XML: '.$error->message;
1979
        }
1980
        libxml_clear_errors();
1981
        libxml_use_internal_errors($save);
1982
        throw new ValidationException($msg);
1983
    }
1984
1985
    /**
1986
     * Adiciona o protocolo no XML da nota
1987
     */
1988 3
    public function addProtocolo($dom)
1989
    {
1990 3
        if (is_null($this->getProtocolo())) {
1991
            throw new \Exception('O protocolo não foi informado na nota "'.$this->getID().'"', 404);
1992
        }
1993 3
        $notae = $dom->getElementsByTagName('NFe')->item(0);
1994
        // Corrige xmlns:default
1995 3
        $notae_xml = $dom->saveXML($notae);
1996
1997 3
        $element = $dom->createElement('nfeProc');
1998 3
        $element->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', self::PORTAL);
1999 3
        $versao = $dom->createAttribute('versao');
2000 3
        $versao->value = self::VERSAO;
2001 3
        $element->appendChild($versao);
2002 3
        $dom->removeChild($notae);
2003
        // Corrige xmlns:default
2004 3
        $notae = $dom->createElement('NFe', 0);
2005
2006 3
        $element->appendChild($notae);
2007 3
        $info = $this->getProtocolo()->getNode();
2008 3
        $info = $dom->importNode($info, true);
2009 3
        $element->appendChild($info);
2010 3
        $dom->appendChild($element);
2011
        // Corrige xmlns:default
2012 3
        $xml = $dom->saveXML();
2013 3
        $xml = str_replace('<NFe>0</NFe>', $notae_xml, $xml);
2014 3
        $dom->loadXML($xml);
2015
2016 3
        return $dom;
2017
    }
2018
}
2019