require 'httparty'

module ImportacaoTcm
	class LicitacaoProcesso
		@@host = 'https://api.tce.ce.gov.br/index.php/sim/1_0'

		class << self
			def importar importacao_tcm_processo
				numero_do_processo = importacao_tcm_processo.numero_do_processo
				exercicio = importacao_tcm_processo.exercicio
				## ***IMPORTANTE***
				## todas as tabelas envolvidas na importação de um processo do TCM, devem estar com arquivo_id = 0
				codigo_do_municipio = ::Configuracao.last.codigo_do_municipio_no_tcm
				raise Exception.new("Código do Município não configurado") if codigo_do_municipio.blank?
				orcamento = ::Orcamento.find_by_exercicio(exercicio)
				if orcamento.nil?
					# **IMPORTANTE** Caso não exista orçamento, será necessário importar antes. Basta apenas executar a linha
					# abaixo, entretanto foi comentado pois demorava a requisição do processo no browser. Para isso foi criado uma
					# task para ser executado => lib/tasks/importar_tcm.rake => task: importa_orcamento_e_despesa
					# ImportacaoTcm::LoaDespesa.importar(codigo_do_municipio, exercicio)
					raise Exception.new("Não existe o Orçamento criado para o exercício #{exercicio}. Contate a equipe de TI para realizarem a importação do Orçamento referente ao exercício informado.")
				end

				dados_do_processo = importar_dados_do_processo(codigo_do_municipio, numero_do_processo, exercicio)
				raise Exception.new("Não foi possível encontrar o processo informado.") if dados_do_processo.nil?

				dados_das_dotacoes = importar_dados_das_dotacoes(codigo_do_municipio, numero_do_processo, exercicio)
				dados_dos_itens = importar_dados_dos_itens(codigo_do_municipio, numero_do_processo, exercicio)
				dados_dos_licitantes = importar_dados_dos_licitantes(codigo_do_municipio, numero_do_processo, exercicio)
				dados_das_comissoes = importar_dados_da_comissao(codigo_do_municipio, dados_do_processo)
				dados_das_publicacoes = importar_dados_das_publicacoes(codigo_do_municipio, numero_do_processo, exercicio)

				if importacao_tcm_processo.cria_processo_completo? || importacao_tcm_processo.cria_apenas_pedido?
					pedido = criar_pedido(dados_das_dotacoes, dados_do_processo, dados_dos_itens, orcamento, importacao_tcm_processo)
					criar_cotacoes(pedido, dados_dos_licitantes, dados_dos_itens, importacao_tcm_processo)
					if importacao_tcm_processo.cria_processo_completo?
						processo = criar_projeto_basico(pedido, dados_do_processo, dados_das_comissoes, orcamento)
						criar_publicacoes(processo, dados_das_publicacoes)
						criar_cotacoes_para_pessoas_do_projeto(processo)
						criar_dotacoes(processo, dados_das_dotacoes, orcamento)
						return processo
					else
						return pedido
					end
				else
					itens_do_pedido = criar_somente_itens_do_pedido(dados_dos_itens, importacao_tcm_processo)
					return itens_do_pedido
				end
			end


			def importar_dados_do_processo codigo_do_municipio, numero_do_processo, exercicio
				response = HTTParty.get( "#{@@host}/licitacoes.xml?codigo_municipio=#{codigo_do_municipio}&data_realizacao_autuacao_licitacao=#{exercicio}0101_#{exercicio}1231&numero_licitacao=#{numero_do_processo}" )
				begin
					dados_processo = Hash.from_xml(response.body.encode(Encoding::UTF_8))['rsp']['licitacoes']
					dados_processo = dados_processo.kind_of?(Array) ? dados_processo.first : dados_processo
				rescue
					puts "Página não encontrada, tentando novamente..."
				end
			end

			def importar_dados_das_dotacoes codigo_do_municipio, numero_do_processo, exercicio
				response = HTTParty.get( "#{@@host}/dotacoes_licitacoes.xml?codigo_municipio=#{codigo_do_municipio}&data_realizacao_licitacao=#{exercicio}0101_#{exercicio}1231&numero_licitacao=#{numero_do_processo}" )
				begin
					dados_dotacoes = Hash.from_xml(response.body.encode(Encoding::UTF_8))['rsp']['dotacoes_licitacoes']
				rescue
					puts "Página não encontrada, tentando novamente..."
				end
			end

			def importar_dados_dos_itens codigo_do_municipio, numero_do_processo, exercicio
				response = HTTParty.get( "#{@@host}/itens_licitacoes.xml?codigo_municipio=#{codigo_do_municipio}&data_realizacao_licitacao=#{exercicio}0101_#{exercicio}1231&numero_licitacao=#{numero_do_processo}" )
				begin
					dados_itens = Hash.from_xml(response.body.encode(Encoding::UTF_8))['rsp']['itens_licitacoes']
				rescue
					puts "Página não encontrada, tentando novamente..."
				end
			end

			def importar_dados_dos_licitantes codigo_do_municipio, numero_do_processo, exercicio
				response = HTTParty.get( "#{@@host}/licitantes.xml?codigo_municipio=#{codigo_do_municipio}&data_realizacao_licitacao=#{exercicio}0101_#{exercicio}1231&numero_licitacao=#{numero_do_processo}" )
				begin
					dados_itens = Hash.from_xml(response.body.encode(Encoding::UTF_8))['rsp']['licitantes']
				rescue
					puts "Página não encontrada, tentando novamente..."
				end
			end

			def importar_dados_da_comissao codigo_do_municipio, dados_do_processo
				cpf_gestor = dados_do_processo['cpf_gestor']
				data_criacao_comissao = dados_do_processo['data_criacao_comissao'].to_date.strftime("%Y%m%d")
				response = HTTParty.get( "#{@@host}/comissoes_licitacoes.xml?codigo_municipio=#{codigo_do_municipio}&cpf_gestor=#{cpf_gestor}&data_criacao_comissao=#{data_criacao_comissao}" )
				begin
					dados_itens = Hash.from_xml(response.body.encode(Encoding::UTF_8))['rsp']['comissoes_licitacoes']
				rescue
					puts "Página não encontrada, tentando novamente..."
				end
			end

			def importar_dados_das_publicacoes codigo_do_municipio, numero_do_processo, exercicio
				response = HTTParty.get( "#{@@host}/publicacoes_editais_licitacoes.xml?codigo_municipio=#{codigo_do_municipio}&data_realizacao_licitacao=#{exercicio}0101_#{exercicio}1231&numero_licitacao=#{numero_do_processo}" )
				begin
					dados_itens = Hash.from_xml(response.body.encode(Encoding::UTF_8))['rsp']['publicacoes_editais_licitacoes']
				rescue
					puts "Página não encontrada, tentando novamente..."
				end
			end

			def criar_pedido dados_das_dotacoes, dados_do_processo, dados_dos_itens, orcamento, importacao_tcm_processo
				raise Exception.new("Não existe(m) dotacão(ões) no SIM para esse processo. Para importar, os campos Categoria e Unidade Orcamentária devem ser informados neste caso.") if dados_das_dotacoes.nil? && importacao_tcm_processo.categoria.nil? && importacao_tcm_processo.unidade_orcamentaria.nil?

				categorias = []
				unidades_orcamentarias = []
				unidade_orcamentaria_principal = importacao_tcm_processo.unidade_orcamentaria
				if unidade_orcamentaria_principal.nil?
					dados_das_dotacoes = [dados_das_dotacoes] if !dados_das_dotacoes.kind_of?(Array)
					dados_das_dotacoes.each do |dotacao|
						cod_unidade_orcamentaria = dotacao['codigo_unidade'].gsub(" ", "")
						cod_orgao = dotacao['codigo_orgao'].gsub(" ", "")
						cod_elemento_de_despesa = dotacao['codigo_elemento_despesa'].gsub(" ", "")

						elemento_de_despesa = orcamento.elementos_de_despesa.find_by_codigo(cod_elemento_de_despesa)
						categoria = elemento_de_despesa.try(:elemento_de_gasto).try(:categorias).first
						if categoria.nil?
							categoria = cria_categoria_para_elemento_de_despesa(elemento_de_despesa.elemento_de_gasto.codigo)
						end
						if categorias.select {|cat| cat.codigo == categoria.codigo}.size == 0
							categorias << categoria
						end

						orgao = ::Loa::Orgao.find_by(codigo: cod_orgao, orcamento_id: orcamento.id)
						if orgao.nil?
							raise Exception.new("Não existe Órgão com o código #{cod_orgao}")
						end
						unidade_orcamentaria_principal = orcamento.unidades_orcamentarias.find_by(orgao_id: orgao.id, codigo: cod_unidade_orcamentaria)
						if unidade_orcamentaria_principal.nil?
							raise Exception.new("Não existe Unidade Orçamentária com o código #{cod_unidade_orcamentaria} para o órgão #{orgao.try(:nome)} e id #{orgao.id} do exercício de #{orcamento.exercicio.to_s}")
						end
						unidades_orcamentarias << unidade_orcamentaria_principal unless unidades_orcamentarias.include?(unidade_orcamentaria_principal)
					end
				else
					categorias << importacao_tcm_processo.categoria
				end

				justificativa = dados_do_processo['descricao1_justificativa_preco'] << dados_do_processo['descricao2_justificativa_preco']
				justificativa = "Sem informações." if justificativa.blank?
				objeto = dados_do_processo['descricao1_objeto_licitacao'] << dados_do_processo['descricao2_objeto_licitacao']
				objeto = "Sem informações." if objeto.blank?

				pedido = ::Licitacao::Pedido.new(
					unidade_orcamentaria_id: unidade_orcamentaria_principal.id,
					usuario_id: 1,
					status: 0,
					objeto: objeto,
					justificativa: justificativa,
					orcamento: orcamento,
					prazo_de_entrega: "7 dias",
					outras_informacoes: "Nenhuma informação adicional.",
					local_de_entrega: "Nenhuma informação. Pedido importado",
					data_do_pedido: dados_do_processo['data_realizacao_autuacao_licitacao'].to_date,
					convidar_unidades: ((importacao_tcm_processo.cria_apenas_pedido? || unidades_orcamentarias.size > 1 ) ? true : false),
					data_limite_para_complementacao: 180.business_day.from_now,
					vigencia: "12 meses"
				)

				if pedido.data_do_pedido.saturday?
					pedido.data_do_pedido = pedido.data_do_pedido.tomorrow + 1
				elsif pedido.data_do_pedido.sunday?
					pedido.data_do_pedido = pedido.data_do_pedido.tomorrow
				end

				categorias.each do |categoria|
					pedido.categorias_do_pedido.build(categoria: categoria)
				end

				unidades_orcamentarias.delete_if {|unidade_orcamentaria| unidade_orcamentaria == unidade_orcamentaria_principal }

				unless pedido.unidade_orcamentaria.ordenadores_de_despesa.any?
					raise Exception.new("Nenhum Ordenador de Despesa foi cadastrado para a Unidade Orçamentária: #{unidade_orcamentaria_principal.codigo_completo_e_nome}, a qual pertence à Unidade Gestora: #{unidade_orcamentaria_principal.unidade_gestora.codigo_e_nome}.")
				end
				pedido.save!

				unidades_orcamentarias.each do |unidade_orcamentaria|
					unless unidade_orcamentaria.ordenadores_de_despesa.any?
						raise Exception.new("Nenhum Ordenador de Despesa foi cadastrado para a Unidade Orçamentária: #{unidade_orcamentaria.codigo_completo_e_nome}, a qual pertence à Unidade Gestora: #{unidade_orcamentaria.unidade_gestora.codigo_e_nome}.")
					end
					pedido.unidades_orcamentarias_por_pedido.create(unidade_orcamentaria: unidade_orcamentaria)
				end

				criar_itens_do_pedido(pedido, dados_dos_itens)
				return pedido
			end

			def criar_cotacoes pedido, dados_dos_licitantes, dados_dos_itens, importacao_tcm_processo
				dados_dos_licitantes = [dados_dos_licitantes] if !dados_dos_licitantes.kind_of?(Array)
				dados_dos_licitantes.each do |dados_do_licitante|

					if dados_do_licitante['codigo_tipo_negociante'] == "1"
						pessoa = ::Base::Pessoa.find_by_cnpj(dados_do_licitante['numero_documento_negociante'])
					elsif dados_do_licitante['codigo_tipo_negociante'] == "2"
						pessoa = ::Base::Pessoa.find_by_cpf(dados_do_licitante['numero_documento_negociante'])
					end

					if pessoa.nil?
						porte = dados_do_licitante['codigo_tipo_negociante'] == "1" ? 3 : nil
						tipo_de_pessoa = dados_do_licitante['codigo_tipo_negociante'] == "1" ? 2 : 1
						nome_cidade = (dados_do_licitante['nome_municipio_negociante'] == "FORTAELZA" ? "FORTALEZA" : dados_do_licitante['nome_municipio_negociante'])
						cidade_da_pessoa = ::Base::Cidade.where('unaccent(nome) ilike unaccent(?)', nome_cidade).first

						pessoa = ::Base::Pessoa.create!(
							nome: dados_do_licitante['nome_negociante'],
							porte: porte,
							tipo_de_pessoa_id: tipo_de_pessoa,
							cnpj: dados_do_licitante['codigo_tipo_negociante'] == "1" ? dados_do_licitante['numero_documento_negociante'] : nil,
							cpf: dados_do_licitante['codigo_tipo_negociante'] == "2" ? dados_do_licitante['numero_documento_negociante'] : nil,
							fornecedor: true,
							data_do_cadastro: Date.today,
							cidade: cidade_da_pessoa,
							cep: dados_do_licitante['cep_negociante'],
							telefone: dados_do_licitante['fone_negociante']
						)
					end

					pessoa_do_pedido = pedido.pessoas_do_pedido.create!(pessoa: pessoa, nome_do_responsavel: pessoa.nome, tipo_de_responsavel: 3, prazo_da_proposta: 60)

					dados_dos_itens = [dados_dos_itens] if !dados_dos_itens.kind_of?(Array)
					dados_dos_itens.each do |dados_do_item|
						documento_licitante_do_item = dados_do_item['numero_documento_negociante']

						if documento_licitante_do_item == dados_do_licitante['numero_documento_negociante']
							item = ::Base::Item.find_by("descricao ILIKE ?", "#{dados_do_item['descricao_item_licitacao']}")
							item_do_pedido = pedido.itens_do_pedido.find_by(item_id: item.id)
							pessoa_do_pedido.itens_do_pedido_por_pessoa.create!(marca: "marca", preco_de_cotacao: dados_do_item['valor_unitario_item_licitacao'].to_f, item_do_pedido: item_do_pedido)
						end
					end
				end
				pedido.update_column(:justificativa_da_cotacao, "Pedido criado de acordo com a importação do Processo.") if pedido.pessoas_do_pedido.count < 3
				pedido.update_column(:status, ::Licitacao::Pedido.status[:projeto_gerado]) unless importacao_tcm_processo.cria_apenas_pedido?
			end

			def criar_itens_do_pedido pedido, dados_dos_itens
				raise Exception.new("Não foi possível importar os dados dos itens do pedido.") if dados_dos_itens.nil?

				dados_dos_itens = [dados_dos_itens] if !dados_dos_itens.kind_of?(Array)
				dados_dos_itens.each do |dados_do_item|

					categoria_ou_subcategoria = pedido.categorias.first.subcategorias.find_by(codigo: 99)
					categoria_ou_subcategoria = pedido.categorias.first if categoria_ou_subcategoria.nil?

					item = ::Base::Item.find_by("descricao ILIKE ?", "#{dados_do_item['descricao_item_licitacao']}")
					if item.nil?
						unidade = ::UnidadeDeMedida.where('unaccent(upper(descricao)) = ?', dados_do_item['descricao_unidade_item_licitacao'].upcase).first
						if unidade.nil?
							unidade = ::UnidadeDeMedida.create!(descricao: dados_do_item['descricao_unidade_item_licitacao'])
						end

						item = categoria_ou_subcategoria.itens.create!(
							descricao: dados_do_item['descricao_item_licitacao'],
							descricao_tecnica: "Importado do TCM - " << dados_do_item['descricao_item_licitacao'],
							unidade_de_medida: unidade
						)
					end
					pedido.itens_do_pedido.find_or_create_by!(item: item)
					pedido.itens_do_pedido.find_by(item: item).itens_do_pedido_por_unidade_orcamentaria.first.update_column(:quantidade, dados_do_item['numero_quantidade_item_licitacao'].to_f)
				end
			end

			def criar_somente_itens_do_pedido dados_dos_itens, importacao_tcm_processo
				raise Exception.new("Não foi possível importar os dados dos itens do pedido.") if dados_dos_itens.nil?

				dados_dos_itens = [dados_dos_itens] if !dados_dos_itens.kind_of?(Array)
				dados_dos_itens.each do |dados_do_item|

					categoria_ou_subcategoria = importacao_tcm_processo.categoria.subcategorias.find_by(codigo: 99)
					categoria_ou_subcategoria = importacao_tcm_processo.categoria if categoria_ou_subcategoria.nil?

					item = ::Base::Item.find_by("descricao ILIKE ?", "#{dados_do_item['descricao_item_licitacao']}")

					if item.nil?
						unidade = ::UnidadeDeMedida.where('unaccent(upper(descricao)) = ?', dados_do_item['descricao_unidade_item_licitacao'].upcase).first
						if unidade.nil?
							unidade = ::UnidadeDeMedida.create!(descricao: dados_do_item['descricao_unidade_item_licitacao'])
						end

						item = categoria_ou_subcategoria.itens.create!(
							descricao: dados_do_item['descricao_item_licitacao'],
							descricao_tecnica: "Importado do TCM - " << dados_do_item['descricao_item_licitacao'],
							unidade_de_medida: unidade
						)
					end
					importacao_tcm_processo.importacoes_tcm_itens.build(item_id: item.id)
				end
			end

			def criar_projeto_basico pedido, dados_do_processo, dados_das_comissoes, orcamento
				numero_comissao = dados_do_processo['numero_comissao']
				dados_das_comissoes = [dados_das_comissoes] if !dados_das_comissoes.kind_of?(Array)
				comissao_do_processo = dados_das_comissoes.select {|dados_da_comissao| dados_da_comissao['numero_comissao'] == numero_comissao}.first
				cpf_gestor_unidade = dados_do_processo['cpf_gestor']

				if comissao_do_processo['tipo_comissao'] == "1"
					tipo_de_comissao = 0
				else
					tipo_de_comissao = 1
				end

				unidade_gestora = ::Loa::UnidadeGestora.joins(gestores: [agente_publico_municipal: :pessoa]).where(base_pessoas: {cpf: cpf_gestor_unidade}).first
				data_da_extincao = comissao_do_processo['data_extincao_comissao'].present? ? comissao_do_processo['data_extincao_comissao'].to_date : nil

				if unidade_gestora.nil?
					comissao = ::Licitacao::Comissao.new(
						unidade_gestora: pedido.unidade_orcamentaria.unidade_gestora,
						tipo_de_comissao: tipo_de_comissao,
						numero_da_portaria_de_extincao: comissao_do_processo['numero_portaria_extincao'],
						numero_da_portaria: comissao_do_processo['numero_portaria_criacao'],
						data_da_extincao: data_da_extincao,
						nome: "Comissão importada do TCM",
						arquivo_id: 0
					)
				else
					comissao = ::Licitacao::Comissao.find_by(unidade_gestora_id: unidade_gestora.id, numero: comissao_do_processo['numero_comissao'])
					if comissao.nil?
						comissao = ::Licitacao::Comissao.new(
							unidade_gestora: pedido.unidade_orcamentaria.unidade_gestora,
							tipo_de_comissao: tipo_de_comissao,
							numero_da_portaria_de_extincao: comissao_do_processo['numero_portaria_extincao'],
							numero_da_portaria: comissao_do_processo['numero_portaria_criacao'],
							data_da_extincao: data_da_extincao,
							nome: "Comissão importada do TCM",
							arquivo_id: 0
						)
					end
				end
				comissao.save(validate: false)

				modalidade_do_processo = nil
				legislacao = nil
				if dados_do_processo['modalidade_processo_administrativo'] == "D"
					modalidade_do_processo = 1 #dispensa
					legislacao = ::Base::Legislacao.find_by_titulo("Artigo\t24\tInciso\tI")
				elsif dados_do_processo['modalidade_processo_administrativo'] == "R" || dados_do_processo['modalidade_processo_administrativo'] == "N"
					modalidade_do_processo = 0 #processo licitatorio
				elsif dados_do_processo['modalidade_processo_administrativo'] == "I"
					modalidade_do_processo = 2 #inexigibilidade
					legislacao = ::Base::Legislacao.find_by_titulo("Artigo\t25\tInciso\tI")
				end

				registro_de_preco_do_processo = false
				if dados_do_processo['modalidade_processo_administrativo'] == "R"
					registro_de_preco_do_processo = true
				end

				modalidade_de_licitacao = nil
				if dados_do_processo['modalidade_processo_administrativo'] == "D" || dados_do_processo['modalidade_processo_administrativo'] == "I"
					modalidade_de_licitacao = 8 #dispensa ou inexigibilidade
				else
					if dados_do_processo['modalidade_licitacao'] == "1"
						modalidade_de_licitacao = 0 #convite
					elsif dados_do_processo['modalidade_licitacao'] == "2"
						modalidade_de_licitacao = 1 #tomada de preco
					elsif dados_do_processo['modalidade_licitacao'] == "3"
						modalidade_de_licitacao = 2 #concorrencia publica
					elsif dados_do_processo['modalidade_licitacao'] == "4"
						modalidade_de_licitacao = 3 #concurso
					elsif dados_do_processo['modalidade_licitacao'] == "5" || dados_do_processo['modalidade_licitacao'] == "6"
						modalidade_de_licitacao = 5 #pregao
					elsif dados_do_processo['modalidade_licitacao'] == "7"
						modalidade_de_licitacao = 7 #rdc
					end
				end

				processo = ::Licitacao::Projeto.new(
					pedido_id: pedido.id,
					comissao_id: comissao.id,
					status: 99, #homologado
					legislacao: legislacao,
					numero_do_processo: dados_do_processo['numero_licitacao'],
					horario_da_abertura: dados_do_processo['hora_licitacao'],
					data_da_sessao: dados_do_processo['data_realizacao_licitacao'],
					modalidade_de_licitacao: modalidade_de_licitacao,
					tipo_de_totalizacao: 0, #menor valor
					modalidade_do_processo: modalidade_do_processo,
					data_do_projeto: dados_do_processo['data_realizacao_autuacao_licitacao'].to_date,
					data_de_autuacao: dados_do_processo['data_realizacao_autuacao_licitacao'].to_date,
					data_da_homologacao: dados_do_processo['data_homologacao'].to_date,
					forma_de_agrupamento: 2, #por item
					registro_de_preco: registro_de_preco_do_processo,
					arquivo_id: 0,
					envia_pro_sim: false,
					orcamento_id: orcamento.id
				)

				processo.save(validate: false)
				return processo
			end

			def criar_publicacoes processo, dados_das_publicacoes
				dados_das_publicacoes = [dados_das_publicacoes] if !dados_das_publicacoes.kind_of?(Array)
				dados_das_publicacoes.each do |dados_da_publicacao|
					unless dados_da_publicacao.nil?
						data_publicacao = dados_da_publicacao['data_publicacao_edital'].to_date
						data_flanelografo = data_publicacao.monday? ? data_publicacao - 3.day : data_publicacao - 1.day

						tipo_de_publicao =  if dados_da_publicacao['codigo_publicacao_edital'].to_i == 9
							5
						else
							dados_da_publicacao['codigo_publicacao_edital'].to_i - 1
						end
						processo.publicacoes.create!(
							data_da_publicacao: data_publicacao,
							tipo_de_publicacao: tipo_de_publicao,
							data_de_publicacao_no_flanelografo: data_flanelografo,
							local_publicado: dados_da_publicacao['descricao_publicacao_edital'],
							arquivo_id: 0
						)
					end
				end
			end

			def criar_dotacoes processo, dados_das_dotacoes, orcamento
				dados_das_dotacoes = [dados_das_dotacoes] if !dados_das_dotacoes.kind_of?(Array)
				dados_das_dotacoes.each do |dotacao|
					unless dotacao.nil?
						cod_unidade_orcamentaria = dotacao['codigo_unidade'].gsub(" ", "")
						cod_orgao = dotacao['codigo_orgao'].gsub(" ", "")
						cod_elemento_de_despesa = dotacao['codigo_elemento_despesa'].gsub(" ", "")
						cod_funcao = dotacao['codigo_funcao'].gsub(" ", "")
						cod_subfuncao = dotacao['codigo_subfuncao'].gsub(" ", "")
						cod_natureza_da_acao = dotacao['codigo_projeto_atividade'].gsub(" ", "")
						cod_programa = dotacao['codigo_programa'].gsub(" ", "")
						cod_acao = dotacao['numero_projeto_atividade'].gsub(" ", "")
						cod_fonte_de_recurso = dotacao['codigo_fonte'].gsub(" ", "")

						elemento_de_despesa = orcamento.elementos_de_despesa.find_by_codigo(cod_elemento_de_despesa)
						orgao = orcamento.orgaos.find_by_codigo(cod_orgao)
						unidade_orcamentaria = orcamento.unidades_orcamentarias.find_by(orgao_id: orgao.id, codigo: cod_unidade_orcamentaria)
						funcao = orcamento.funcoes.find_by_codigo(cod_funcao)
						subfuncao = orcamento.subfuncoes.find_by_codigo(cod_subfuncao)
						programa_de_governo = orcamento.programas_de_governo.find_by_codigo(cod_programa)
						natureza_da_acao = orcamento.naturezas_da_acao.find_by_codigo(cod_natureza_da_acao)

						acao = orcamento.acoes.where(codigo: cod_acao, programa_de_governo_id: programa_de_governo.id, natureza_da_acao_id: natureza_da_acao.id ).first
						fonte_de_recurso = ::Base::FonteDeRecursos.where(modulo_id: orcamento.id).select {|fdr| fdr.codigo_tcm == cod_fonte_de_recurso}.first
						orcamento_da_despesa = orcamento.orcamentos_da_despesa.joins(:fonte_de_recursos).joins(elemento_de_despesa_por_subacao: :elemento_de_despesa)
							.joins(elemento_de_despesa_por_subacao: [subacao: [:unidade_orcamentaria, :acao, :funcao, :subfuncao]])
								.where('loa_unidades_orcamentarias.id = ?', unidade_orcamentaria.id)
									.where('base_fontes_de_recursos.id = ?', fonte_de_recurso.id)
										.where('base_elementos_de_despesa.id = ?', elemento_de_despesa.id)
											.where('base_funcoes.id = ?', funcao.id)
												.where('base_subfuncoes.id = ?', subfuncao.id)
													.where('loa_acoes.id = ?', acao.id).first

						if orcamento_da_despesa.nil?
							raise Exception.new("Não foi possível encontrar a dotação com os parâmetros informados no TCM")
						end
						orcamento_da_despesa_por_projeto = processo.orcamentos_da_despesa_por_projetos.new(
							orcamento_da_despesa: orcamento_da_despesa,
							valor: dotacao['valor_dotacao'],
							arquivo_id: 0
						)
						orcamento_da_despesa_por_projeto.save(validate: false)
					end
				end
			end

			def criar_cotacoes_para_pessoas_do_projeto processo
				if processo.processo_licitatorio?
					# neste caso, como é importação e sempre o agrupamento vai ser por item, usaremos os métodos abaixo
					# apenas para automatizar as cotações e definir ganhador de cada item
					processo.send(:criar_cotacoes)

					processo.lotes.each do |lote|
						primeiro_colocado = lote.send(:ranking_de_propostas).keys.first
						lote.update(ganhador_id: primeiro_colocado.id)
						cria_proposta_final(lote)
					end
				end
			end

			def cria_proposta_final lote
				lote.itens_do_projeto_por_pessoa.each {|item_do_projeto_por_pessoa|
					pessoa_do_projeto_do_lote = lote.pessoas_do_projeto_do_lote.find_by(pessoa_do_projeto_id: item_do_projeto_por_pessoa.pessoa_do_projeto_id)
					if pessoa_do_projeto_do_lote.pessoa_do_projeto.eql?(lote.ganhador)
						item_do_projeto_por_pessoa_final = item_do_projeto_por_pessoa.dup
						item_do_projeto_por_pessoa_final.final = true
						item_do_projeto_por_pessoa_final.save
					end
				}
			end

			def cria_categoria_para_elemento_de_despesa codigo
				elemento_de_despesa = ::NaturezaDaDespesa::ElementoDeDespesa.find_by_codigo(codigo)
				::Base::Categoria.find_or_create_by!(codigo: elemento_de_despesa.codigo, titulo: elemento_de_despesa.descricao, tipo: 0).tap do |categoria|
					categoria.elementos_por_categoria.find_or_create_by!(elemento_de_gasto: elemento_de_despesa)
					elemento_de_despesa.sub_elementos_de_despesa.each do |sub_elemento|
						subcategoria = categoria.subcategorias.find_or_create_by!(codigo: sub_elemento.codigo, titulo: sub_elemento.descricao)
						subcategoria.elementos_por_categoria.find_or_create_by!(elemento_de_gasto: sub_elemento)
					end
				end
			end

		end
	end
end
