require 'active_support/concern'

module Tcm::ItemDaNotaFiscalConcern extend ActiveSupport::Concern
	# IF_____.DCD
	# ARQUIVO 602

	def pesquisa_itens_notas_fiscais
		itens = Contabilidade::ItemDaNotaFiscal.joins(liquidacao: [empenho: [orcamento_da_despesa:[elemento_de_despesa_por_subacao: [subacao: [unidade_orcamentaria: :tipo_de_unidade_administrativa]]]]])
			.where('contabilidade_liquidacoes.data_da_liquidacao is not null AND contabilidade_liquidacoes.nota_fiscal_tipo BETWEEN 1 AND 6 AND contabilidade_liquidacoes.status in (2,5,6,8) AND contabilidade_liquidacoes.data_da_liquidacao >= ? AND contabilidade_liquidacoes.data_da_liquidacao <= ? AND contabilidade_liquidacoes.restos_a_pagar <> true', self.lote.data_referencia, self.lote.data_referencia.end_of_month).distinct.all
			.where('base_tipos_de_unidades_administrativas.poder_associado = ?', self.lote.poder_associado)

		itens_rp = Contabilidade::ItemDaNotaFiscal.joins(liquidacao: [empenho: [orcamento_da_despesa:[elemento_de_despesa_por_subacao: [subacao: [unidade_orcamentaria: :tipo_de_unidade_administrativa]]]]])
			.where('contabilidade_liquidacoes.data_da_liquidacao is not null AND contabilidade_liquidacoes.nota_fiscal_tipo BETWEEN 1 AND 6 AND contabilidade_liquidacoes.status in (2,5,6,8) AND contabilidade_liquidacoes.data_da_liquidacao >= ? AND contabilidade_liquidacoes.data_da_liquidacao <= ? AND contabilidade_liquidacoes.restos_a_pagar = true', self.lote.data_referencia, self.lote.data_referencia.end_of_month).distinct.all
			.where('base_tipos_de_unidades_administrativas.poder_associado = ?', self.lote.poder_associado)
			.select{|item| item.liquidacao.eh_processada? == false}

		return itens + itens_rp
	end

	def gerar_itens_das_notas
		# pesquisar objetos
		objetos = self.pesquisa_itens_notas_fiscais.select { |i| i.liquidacao.nota_fiscal.present? }
		classe_do_objeto = 'Contabilidade::ItemDaNotaFiscal'
		tipo_de_poder = Tcm::Linha.tipos_de_poder[self.lote.tipo_de_poder]

		# limpar arquivo
		ActiveRecord::Base.connection.execute("DELETE FROM tcm_linhas WHERE modulo_type = '#{classe_do_objeto}' and tipo_de_poder = #{tipo_de_poder} and arquivo_referencia = '#{self.nome}'")

		self.carrega_dependencias_para_itens_das_notas_fiscais

		linhas = []
		conteudo = ""
		sequencia = 1
		objetos.group_by{|item| [item.liquidacao.empenho_id, item.liquidacao.data_da_liquidacao , item.liquidacao.tipo_da_folha || '' , item.item_id, item.liquidacao.nota_fiscal.attributes.except("id", "liquidacao_id","tipo_de_desconto", "valor_de_desconto", "cfop_id", "created_at", "updated_at", "orcamentario_iss", "extraorcamentario_iss", "orcamentario_inss_pj", "extraorcamentario_inss_pj", "extraorcamentario_irpj", "orcamentario_irpj", "extraorcamentario_inss_pf","orcamentario_irpf", "extraorcamentario_irpf", "arquivo_id")]}.each do |agrupamento, itens|
			objeto = itens.min_by(&:id)
			linha = self.item_da_nota_fiscal_to_sim(itens, sequencia)
			sequencia += 1
			conteudo << linha
			conteudo << "\r\n"
			linhas << Tcm::Linha.new(modulo_id: objeto.id, modulo_type: objeto.class.name, arquivo_referencia: self.nome , conteudo: linha, tipo_de_poder: tipo_de_poder)
			itens.map{|item| item.update_column(:arquivo_id, self.id)}
		end
		self.update_columns(conteudo: conteudo, classe: classe_do_objeto)
		Tcm::Linha.import linhas
	end

	def carrega_dependencias_para_itens_das_notas_fiscais
		@configuracao = Configuracao.first
		@orcamentos = Orcamento.all.map(&:attributes).map(&:symbolize_keys)
	end

	def item_da_nota_fiscal_to_sim(itens_da_nota_fiscal, sequencial)
		begin
			item_da_nota_fiscal = itens_da_nota_fiscal.min_by(&:id)
			qtd_total = itens_da_nota_fiscal.sum(&:quantidade)
			val_total = itens_da_nota_fiscal.sum(&:total)
			val_unit = val_total / qtd_total
			exercicio_do_orcamento = item_da_nota_fiscal.liquidacao.empenho.orcamento.exercicio.to_s
			nota_fiscal = item_da_nota_fiscal.liquidacao.nota_fiscal

			texto = ""
			texto << "603".sim_preenche(3) + ","#1
			texto << @configuracao.codigo_do_municipio_no_tcm.sim_preenche(3) + ","#2
			texto << exercicio_do_orcamento + '00' + ","#3
			texto << item_da_nota_fiscal.liquidacao.unidade_orcamentaria.orgao.codigo.sim_preenche(2) + ","#4
			texto << item_da_nota_fiscal.liquidacao.unidade_orcamentaria.codigo.codigo_uo_to_sim + ","#5
			texto << item_da_nota_fiscal.liquidacao.empenho.data_do_empenho.sim_data + ","#6
			texto << item_da_nota_fiscal.liquidacao.empenho.numero_do_empenho.sim_limite(8) + ","#7
			texto << item_da_nota_fiscal.liquidacao.data_da_liquidacao.sim_data + ","#8
			texto << nota_fiscal.tipo_da_nota_to_sim.sim_limite(1) + ","#9
			texto << nota_fiscal.numero_da_nota.sim_limite(15) + ","#10
			texto << sequencial.to_s.sim_preenche(4) + ","#11
			texto << item_da_nota_fiscal.item.descricao.to_s.sim_descricao.delete('"').sim_limite(510) + ","#12
			texto << item_da_nota_fiscal.item.unidade_de_medida.try(:descricao).to_s.sim_limite(10) + ","#13
			texto << qtd_total.to_d.to_s.sim_valor + ","#14
			texto << val_unit.to_f.to_s.sim_valor_maior + ","#15
			texto << val_total.to_f.to_s.sim_valor  + ","#16
			texto << (item_da_nota_fiscal.ncm.present? ? item_da_nota_fiscal.ncm.codigo.sim_limite(8) : '""')#17
			return texto
		rescue => e
			if e.class.to_s == "NoMethodError"
				atributo_falho = e.message.split(" ")[2]
				coluna = CSV.parse(texto, :headers => false).last.count
				raise e.mensagem_traduzida(self, "", atributo_falho, coluna)
			else
				raise e
			end
		end
	end

end
