module BrNfe
	module Product
		class NotaFiscal  < BrNfe::ActiveModelBase
			# include BrNfe::Association::HaveCondicaoPagamento

			# Identificação do emitente da NF-e
			# Versão do XML
			attr_accessor :versao

			# Identificação do emitente da NF-e
			#
			# <b>Type:     </b> _BrNfe.emitente_product_class
			# <b>Required: </b> _Yes_
			# <b>tag:      </b> emit
			#
			has_one :emitente, 'BrNfe.emitente_product_class', null: false
			alias_attribute :emit, :emitente

			# Identificação do Destinatário da NF-e
			#  Grupo obrigatório para a NF-e (modelo 55)
			#
			# <b>Type:     </b> _BrNfe.destinatario_product_class_
			# <b>Required: </b> _Yes_ (No if modelo_nf == 65)
			# <b>tag:      </b> dest
			#
			has_one :destinatario, 'BrNfe.destinatario_product_class', null: false
			alias_attribute :dest, :destinatario

			# Código do Tipo de Emissão da NF-e
			#  ✓ 1=Emissão normal (não em contingência);
			#  ✓ 6=Contingência SVC-AN (SEFAZ Virtual de Contingência do AN);
			#  ✓ 7=Contingência SVC-RS (SEFAZ Virtual de Contingência do RS);
			#  ✓ 9=Contingência off-line da NFC-e (as demais opções de contingência são válidas
			#      também para a NFC-e).
			#  Para a NFC-e somente estão disponíveis e são válidas as opções de contingência 5 e 9.
			#
			# <b>Type:     </b> _Number_
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _1_
			# <b>Length:   </b> _1_
			# <b>tag:      </b> tpEmis
			#
			attr_accessor :codigo_tipo_emissao
			alias_attribute :tpEmis, :codigo_tipo_emissao


			attr_accessor :chave_de_acesso

			def chave_de_acesso_dv
				chave_de_acesso[-1]
			end
			def chave_de_acesso_sem_dv
				chave_de_acesso[0..-2]
			end
			def chave_de_acesso
				@chave_de_acesso ||= gerar_chave_de_acesso!
			end


			# Código numérico que compõe a Chave de Acesso. Número aleatório gerado pelo
			# emitente para cada NF-e para evitar acessos indevidos da NF-e.
			# Resumo: É um código controlado pelo sistema. Pode por exemplo ser
			#        utilizado o ID da tabela da nota fiscal.
			#
			# <b>Type:     </b> _Number_
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _nil_
			# <b>Length:  </b> _max: 8_
			# <b>tag:      </b> cNF
			#
			attr_accessor :codigo_nf
			alias_attribute :cNF, :codigo_nf


			# Série do Documento Fiscal, preencher com zeros na hipótese
			# de a NF-e não possuir série. (v2.0)
			# Série 890-899: uso exclusivo para emissão de NF-e avulsa, pelo
			#    contribuinte com seu certificado digital, através do site do Fisco
			#    (procEmi=2). (v2.0)
			# Serie 900-999: uso exclusivo de NF-e emitidas no SCAN. (v2.0)
			#
			# <b>Type:     </b> _Number_
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _nil_
			# <b>Length:   </b> _max: 3_
			# <b>tag:      </b> serie
			#
			attr_accessor :serie

			# Número do Documento Fiscal.
			# Número da nota fiscal De fato
			#
			# <b>Type:     </b> _Number_
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _nil_
			# <b>Length:   </b> _max: 9_
			# <b>tag:      </b> nNF
			#
			attr_accessor :numero_nf
			alias_attribute :nNF, :numero_nf

			# Descrição da Natureza da Operação
			# Informar a natureza da operação de que decorrer a saída ou a
			# entrada, tais como: venda, compra, transferência, devolução,
			# importação, consignação, remessa (para fins de demonstração,
			# de industrialização ou outra), conforme previsto na alínea 'i',
			# inciso I, art. 19 do CONVÊNIO S/No, de 15 de dezembro de
			# 1970.
			#
			# <b>Type:     </b> _String_
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _'Venda'_
			# <b>tag:      </b> natOp
			#
			attr_accessor :natureza_operacao
			alias_attribute :natOp, :natureza_operacao

			# Indicador da forma de pagamento
			# 0=Pagamento à vista; (Default)
			# 1=Pagamento a prazo;
			# 2=Outros.
			#
			# <b>Type:     </b> _Number_ OR _String_
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _0_
			# <b>Length:   </b> _1_
			# <b>tag:      </b> indPag
			#
			attr_accessor :forma_pagamento
			alias_attribute :indPag, :forma_pagamento

			# Código do Modelo do Documento Fiscal
			# 55=NF-e emitida em substituição ao modelo 1 ou 1A; (Default)
			# 65=NFC-e, utilizada nas operações de venda no varejo (a critério da UF aceitar este modelo de documento).
			#
			# <b>Type:     </b> _Number_ OR _String_
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _55_
			# <b>Length:   </b> _2_
			# <b>tag:      </b> mod
			#
			attr_accessor :modelo_nf
			alias_attribute :mod, :modelo_nf

			# Data e hora de emissão do Documento Fiscal
			#
			# <b>Type:     </b> _Time_
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _Time.current_
			# <b>tag:      </b> dhEmi
			#
			attr_accessor :data_hora_emissao
			def data_hora_emissao
				convert_to_time(@data_hora_emissao)
			end
			alias_attribute :dhEmi, :data_hora_emissao

			# Data e hora de Saída ou da Entrada da Mercadoria/Produto
			# Campo não considerado para a NFC-e.
			#
			# <b>Type:     </b> _Time_
			# <b>Required: </b> _Yes_ (apenas para modelo 55)
			# <b>Default:  </b> _Time.current_
			# <b>tag:      </b> dhSaiEnt
			#
			attr_accessor :data_hora_expedicao
			def data_hora_expedicao
				convert_to_time(@data_hora_expedicao)
			end
			alias_attribute :dhSaiEnt, :data_hora_expedicao

			# Tipo de Operação
			# 0=Entrada;
			# 1=Saída (Default)
			#
			# <b>Type:     </b> _Number_ OR _String_
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _1_
			# <b>Length:   </b> _1_
			# <b>tag:      </b> tpNF
			#
			attr_accessor :tipo_operacao
			alias_attribute :tpNF, :tipo_operacao

			# Formato de Impressão do DANFE
			# 0=Sem geração de DANFE;
			# 1=DANFE normal, Retrato; (Default)
			# 2=DANFE normal, Paisagem;
			# 3=DANFE Simplificado;
			# 4=DANFE NFC-e;
			# 5=DANFE NFC-e em mensagem eletrônica (o envio de mensagem eletrônica pode
			#   ser feita de forma simultânea com a impressão do DANFE; usar o tpImp=5
			#   quando esta for a única forma de disponibilização do DANFE).
			#
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _1_
			# <b>tag:      </b> tpEmis
			#
			attr_accessor :tipo_impressao
			alias_attribute :tpEmis, :tipo_impressao

			# Finalidade de emissão da NF-e
			# 1=NF-e normal; (Default)
			# 2=NF-e complementar;
			# 3=NF-e de ajuste;
			# 4=Devolução de mercadoria.
			#
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _1_
			# <b>tag:      </b> finNFe
			#
			attr_accessor :finalidade_emissao
			alias_attribute :finNFe, :finalidade_emissao


			# Indica operação com Consumidor final
			# false=Normal;
			# true=Consumidor final;
			#
			# Preencher esse campo com true ou false
			#
			# <b>Type:     </b> _Boolean_
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _false_
			# <b>tag:      </b> indFinal
			#
			attr_accessor :consumidor_final
			def consumidor_final
				convert_to_boolean(@consumidor_final)
			end
			alias_attribute :indFinal, :consumidor_final

			# Indicador de presença do comprador no estabelecimento comercial no
			# momento da operação:
			#   0=Não se aplica (por exemplo, Nota Fiscal complementar ou de ajuste);
			#   1=Operação presencial;
			#   2=Operação não presencial, pela Internet;
			#   3=Operação não presencial, Teleatendimento;
			#   4=NFC-e em operação com entrega a domicílio;
			#   9=Operação não presencial, outros. (Default)
			#
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _9_
			# <b>tag:      </b> indPres
			#
			attr_accessor :presenca_comprador
			alias_attribute :indPres, :presenca_comprador

			# Processo de emissão da NF-e
			# 0=Emissão de NF-e com aplicativo do contribuinte; (Default)
			# 1=Emissão de NF-e avulsa pelo Fisco;
			# 2=Emissão de NF-e avulsa, pelo contribuinte com seu certificado digital, através do site do Fisco;
			# 3=Emissão NF-e pelo contribuinte com aplicativo fornecido pelo Fisco.
			#
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _0_
			# <b>tag:      </b> procEmi
			#
			attr_accessor :processo_emissao
			alias_attribute :procEmi, :processo_emissao

			# Versão do Processo de emissão da NF-e
			# Informar a versão do aplicativo emissor de NF-e.
			#
			# <b>Required: </b> _Yes_
			# <b>Default:  </b> _0_
			# <b>tag:      </b> verProc
			#
			attr_accessor :versao_aplicativo
			alias_attribute :verProc, :versao_aplicativo

			# Chave de acesso de notas referenciadas. (por enquanto aceita apenas a chave de acesso)
			#
			# <b>Type:     </b> _Array_
			# <b>Required: </b> _No_
			# <b>Default:  </b> _[]_
			# <b>tag:      </b> NFref > refNFe
			#
			attr_accessor :notas_referenciadas
			def notas_referenciadas
				@notas_referenciadas = [@notas_referenciadas].flatten unless @notas_referenciadas.is_a?(Array)
				@notas_referenciadas.compact!
				@notas_referenciadas
			end
			alias_attribute :NFref, :notas_referenciadas

			# Endereço da retirada da mercadoria
			#
			# <b>Type:     </b> _BrNfe.endereco_class_
			# <b>Required: </b> _No_
			# <b>Default:  </b> _nil_
			# <b>tag:      </b> retirada
			#
			has_one :endereco_retirada, 'BrNfe.endereco_class'
			alias_attribute :retirada, :endereco_retirada

			# CPF ou CNPJ do local de retirada da mercadoria.
			# Só é obrigatório se o endereco_retirada for preenchido
			#
			# <b>Type:     </b> _String_
			# <b>Required: </b> _No_ (_Yes_ if endereco_retirada is present)
			# <b>Default:  </b> _nil_
			# <b>tag:      </b> retirada/CPF ou retirada/CNPJ
			#
			attr_accessor :endereco_retirada_cpf_cnpj
			def endereco_retirada_cpf_cnpj
				return unless @endereco_retirada_cpf_cnpj.present?
				BrNfe::Helper::CpfCnpj.new(@endereco_retirada_cpf_cnpj).sem_formatacao
			end


			# Endereço da entrega da mercadoria
			# Informar apenas quando for diferente do endereço do destinatário
			#
			# <b>Type:     </b> _BrNfe.endereco_class_
			# <b>Required: </b> _No_
			# <b>Default:  </b> _nil_
			# <b>tag:      </b> entrega
			#
			has_one :endereco_entrega, 'BrNfe.endereco_class'
			alias_attribute :entrega, :endereco_entrega

			# CPF ou CNPJ do local de entrega da mercadoria.
			# Só é obrigatório se o endereco_entrega for preenchido
			#
			# <b>Type:     </b> _String_
			# <b>Required: </b> _No_ (_Yes_ if endereco_entrega is present)
			# <b>Default:  </b> _nil_
			# <b>tag:      </b> entrega/CPF ou entrega/CNPJ
			#
			attr_accessor :endereco_entrega_cpf_cnpj
			def endereco_entrega_cpf_cnpj
				return unless @endereco_entrega_cpf_cnpj.present?
				BrNfe::Helper::CpfCnpj.new(@endereco_entrega_cpf_cnpj).sem_formatacao
			end

			# CPF ou CNPJ das pessoas que estão autorizadas a fazer o download do XML da NF-e.
			# Deve ser um Array com os CPF's e CNPJ's válidos.
			#
			# <b>Type:     </b> _Array_
			# <b>Required: </b> _No_
			# <b>Default:  </b> _[]_
			# <b>tag:      </b> autXML
			#
			attr_accessor :autorizados_download_xml
			def autorizados_download_xml
				@autorizados_download_xml = [@autorizados_download_xml].flatten unless @autorizados_download_xml.is_a?(Array)
				@autorizados_download_xml.compact!
				@autorizados_download_xml
			end
			alias_attribute :autXML, :autorizados_download_xml

			# Transporte da mercadoria
			# Informações referentes ao transporte da mercadoria.
			#
			# <b>Type:     </b> _BrNfe.transporte_product_class_
			# <b>Required: </b> _No_
			# <b>Default:  </b> _nil_
			# <b>tag:      </b> transp
			#
			has_one :transporte, 'BrNfe.transporte_product_class'
			alias_attribute :transp, :transporte

			# Dados da cobrança da NF-e
			# Fatura e Duplicatas da Nota Fiscal
			# Utilizado para especificar os dados da fatura e das duplicatas.
			# No caso desta GEM, a fatura contém o Array de duplicatas.
			# Ex:
			#    self.fatura.duplicatas
			#    => [#<::Cobranca::Duplicata:0x00000006302b80 ...>, #<::Cobranca::Duplicata:0x00000046465bw4 ...>]
			#
			# <b>Type:     </b> _BrNfe.fatura_product_class_
			# <b>Required: </b> _No_
			# <b>Default:  </b> _nil_
			# <b>Exemplo:  </b> _BrNfe::Product::Nfe::Cobranca::Fatura.new(numero_fatura: 'FAT646498'...)_
			# <b>tag:      </b> cobr
			#
			has_one :fatura, 'BrNfe.fatura_product_class'
			alias_attribute :cobranca, :fatura
			alias_attribute :cobr, :fatura

			# Array com as informações dos pagamentos
			# IMPORTANTE: Utilizado apenas para NFC-e
			#
			# Pode ser adicionado os dados dos pagamentos em forma de `Hash`
			# ou o próprio objeto da classe BrNfe.pagamento_product_class.
			#
			# Exemplo com Hash:
			#    self.pagamentos = [{forma_pagamento: '1', total: 100.00, ...},{forma_pagamento: '2', total: 200.00, ...}]
			#    self.pagamentos << {forma_pagamento: '3', total: 300.00, ...}
			#    self.pagamentos << {forma_pagamento: '4', total: 400.00, ...}
			#
			# Exemplo com Objetos:
			#    self.pagamentos = [BrNfe::Product::Nfe::Cobranca::Pagamento.new({forma_pagamento: '5', total: 500.00, ...}),{forma_pagamento: '11', total: 600.00, ...}]
			#    self.pagamentos << BrNfe::Product::Nfe::Cobranca::Pagamento.new({forma_pagamento: '10', total: 700.00, ...})
			#    self.pagamentos << {forma_pagamento: '12', total: 800.00, ...}
			#
			# Sempre vai retornar um Array de objetos da class configurada em `BrNfe.pagamento_product_class`
			#
			# <b>Tipo:    </b> _BrNfe.pagamento_product_class (BrNfe::Product::Nfe::Cobranca::Pagamento)_
			# <b>Min:     </b> _0_
			# <b>Max:     </b> _100_
			# <b>Default: </b> _[]_
			# <b>tag:     </b> pag
			#
			has_many :pagamentos, 'BrNfe.pagamento_product_class'
			alias_attribute :pag, :pagamentos

			# DETALHAMENTO DE PRODUTOS E SERVIÇOS
			#
			# <b>Type:    </b> _BrNfe.item_product_class (BrNfe::Product::Nfe::Item)_
			# <b>Default: </b> _[]_
			# <b>Length:  </b> _min: 1, max: 990_
			# <b>tag:     </b> det
			#
			has_many :itens, 'BrNfe.item_product_class'
			alias_attribute :det, :itens

			##########################################################################
			#########################  TOTAIS PARA PRODUTOS  #########################
				# BASE DE CÁLCULO DO ICMS
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vBC
				#
				attr_accessor :total_icms_base_calculo
				alias_attribute :ICMSTot_vBC, :total_icms_base_calculo
				validates :total_icms_base_calculo, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO ICMS
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vICMS
				#
				attr_accessor :total_icms
				alias_attribute :ICMSTot_vICMS, :total_icms
				validates :total_icms, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO ICMS DESONERADO
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vICMSDeson
				#
				attr_accessor :total_icms_desonerado
				alias_attribute :ICMSTot_vICMSDeson, :total_icms_desonerado
				validates :total_icms_desonerado, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO ICMS RELATIVO FUNDO DE COMBATE À POBREZA(FCP)
				# DA UF DE DESTINO
				#   Valor total do ICMS relativo ao Fundo de Combate à Pobreza
				#   (FCP) para a UF de destino.
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _108.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vFCPUFDest
				#
				attr_accessor :total_icms_fcp_uf_destino
				alias_attribute :ICMSTot_vFCPUFDest, :total_icms_fcp_uf_destino
				validates :total_icms_fcp_uf_destino, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO ICMS INTERESTADUAL PARA A UF DE DESTINO
				#   Valor total do ICMS Interestadual para a UF de destino, já
				#   considerando o valor do ICMS relativo ao Fundo de Combate à
				#   Pobreza naquela UF
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _108.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vICMSUFDest
				#
				attr_accessor :total_icms_uf_destino
				alias_attribute :ICMSTot_vICMSUFDest, :total_icms_uf_destino
				validates :total_icms_uf_destino, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO ICMS INTERESTADUAL PARA A UF DO REMETENTE
				#   Valor total do ICMS Interestadual para a UF do remetente.
				#   Nota: A partir de 2019, este valor será zero.
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _108.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vICMSUFRemet
				#
				attr_accessor :total_icms_uf_origem
				alias_attribute :ICMSTot_vICMSUFRemet, :total_icms_uf_origem
				validates :total_icms_uf_origem, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# BASE DE CÁLCULO DO ICMS ST
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vBCST
				#
				attr_accessor :total_icms_base_calculo_st
				alias_attribute :ICMSTot_vBCST, :total_icms_base_calculo_st
				validates :total_icms_base_calculo_st, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO ICMS ST
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vST
				#
				attr_accessor :total_icms_st
				alias_attribute :ICMSTot_vST, :total_icms_st
				validates :total_icms_st, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DOS PRODUTOS E SERVIÇOS
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vProd
				#
				attr_accessor :total_produtos
				alias_attribute :ICMSTot_vProd, :total_produtos
				validates :total_produtos, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO FRETE
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vFrete
				#
				attr_accessor :total_frete
				alias_attribute :ICMSTot_vFrete, :total_frete
				validates :total_frete, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO SEGURO
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vSeg
				#
				attr_accessor :total_seguro
				alias_attribute :ICMSTot_vSeg, :total_seguro
				validates :total_seguro, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO DESCONTO
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vDesc
				#
				attr_accessor :total_desconto
				alias_attribute :ICMSTot_vDesc, :total_desconto
				validates :total_desconto, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO II
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vII
				#
				attr_accessor :total_imposto_importacao
				alias_attribute :ICMSTot_vII, :total_imposto_importacao
				validates :total_imposto_importacao, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO IPI
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vIPI
				#
				attr_accessor :total_ipi
				alias_attribute :ICMSTot_vIPI, :total_ipi
				validates :total_ipi, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO PIS
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vPIS
				#
				attr_accessor :total_pis
				alias_attribute :ICMSTot_vPIS, :total_pis
				validates :total_pis, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO COFINS
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vCOFINS
				#
				attr_accessor :total_cofins
				alias_attribute :ICMSTot_vCOFINS, :total_cofins
				validates :total_cofins, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# OUTRAS DESPESAS ACESSÓRIAS
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vOutro
				#
				attr_accessor :total_outras_despesas
				alias_attribute :ICMSTot_vOutro, :total_outras_despesas
				validates :total_outras_despesas, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DA NF-E
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vNF
				#
				attr_accessor :total_nf
				alias_attribute :ICMSTot_vNF, :total_nf
				validates :total_nf, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR APROXIMADO TOTAL DE TRIBUTOS FEDERAIS, ESTADUAIS E MUNICIPAIS.
				# (NT 2013/003)
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ICMSTot/vTotTrib
				#
				attr_accessor :total_tributos
				alias_attribute :ICMSTot_vTotTrib, :total_tributos
				validates :total_tributos, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true
			##########################################################################
			#########################  TOTAIS PARA SERVIÇOS  #########################
				# VALOR TOTAL DOS SERVIÇOS SOB NÃO-INCIDÊNCIA OU NÃO TRIBUTADOS PELO ICMS
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _Yes_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ISSQNtot/vServ
				#
				attr_accessor :total_servicos
				alias_attribute :ISSQNtot_vServ, :total_servicos
				validates :total_servicos, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL BASE DE CÁLCULO DO ISS
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ISSQNtot/vBC
				#
				attr_accessor :total_servicos_base_calculo
				alias_attribute :ISSQNtot_vBC, :total_servicos_base_calculo
				validates :total_servicos_base_calculo, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO ISS
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ISSQNtot/vISS
				#
				attr_accessor :total_servicos_iss
				alias_attribute :ISSQNtot_vISS, :total_servicos_iss
				validates :total_servicos_iss, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DO PIS SOBRE SERVIÇOS
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ISSQNtot/vPIS
				#
				attr_accessor :total_servicos_pis
				alias_attribute :ISSQNtot_vPIS, :total_servicos_pis
				validates :total_servicos_pis, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DA COFINS SOBRE SERVIÇOS
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ISSQNtot/vCOFINS
				#
				attr_accessor :total_servicos_cofins
				alias_attribute :ISSQNtot_vCOFINS, :total_servicos_cofins
				validates :total_servicos_cofins, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# DATA DA PRESTAÇÃO DO SERVIÇO
				#
				#
				# <b>Type:     </b> _Date_
				# <b>Required: </b> _Yes_ apenas se tiver algum serviço nos itens
				# <b>Default:  </b> _Date.current_
				# <b>Example:  </b> _Date.current_
				# <b>Length:   </b> _8_ YYYYMMDD
				# <b>tag:      </b> total/ISSQNtot/dCompet
				#
				attr_accessor :servicos_data_prestacao
				def servicos_data_prestacao
					convert_to_date(@servicos_data_prestacao)
				end
				alias_attribute :ISSQNtot_dCompet, :servicos_data_prestacao
				validates :servicos_data_prestacao, presence: true, if: :has_any_service?

				# VALOR TOTAL DEDUÇÃO PARA REDUÇÃO DA BASE DE CÁLCULO
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ISSQNtot/vDeducao
				#
				attr_accessor :total_servicos_deducao
				alias_attribute :ISSQNtot_vDeducao, :total_servicos_deducao
				validates :total_servicos_deducao, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL OUTRAS RETENÇÕES DO ISSQN
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ISSQNtot/vOutro
				#
				attr_accessor :total_servicos_outras_retencoes
				alias_attribute :ISSQNtot_vOutro, :total_servicos_outras_retencoes
				validates :total_servicos_outras_retencoes, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DESCONTO INCONDICIONADO
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ISSQNtot/vDescIncond
				#
				attr_accessor :total_servicos_desconto_incondicionado
				alias_attribute :ISSQNtot_vDescIncond, :total_servicos_desconto_incondicionado
				validates :total_servicos_desconto_incondicionado, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL DESCONTO CONDICIONADO
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ISSQNtot/vDescCond
				#
				attr_accessor :total_servicos_desconto_condicionado
				alias_attribute :ISSQNtot_vDescCond, :total_servicos_desconto_condicionado
				validates :total_servicos_desconto_condicionado, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR TOTAL RETENÇÃO ISS
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/ISSQNtot/vISSRet
				#
				attr_accessor :total_servicos_iss_retido
				alias_attribute :ISSQNtot_vISSRet, :total_servicos_iss_retido
				validates :total_servicos_iss_retido, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# CÓDIGO DO REGIME ESPECIAL DE TRIBUTAÇÃO
				#  1 = Microempresa Municipal;
				#  2 = Estimativa;
				#  3 = Sociedade de Profissionais;
				#  4 = Cooperativa;
				#  5 = Microempresário Individual (MEI);
				#  6 = Microempresário e Empresa de Pequeno Porte (ME/EPP)
				#
				# <b>Type:     </b> _Number_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _2_
				# <b>Default:  </b> _1_
				# <b>Length:   </b> _1_
				# <b>tag:      </b> total/ISSQNtot/cRegTrib
				#
				attr_accessor :regime_tributario_servico
				def regime_tributario_servico
					@regime_tributario_servico.to_i if @regime_tributario_servico.present?
				end
				alias_attribute :ISSQNtot_cRegTrib, :regime_tributario_servico
				validates :regime_tributario_servico, inclusion: {in: [1,2,3,4,5,6]}
			##########################################################################
			#########################  TOTAIS DAS RETENÇÕES  #########################
				# VALOR RETIDO DE PIS
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/retTrib/vRetPIS
				#
				attr_accessor :total_retencao_pis
				alias_attribute :retTrib_vRetPIS, :total_retencao_pis
				validates :total_retencao_pis, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR RETIDO DE COFINS
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/retTrib/vRetCOFINS
				#
				attr_accessor :total_retencao_cofins
				alias_attribute :retTrib_vRetCOFINS, :total_retencao_cofins
				validates :total_retencao_cofins, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR RETIDO DE CSLL
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/retTrib/vRetCSLL
				#
				attr_accessor :total_retencao_csll
				alias_attribute :retTrib_vRetCSLL, :total_retencao_csll
				validates :total_retencao_csll, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# BASE DE CÁLCULO DO IRRF
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/retTrib/vBCIRRF
				#
				attr_accessor :total_retencao_base_calculo_irrf
				alias_attribute :retTrib_vBCIRRF, :total_retencao_base_calculo_irrf
				validates :total_retencao_base_calculo_irrf, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR RETIDO DO IRRF
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/retTrib/vIRRF
				#
				attr_accessor :total_retencao_irrf
				alias_attribute :retTrib_vIRRF, :total_retencao_irrf
				validates :total_retencao_irrf, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# BASE DE CÁLCULO DA RETENÇÃO DA PREVIDÊNCIA SOCIAL
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/retTrib/vBCRetPrev
				#
				attr_accessor :total_retencao_base_calculo_previdencia
				alias_attribute :retTrib_vBCRetPrev, :total_retencao_base_calculo_previdencia
				validates :total_retencao_base_calculo_previdencia, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true

				# VALOR DA RETENÇÃO DA PREVIDÊNCIA SOCIAL
				#
				# <b>Type:     </b> _Float_
				# <b>Required: </b> _No_
				# <b>Example:  </b> _178.46_
				# <b>Length:   </b> _13v2_
				# <b>tag:      </b> total/retTrib/vRetPrev
				#
				attr_accessor :total_retencao_previdencia
				alias_attribute :retTrib_vRetPrev, :total_retencao_previdencia
				validates :total_retencao_previdencia, numericality: {greater_than_or_equal_to: 0.0}, allow_blank: true
			##########################################################################
			########################  INFORMAÇÕES ADICIONAIS  ########################
				# INFORMAÇÕES ADICIONAIS DE INTERESSE DO FISCO
				#
				# <b>Type:     </b> _String_
				# <b>Required: </b> _No_
				# <b>Default:  </b> _nil_
				# <b>Length:   </b> _max: 2000_
				# <b>tag:      </b> infAdic/infAdFisco
				#
				attr_accessor :informacoes_fisco
				alias_attribute :infAdFisco, :informacoes_fisco

				# INFORMAÇÕES COMPLEMENTARES DE INTERESSE DO CONTRIBUINTE
				#
				# <b>Type:     </b> _String_
				# <b>Required: </b> _No_
				# <b>Default:  </b> _nil_
				# <b>Length:   </b> _max: 5000_
				# <b>tag:      </b> infAdic/infCpl
				#
				attr_accessor :informacoes_contribuinte
				alias_attribute :infCpl, :informacoes_contribuinte

				# GRUPO PROCESSO REFERENCIADO
				# (NT 2012/003)
				#
				# <b>Type:    </b> _BrNfe.processo_referencia_product_class (BrNfe::Product::Nfe::ProcessoReferencia)_
				# <b>Default: </b> _[]_
				# <b>Length:  </b> _max: 100_
				# <b>tag:     </b> procRef
				#
				has_many :processos_referenciados, 'BrNfe.processo_referencia_product_class'
				alias_attribute :procRef, :processos_referenciados
			##########################################################################
			######################  INFORMAÇÕES DE EXPORTAÇÃO  #######################
				# SIGLA DA UF DE EMBARQUE OU DE TRANSPOSIÇÃO DE FRONTEIRA
				# Não aceita o valor "EX"
				#
				# <b>Type:     </b> _String_
				# <b>Required: </b> _No_
				# <b>Default:  </b> _nil_
				# <b>Length:   </b> _2_
				# <b>tag:      </b> exporta/UFSaidaPais
				#
				attr_accessor :exportacao_uf_saida
				alias_attribute :UFSaidaPais, :exportacao_uf_saida
				validates :exportacao_uf_saida, inclusion: {in: BrNfe::Constants::SIGLAS_UF-['EX'] }, allow_blank: true

				# DESCRIÇÃO DO LOCAL DE EMBARQUE OU DE TRANSPOSIÇÃO DE FRONTEIRA
				#
				# <b>Type:     </b> _String_
				# <b>Required: </b> _No_
				# <b>Default:  </b> _nil_
				# <b>Length:   </b> _max: 60_
				# <b>tag:      </b> exporta/xLocExporta
				#
				attr_accessor :exportacao_local_embarque
				alias_attribute :xLocExporta, :exportacao_local_embarque

				# DESCRIÇÃO DO LOCAL DE DESPACHO
				# Informação do Recinto Alfandegado
				#
				# <b>Type:     </b> _String_
				# <b>Required: </b> _No_
				# <b>Default:  </b> _nil_
				# <b>Length:   </b> _max: 60_
				# <b>tag:      </b> exporta/xLocDespacho
				#
				attr_accessor :exportacao_local_despacho
				alias_attribute :xLocDespacho, :exportacao_local_despacho

			############################################################################
			#########################  DADOS SETADOS NO RETORNO #######################
				# Utilizado para setar o XML da nfe na resposta
				attr_accessor :xml

				# Utilizado para setar o XML da tag <infNFe>
				# Serve apenas se deseja pegar apenas a informação da NF-e sem a assinatura.
				#
				attr_accessor :xml_inf_nfe

				# PROTOCOLO / NÚMERO DO RECIBO
				#  Número do Recibo gerado pelo Portal da
				#  Secretaria de Fazenda Estadual
				#
				attr_accessor :protocol
				alias_attribute :nProt, :protocol

				# VALOR DIGEST DO RETORNO
				#  Digest Value da NF-e processada
				#  Utilizado para conferir a integridade da NFe
				#  original.
				#
				attr_accessor :digest_value
				alias_attribute :digVal, :digest_value

				# DATA E HORA DO PROCESSAMENTO DA REQUISIÇÃO
				#
				attr_accessor :processed_at
				def processed_at
					convert_to_time(@processed_at)
				end
				alias_attribute :dhRecbto, :processed_at

				# STATUS DA OPERAÇÃO
				# Esse é o status final da operação com anota fiscal.
				# A partir do status é possível identificar se obteve sucesso
				# no processamento da nota (para qualquer operação)
				#
				attr_accessor :status_code
				attr_accessor :status_motive
				def status
					if "#{status_code}   ".strip.in?( BrNfe::Constants::NFE_STATUS_SUCCESS )
						:success
					elsif "#{status_code}".strip.in?( BrNfe::Constants::NFE_STATUS_PROCESSING )
						:processing
					elsif "#{status_code}".strip.in?( BrNfe::Constants::NFE_STATUS_OFFLINE )
						:offline
					elsif "#{status_code}".strip.in?( BrNfe::Constants::NFE_STATUS_DENIED )
						:denied
					elsif status_code.present?
						:error
					end
				end

				# SITUAÇÃO DA NOTA FISCAL
				# Informa o status atual da nota fiscal.
				# Retorna se a nota fiscal está autorizada, cancelada, denegada, rejeitada, ajustada.
				# Exemplo:
				# - :authorized - Quando a nota fiscal está autorizada para uso
				# - :adjusted - Quando a nota fiscal está autorizada para o uso e foi realizado algum
				#               evento posterior que a mesma foi ajustada
				# - :draft    - Quando a nota fiscal ainda não tem validade fiscal.
				# - :canceled - Quando a nota fiscal foi cancelada.
				# - :denied   - Quando a nota fiscal foi denegada e o XML deve ser guardado.
				# - :rejected - Quando a nota fiscal foi rejeitada e pode ser enviada novamente com as correções.
				#
				attr_accessor :situation
				def situation
					@situation ||= get_situation_by_status_code
				end
				def get_situation_by_status_code
					if "#{status_code}".strip.in?(    BrNfe::Constants::NFE_SITUATION_AUTORIZED )
						:authorized
					elsif "#{status_code}".strip.in?( BrNfe::Constants::NFE_SITUATION_ADJUSTED )
						:adjusted
					elsif "#{status_code}".strip.in?( BrNfe::Constants::NFE_SITUATION_CANCELED )
						:canceled
					elsif "#{status_code}".strip.in?( BrNfe::Constants::NFE_SITUATION_DENIED )
						:denied
					elsif status_code.blank? || "#{status_code}".strip.in?( BrNfe::Constants::NFE_SITUATION_DRAFT )
						:draft
					else
						:rejected
					end
				end

			##################################################################################
			#########################  DADOS SETADOS NA LEITURA DO XML #######################
				attr_accessor :tipo_ambiente
				alias_attribute :tbAmb, :tipo_ambiente

			def default_values
				{
					versao_aplicativo:   0,
					natureza_operacao:   'Venda',
					forma_pagamento:     0, # 0=À vista
					modelo_nf:           55, #NF-e
					data_hora_emissao:   Time.current.in_time_zone,
					data_hora_expedicao: Time.current.in_time_zone,
					tipo_operacao:       1, # 1=Saída
					tipo_impressao:      1, # 1=DANFE normal, Retrato;
					finalidade_emissao:  1, # 1=NF-e normal;
					presenca_comprador:  9, # 9=Operação não presencial, outros.
					processo_emissao:    0, # 0=Emissão de NF-e com aplicativo do contribuinte;
					codigo_tipo_emissao: 1, # 1=Normal
					servicos_data_prestacao:   Date.current,
					regime_tributario_servico: 1, # 1=Microempresa Municipal;
				}
			end

			validates :codigo_tipo_emissao, presence: true
			validates :codigo_tipo_emissao, inclusion: [1, 6, 7, 9, '1', '6', '7', '9']

			validates :codigo_nf, presence: true
			validates :codigo_nf, numericality: { only_integer: true }
			validates :codigo_nf, length: { maximum: 8 }

			validates :serie, presence: true
			validates :serie, numericality: { only_integer: true }
			validates :serie, length: { maximum: 3 }
			validates :serie, exclusion: [890, 899, 990, 999, '890', '899', '990', '999']

			validates :numero_nf, presence: true
			validates :numero_nf, numericality: { only_integer: true }
			validates :numero_nf, length: { maximum: 9 }

			validates :natureza_operacao, presence: true

			validates :forma_pagamento, presence: true
			validates :forma_pagamento, inclusion: [0, 1, 2, '0', '1', '2']

			validates :modelo_nf, presence: true
			validates :modelo_nf, inclusion: [55, 65, '55', '65']

			validates :data_hora_emissao, presence: true
			validates :data_hora_expedicao, presence: true, if: :nfe?

			validates :tipo_operacao, presence: true
			validates :tipo_operacao, inclusion: [0, 1, '0', '1']

			validates :tipo_impressao, presence: true
			validates :tipo_impressao, inclusion: [0, 1, 2, 3, 4, 5, '0', '1', '2', '3', '4', '5']

			validates :presenca_comprador, presence: true
			validates :presenca_comprador, inclusion: [0, 1, 2, 3, 4, 9, '0', '1', '2', '3', '4', '9']

			validates :processo_emissao, presence: true
			validates :processo_emissao, inclusion: [0, 1, 2, 3, '0', '1', '2', '3']

			validates :autorizados_download_xml, length: { maximum: 10 }

			validate_has_many :itens, message: :invalid_item
			validates         :itens, length:  {minimum: 1, maximum: 990}

			validate_has_many :processos_referenciados, message: :invalid_processo

			with_options if: :nfce? do |record|
				record.validate_has_many :pagamentos
				record.validates :pagamentos, length: {maximum: 100}
			end

			validate_has_one  :transporte
			validate_has_one  :fatura
			validate_has_one  :destinatario
			validate_has_one  :emitente

			validate_has_one  :endereco_retirada
			with_options if: :endereco_retirada do |record|
				record.validates :endereco_retirada_cpf_cnpj, presence: true
				record.validates :endereco_retirada_cpf_cnpj, length: {maximum: 14}
			end

			validate_has_one  :endereco_entrega
			with_options if: :endereco_entrega do |record|
				record.validates :endereco_entrega_cpf_cnpj, presence: true
				record.validates :endereco_entrega_cpf_cnpj, length: {maximum: 14}
			end

			def nfe?
				modelo_nf.to_i == 55
			end

			def nfce?
				modelo_nf.to_i == 65
			end

			def has_any_service?
				itens.select(&:is_service?).any?
			end

			def has_any_product?
				itens.select(&:is_product?).any?
			end

			# MÉTODO PARA SABER SE EXISTE ALGUM VALOR NO TOTALIZADOR DE RETENÇÃO DE IMPOSTOS.
			# Utilizado para saber se deve ou não colocar a tag de totalizador de retenções
			# no XML.
			#
			# <b>Tipo: </b> _Boolean_
			#
			def has_taxes_retention?
				total_retencao_pis.to_f  > 0.0 || total_retencao_cofins.to_f > 0.0 ||
				total_retencao_csll.to_f > 0.0 || total_retencao_irrf.to_f > 0.0   ||
				total_retencao_previdencia.to_f > 0.0
			end

		private

			###############################################################################################
			#       | Código | AAMM da | CNPJ do  | Modelo | Série | Número  | Cód. tipo | Código   | DV  |
			#       | da UF  | emissão | Emitente |        |       | da NF-e | emissão   | Numérico |     |
			#       ---------------------------------------------------------------------------------------
			# Tam = |  02    |   04    |    14    |   02   |   03  |   09    |    01     |    08    | 01  |
			#       °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
			def gerar_chave_de_acesso!
				chave_sem_dv =  "#{emitente.endereco.codigo_ibge_uf}"
				chave_sem_dv << "#{data_hora_emissao.try(:strftime, '%y%m')}"
				chave_sem_dv << "#{emitente.cnpj}".rjust(14,'0')
				chave_sem_dv << "#{modelo_nf}"
				chave_sem_dv << "#{serie}".rjust(3, '0')
				chave_sem_dv << "#{numero_nf}".rjust(9, '0')
				chave_sem_dv << "#{codigo_tipo_emissao}"
				chave_sem_dv << "#{codigo_nf}".rjust(8, '0')
				dv = BrNfe::Calculos::Modulo11FatorDe2a9RestoZero.new(chave_sem_dv)
				"#{chave_sem_dv}#{dv}"
			end
		end
	end
end