require 'active_support/concern'

module Tcm::LiquidacaoConcern extend ActiveSupport::Concern

	def pesquisa_liquidacoes
		Contabilidade::Liquidacao.joins(empenho: [unidade_orcamentaria: :tipo_de_unidade_administrativa])
			.where('base_tipos_de_unidades_administrativas.poder_associado = ?', self.lote.poder_associado)
			.where('contabilidade_liquidacoes.arquivo_id is null OR contabilidade_liquidacoes.arquivo_id = ?', self.id)
			.where('contabilidade_liquidacoes.status in (2,5,6,8) AND contabilidade_liquidacoes.data_da_liquidacao between ? and ?', self.lote.data_referencia, self.lote.data_referencia.end_of_month).distinct.all
			.where('(contabilidade_liquidacoes.restos_a_pagar = false OR (contabilidade_liquidacoes.restos_a_pagar = true AND EXTRACT (YEAR FROM contabilidade_liquidacoes.data_da_liquidacao) > EXTRACT (YEAR FROM contabilidade_empenhos.data_do_empenho)))').distinct.all
		end

	def gerar_liquidacoes
		liquidacoes = self.pesquisa_liquidacoes
		classe_do_objeto = 'Contabilidade::Liquidacao'
		tipo_de_poder = Tcm::Linha.tipos_de_poder[self.lote.tipo_de_poder]
		linhas = []

		Tcm::Linha.where(modulo_type: classe_do_objeto, tipo_de_poder: tipo_de_poder, arquivo_referencia: self.nome).delete_all

		liquidacoes.group_by { |lq| [lq.empenho_id, lq.data_da_liquidacao, lq.tipo_da_folha || ''] }.each do |agrupamentos, lqs|
			linhas << Tcm::Linha.new(modulo_id: lqs.min_by(&:numero), modulo_type: classe_do_objeto, arquivo_referencia: self.nome , conteudo: liquidacao_to_sim(lqs), tipo_de_poder: tipo_de_poder)
			liquidacoes.where('contabilidade_liquidacoes.id IN (?)', lqs.pluck(:id)).update_all(arquivo_id: self.id, liquidacao_sim_id: lqs.min_by(&:numero).id)
		end

		self.update_columns(conteudo: linhas.sort_by(&:modulo_id).map(&:conteudo).join("\r\n"), classe: classe_do_objeto)
		Tcm::Linha.import linhas
	end

	def liquidacao_to_sim(liquidacoes)
		begin
			lq = liquidacoes.min_by(&:numero)
			empenho = lq.empenho
			orcamento = empenho.orcamento
			soma_dos_valores = liquidacoes.sum(&:valor)
			unidade_orcamentaria = lq.unidade_orcamentaria
			ord_despesa = unidade_orcamentaria.ordenadores_de_despesa.atual_na_data(lq.data_da_liquidacao.to_date)

			texto = ""
			texto << '612'.sim_preenche(3) + "," # 1
			texto << Configuracao.first.codigo_do_municipio_no_tcm.sim_preenche(3) + "," # 2
			texto << "#{orcamento.exercicio}00" + "," # 3
			texto << unidade_orcamentaria.orgao.codigo.sim_preenche(2) + "," # 4
			texto << unidade_orcamentaria.codigo.codigo_uo_to_sim + "," # 5
			texto << empenho.data_do_empenho.sim_data + "," # 6
			texto << empenho.numero_do_empenho.sim_limite(8) + "," # 7
			texto << lq.data_da_liquidacao.sim_data + "," # 8
			texto << (self.try(:lote).present? ? self.lote.exercicio_e_mes_de_geracao : self.exercicio_e_mes_de_geracao).to_s + "," # 9
			texto << (ord_despesa&.agente_publico&.cpf || "''").sim_limite(11) + "," # 10
			texto << (ord_despesa&.agente_publico&.nome || "''").sim_limite(40) + "," # 11
			texto << (empenho.ordinario? ? '000' : '001').sim_limite(3) + "," # 12
			texto << soma_dos_valores.to_f.to_s.sim_valor + "," # 13

			if lq.tem_folha_de_pagamento? && lq.data_de_emissao_da_folha.present?
				mes_da_folha = lq.read_attribute_before_type_cast(:mes_da_folha).to_i + 1
				atributo_mes_da_folha = mes_da_folha > 9 ? mes_da_folha : "0#{mes_da_folha}"

				texto << "#{lq.ano_da_folha}#{atributo_mes_da_folha}," # 14
				texto << (lq.tipo_da_folha.presence || "").sim_limite(2) + "," # 15
				texto << lq.data_de_emissao_da_folha.sim_data + "," # 16
				texto << soma_dos_valores.to_f.to_s.sim_valor # 17
			else
				texto << "0," # 14
				texto << '""' + "," # 15
				texto << "0," # 16
				texto << "0.00" # 17
			end

			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(lq, lq.numero, atributo_falho, coluna)
			else
				raise e
			end
		end
	end


end
