module Licitacao
class PedidosController < ApplicationController
	include LicitacaoHelper
	include ControllerConcern
	include LicitacoesContabilidadeControllersConcern

	before_action :authenticate_usuario!
	before_action :set_pedido, except: [:index, :new, :create]
	before_action :disponibiliza_dependencias, only: [:create, :new, :update, :edit, :editar_itens]
	before_action :disponibiliza_dependencias_categorias, only: [:create, :new, :update, :edit]
	before_action :disponibiliza_dependencias_subcategorias, only: [:index]
	before_action :acao_corresponde_ao_status_do_pedido?, except: [:index, :new, :create, :arquivo_itens_do_pedido], if: -> { !Configuracao.last.implantacao? }
	before_action :verifica_edicao_do_pedido, only: [:edit], if: -> { !Configuracao.last.implantacao? }

	before_action :autoriza_usuario!, except: [:confirmar_cancelamento,:finalizar_pedido, :reativar_cotacao,
		:anular_preco,:preco,:reativar_item_da_cotacao,:mapa, :motivo_anular_cotacao, :atualizar_pessoas,
		:atualizar_itens, :atualizar_unidades_orcamentarias, :abrir_para_outras_unidades, :atualizar_quantidades,
		:busca_itens, :adiciona_itens, :atualizar_justificativa_da_cotacao, :convidar, :atualizar_data_do_mapa,
		:editar_data_do_mapa, :voltar_para_aberto, :arquivo_itens_do_pedido, :editar_pessoas, :busca_pessoas,
		:adiciona_pessoas, :remove_unidade_e_seus_itens, :zera_quantidade_do_item_da_unidade, :zera_valor_previsto_do_item_da_unidade,
		:duplicar, :selecionar_dotacao, :adicionar_dotacao, :atualiza_dotacao, :excluir_dotacao,
		:atualizar_responsavel_setor_de_compras, :atualizar_responsavel_da_unidade]

	before_action except: [:finalizar_pedido, :reativar_cotacao, :anular_preco,:preco,:reativar_item_da_cotacao, :mapa, :anular_cotacao, :motivo_anular_cotacao, :index, :show, :new, :create, :destroy, :editar_quantidades,:atualizar_quantidades, :editar_pessoas, :atualizar_pessoas] do |controller|
		return if bloqueia_usuario_com_base_em 'update'
	end

	before_action only: [:atualizar_itens, :atualizar_pessoas, :atualizar_quantidades, :atualizar_unidades_orcamentarias] do |controller|
		redirect_to @pedido, alert: 'lista não pode ficar em branco. Alterações não foram salvas.' unless params[:licitacao_pedido]
	end

	before_action only: [:atualizar_quantidades, :zera_quantidade_do_item_da_unidade, :zera_valor_previsto_do_item_da_unidade, :remove_unidade_e_seus_itens ] do |controller|
		redirect_to @pedido, alert: 'Você não tem autorização para editar as quantidades dessa unidade' unless @pedido.verifica_acesso_do_usuario_a_unidades_convidadas(current_usuario, params[:unidade_id].to_i)
	end

	# GET /licitacao/pedidos
	def index
		@unidades_por_usuario = current_usuario.unidades_orcamentarias_por_usuario
		@orcamentos = Orcamento.all.order(exercicio: :desc)
		orcamento = unless query_params["orcamento_id_eq"].blank?
			Orcamento.find(query_params["orcamento_id_eq"])
		else
			contexto_atual
		end
		@unidades_orcamentarias = orcamento.unidades_orcamentarias.order(:codigo, :nome)

		if params[:criado_na_contabilidade].present?
			@q = orcamento.pedidos.where("criado_na_contabilidade = true").order("data_do_pedido DESC, numero::integer DESC").ransack(query_params)
		elsif current_usuario.desenvolvedor?
			@q = orcamento.pedidos.order("data_do_pedido DESC, numero::integer DESC").ransack(query_params)
		elsif current_usuario.setor_de_compras?
			@q = orcamento.pedidos.where("status in (0, 2, 3, 98, 99)").order("data_do_pedido DESC, numero::integer DESC").ransack(query_params)
		else
			if current_usuario.nivel_de_permissao_a_unidades == "todas_as_unidades"
				@q = orcamento.pedidos.joins(:unidades_orcamentarias_por_pedido).where(licitacao_unidades_orcamentarias_por_pedido: {unidade_orcamentaria_id: @unidades_orcamentarias.ids}).order("data_do_pedido DESC, numero DESC").distinct.ransack(query_params)
			else
				@q = orcamento.pedidos.joins(:unidades_orcamentarias_por_pedido).where(licitacao_unidades_orcamentarias_por_pedido: {unidade_orcamentaria_id: @unidades_por_usuario.pluck(:unidade_orcamentaria_id)}).order("data_do_pedido DESC, numero DESC").distinct.ransack(query_params)
			end
		end

		@pedidos = @q.result(distinct: false).paginate(page: params[:page], per_page: 10)
	end

	# GET /licitacao/pedidos/1
	def show
	end

	# GET /licitacao/pedidos/new
	def new
		@pedido = contexto_atual.pedidos.new
	end

	# POST /licitacao/pedidos
	def create
		@pedido = Pedido.new(pedido_params)
		@pedido.usuario = current_usuario
		@pedido.orcamento = contexto_atual

		if @pedido.save
			if params[:ir_para_itens].present?
				redirect_path = { action: :editar_itens, id: @pedido.id }
			else
				redirect_path = @pedido
			end
			redirect_to redirect_path, notice: 'Pedido foi criado com sucesso.'
		else
			render :new
		end
	end

	# GET /licitacao/pedidos/1/edit
	def edit
	end

	# PATCH/PUT /licitacao/pedidos/1
	def update
		if @pedido.verifica_acesso_do_usuario(current_usuario)
			if @pedido.update( pedido_params )
				redirect_to @pedido, notice: 'Pedido foi atualizado com sucesso.'
			else
				flash.now[:alert] = "Não foi possivel atualizar pedido."
				render :edit
			end
		else
			redirect_to @pedido, notice: 'Você não tem autorização para editar esse pedido'
		end
	end

	# DELETE /licitacao/pedidos/1
	def destroy
		if @pedido.verifica_acesso_do_usuario(current_usuario)
			if @pedido.cancelado?
				redirect_to @pedido, notice: 'Pedido cancelado não pode ser apagado.'
			elsif @pedido.aguardando_outras_unidades? || @pedido.coleta_de_preco?
				redirect_to @pedido, notice: 'Não é possivel deletar um pedido nessa etapa.'
			else
				mensagem = apaga_e_retorna_mensagem(@pedido)
				redirect_to licitacao_pedidos_url, mensagem
			end
		else
				redirect_to @pedido, notice: 'Você não tem autorização para excluir esse pedido'
		end
	end

	# GET /licitacao/pedidos/1/itens
	def editar_itens
		disponibiliza_dependencias_itens
		if @pedido.itens_do_pedido.empty?
			@pedido.itens_do_pedido.build
		end
		@action = params[:action]
		@unidade_id = params[:unidade_id].present? ? params[:unidade_id].to_i : @pedido.unidade_orcamentaria_id
		@pedido.cria_itens_do_pedido_para_unidade @unidade_id
	end

	# PATCH /licitacao/pedidos/1/itens
	def atualizar_itens
		return if bloqueia_usuario_com_base_em 'editar_itens'
		if @pedido.verifica_acesso_do_usuario(current_usuario)
			if @pedido.update(itens_params)
				if @pedido.divide_lote_no_pedido?

					@pedido.lotes_do_pedido.destroy_all
					@pedido.itens_do_lote_do_pedido.destroy_all

					@pedido.itens_do_pedido.each do |item|
						lote_escolhido = @pedido.lotes_do_pedido.find_by(numero: item.lote_do_pedido)
						
						if lote_escolhido.nil?
							lote_escolhido = @pedido.lotes_do_pedido.create!(numero: item.lote_do_pedido)
						end
						
						item_do_pedido = Licitacao::ItemDoLoteDoPedido.create!(item_do_pedido_id: item.id ,lote_do_pedido_id: lote_escolhido.id, ordem: item.sequencia_do_lote )
					
					end

					@pedido.lotes_do_pedido.each do |lote|
						nova_sequencia = lote.itens_do_lote_do_pedido.where('ordem is not null AND ordem != 0').count
						lote.itens_do_lote_do_pedido.where('ordem is null OR ordem = 0').each do |item|
							nova_sequencia += 1;
							item.update_column(:ordem, nova_sequencia);
						end
					end
				end

				if Configuracao.last.ordencacao_de_itens_pela_sequencia?
					nova_sequencia = @pedido.itens_do_pedido.where('sequencia is not null AND sequencia != 0').count
					@pedido.itens_do_pedido.where('sequencia is null OR sequencia = 0').each do |item|
						nova_sequencia += 1;
						item.update_column(:sequencia, nova_sequencia);
					end
				end

				if params[:continuar_editando].present?
					redirect_to itens_licitacao_pedido_path(@pedido), notice: 'Os itens cadastrados foram salvos com sucesso.'
				else
					redirect_to @pedido, notice: 'Pedido foi atualizado com sucesso.'
				end
			else
				@action = params[:action]
				@unidade_id = params[:unidade_id].present? ? params[:unidade_id].to_i : @pedido.unidade_orcamentaria_id
				disponibiliza_dependencias_itens
				flash.now[:alert] = "Não foi possivel adicionar os itens ao pedido."
				render :editar_itens
			end
		else
			redirect_to @pedido, notice: 'Você não tem autorização para editar os itens desse pedido'
		end
	end

	# GET /licitacao/pedidos/1/busca_itens
	def busca_itens
		return if bloqueia_usuario_com_base_em 'editar_itens'
		disponibiliza_dependencias_busca_itens
		@q = Base::Item.where(esconder: false).where(categoria: @pedido.categorias_dos_itens).where.not(id: @pedido.itens_do_pedido.map(&:item_id)).search(params[:q])
		@itens = params[:q].try(:values).try(:delete_if, &:empty?).try(:present?) ? @q.result(distinct: false) : []
		if @itens.size > 100
			@qtd_removida = @itens.size - 100
			@itens = @itens.limit(100)
		end
	end

	# PATCH /licitacao/pedidos/1/adiciona_itens
	def adiciona_itens
		return if bloqueia_usuario_com_base_em 'editar_itens'
		@action = params[:action]
		if params[:itens] && params[:itens].size > 0
			quantidade = @pedido.adiciona_itens(params[:itens])
			disponibiliza_dependencias_itens
			flash.now[:notice] = quantidade > 1 ? "#{quantidade} itens adicionados com sucesso" : "#{quantidade} item adicionado com sucesso"
			render :editar_itens
		else
			redirect_to busca_itens_licitacao_pedido_path(@pedido), alert: "Nenhum item foi selecionado."
		end
	end

	# GET /licitacao/pedidos/1/unidades_orcamentarias
	def editar_unidades_orcamentarias
		disponibiliza_dependencias_unidades_convidadas
		if @pedido.pode_convidar_unidades?
			if params[:todas].present? && params[:todas] == "true"
				unidades_existentes = @pedido.unidades_orcamentarias_por_pedido.map(&:unidade_orcamentaria_id)
				@unidades_orcamentarias.where.not(id: unidades_existentes.compact).each do |unidade_orcamentaria|
					@pedido.unidades_orcamentarias_por_pedido.build(unidade_orcamentaria_id: unidade_orcamentaria.id) unless unidade_orcamentaria.ordenadores_de_despesa.empty?
				end
			else
				@pedido.unidades_orcamentarias_por_pedido.build if @pedido.unidades_orcamentarias_por_pedido.count <= 1
			end
		else
			redirect_to @pedido, tab: "unidades_orcamentarias", notice: 'Prazo para as unidades convidadas foram encerradas.'
		end
	end

	# PATCH /licitacao/pedidos/1/unidades_orcamentarias
	def atualizar_unidades_orcamentarias
		return if bloqueia_usuario_com_base_em 'editar_unidades_orcamentarias'
		if @pedido.verifica_acesso_do_usuario(current_usuario)
			if @pedido.update( unidades_orcamentarias_params )
				redirect_to licitacao_pedido_path(@pedido) + "?tab=unidades_orcamentarias", notice: 'Unidades do pedido atualizadas com sucesso.'
			else
				disponibiliza_dependencias_unidades_convidadas
				render :editar_unidades_orcamentarias
			end
		else
			redirect_to @pedido, notice: 'Você não tem autorização para atualizar a unidades desse pedido'
		end
	end

	# GET /licitacao/pedidos/1/quantidades
	def editar_quantidades
		@action = params[:action]
		@pedido.itens_do_pedido.build if @pedido.itens_do_pedido.empty?
		@unidade_id = params[:unidade_id].present? ? params[:unidade_id].to_i : @pedido.unidade_orcamentaria_id
		@unidade_orcamentaria_convidada = @pedido.unidades_orcamentarias.find(@unidade_id)
		@pedido.cria_itens_do_pedido_para_unidade @unidade_id
	end

	# PATCH /licitacao/pedidos/1/quantidades
	def atualizar_quantidades
		return if bloqueia_usuario_com_base_em 'editar_quantidades'
		if @pedido.update( quantidade_params )
			mensagem_complementacao_pedido
			redirect_to licitacao_pedido_path(@pedido, tab: "unidades_orcamentarias"), notice: 'Pedido foi atualizado com sucesso.'
		else
			@action = params[:action]
			@unidade_id = params[:unidade_id].present? ? params[:unidade_id].to_i : @pedido.unidade_orcamentaria_id
			render :editar_quantidades, tab: "unidades_orcamentarias"
		end
	end

	# PATCH /licitacao/pedidos/1/zera_quantidade_do_item_da_unidade
	def zera_quantidade_do_item_da_unidade
		return if bloqueia_usuario_com_base_em 'editar_quantidades'
		if @pedido.zera_quantidade_do_item_da_unidade(params[:item_da_unidade_id].to_i)
			redirect_to licitacao_pedido_path(@pedido, tab: "unidades_orcamentarias"), notice: 'Quantidade removida do item com sucesso.'
		else
			@action = params[:action]
			@unidade_id = params[:unidade_id].present? ? params[:unidade_id].to_i : @pedido.unidade_orcamentaria_id
			render :editar_quantidades
		end
	end

	# PATCH /licitacao/pedidos/1/zera_valor_previsto_do_item_da_unidade
	def zera_valor_previsto_do_item_da_unidade
		return if bloqueia_usuario_com_base_em 'editar_quantidades'
		if @pedido.zera_valor_previsto_do_item_da_unidade(params[:item_da_unidade_id].to_i)
			redirect_to licitacao_pedido_path(@pedido, tab: "unidades_orcamentarias"), notice: 'O valor previsto foi removido do item com sucesso.'
		else
			@action = params[:action]
			@unidade_id = params[:unidade_id].present? ? params[:unidade_id].to_i : @pedido.unidade_orcamentaria_id
			render :editar_quantidades
		end
	end

	# PATCH /licitacao/pedidos/1/remove_unidade_e_seus_itens
	def remove_unidade_e_seus_itens
		@action = params[:action]
		return if bloqueia_usuario_com_base_em 'editar_quantidades'
		if @pedido.remove_unidade_e_seus_itens(params[:unidade_por_pedido_id])
			redirect_to licitacao_pedido_path(@pedido, tab: "unidades_orcamentarias"), notice: 'Unidade desistida com sucesso.'
		else
			render :show, tab: "unidades_orcamentarias"
		end
	end

	# GET /licitacao/pedidos/1/fornecedores
	def editar_pessoas
		disponibiliza_dependencias_pessoas
		@pedido.pessoas_do_pedido.build if @pedido.pessoas_do_pedido.empty?
	end

	# PATCH /licitacao/pedidos/1/fornecedores
	def atualizar_pessoas
		return if bloqueia_usuario_com_base_em 'editar_pessoas'
		if @pedido.verifica_acesso_do_usuario(current_usuario)
			if @pedido.update(pessoas_params)
				if params[:continuar_editando].present?
					disponibiliza_dependencias_pessoas
					flash.now[:notice] = "Fornecedores cadastrados foram salvos com sucesso."
					render :editar_pessoas
				else
					redirect_to licitacao_pedido_path(@pedido) + "?tab=fornecedores", notice: 'Pedido foi atualizado com sucesso.'
				end
			else
				disponibiliza_dependencias_pessoas
				render :editar_pessoas
			end
		else
			redirect_to @pedido, notice: 'Você não tem autorização para atualizar as pessoas desse pedido'
		end
	end

	# GET /licitacao/pedidos/1/busca_pessoas
	def busca_pessoas
		return if bloqueia_usuario_com_base_em 'editar_pessoas'
		@q = Base::Pessoa.order(:id).ransack(query_params)
		disponibiliza_dependencias_busca_pessoas
		@pessoas = @q.result(distinct: true)
		@categorias = Base::Categoria.where(id: @pedido.categorias_do_pedido.pluck(:categoria_id))
		@subcategorias = Array.new

		if params[:q].present? && params[:q][:categorias_da_pessoa_categoria_id_eq].present?
			@subcategorias = Base::Categoria.find_by(id: params[:q][:categorias_da_pessoa_categoria_id_eq]).subcategorias rescue Array.new
		end

		if @pessoas.size > 100
			@qtd_removida = @pessoas.size - 100
			@pessoas = @pessoas.limit(100)
		end
	end

	# PATCH /licitacao/pedidos/1/adiciona_pessoas
	def adiciona_pessoas
		return if bloqueia_usuario_com_base_em 'editar_pessoas'
		if params[:pessoas] && params[:pessoas].size > 0
			quantidade = @pedido.adiciona_pessoas(params[:pessoas])
			disponibiliza_dependencias_pessoas
			flash.now[:notice] = quantidade > 1 ? "#{quantidade} pessoas adicionados com sucesso" : "#{quantidade} pessoa adicionado com sucesso"
			render :editar_pessoas
		else
			redirect_to busca_pessoas_licitacao_pedido_path(@pedido), alert: "Nenhum fornecedor foi selecionado."
		end
	end

	# GET /licitacao/pedidos/1/selecionar_dotacao
	def selecionar_dotacao
		return if bloqueia_usuario_com_base_em 'update'
		if params[:dotacao_id].present? && !params[:dotacao_id].nil?
			@orcamento_da_despesa_por_pedido = @pedido.orcamentos_da_despesa_por_pedido.find(params[:dotacao_id])
		else
			@orcamento_da_despesa_por_pedido = @pedido.orcamentos_da_despesa_por_pedido.new
		end
		carrega_select_box
	end

	# POST /licitacao/pedidos/1/adicionar_dotacao
	def adicionar_dotacao
		@orcamento_da_despesa_por_pedido = @pedido.orcamentos_da_despesa_por_pedido.new(dotacao_params)
		if @orcamento_da_despesa_por_pedido.save
			redirect_path = licitacao_pedido_path(@pedido, tab: "dotacoes_do_pedido")
			redirect_to redirect_path, success: 'Dotação foi adicionada com sucesso.'
		else
			carrega_select_box
			render :selecionar_dotacao
		end
	end

	# POST /licitacao/pedidos/1/atualiza_dotacao
	def atualiza_dotacao
		return if bloqueia_usuario_com_base_em 'update'
		@orcamento_da_despesa_por_pedido = @pedido.orcamentos_da_despesa_por_pedido.find(dotacao_params[:id])
		if @orcamento_da_despesa_por_pedido.update(dotacao_params)
			redirect_path = licitacao_pedido_path(@pedido, tab: "dotacoes_do_pedido")
			redirect_to redirect_path, success: 'Dotação foi atualizada com sucesso.'
		else
			carrega_select_box
			render :selecionar_dotacao
		end
	end

	# DELETE /licitacao/pedidos/1/excluir_dotacao/1
	def excluir_dotacao
		return if bloqueia_usuario_com_base_em 'update'
		orcamento_da_despesa_por_pedido = Licitacao::OrcamentoDaDespesaPorPedido.find(params[:orcamento_da_despesa_por_pedido_id])

		redirect_to licitacao_pedido_path(orcamento_da_despesa_por_pedido.pedido) + "?tab=dotacoes_do_pedido", alert: "Essa ação não é permitida nessa etapa" unless acao_permitida? orcamento_da_despesa_por_pedido.pedido, action_name.to_sym
		mensagem = apaga_e_retorna_mensagem(orcamento_da_despesa_por_pedido)
		redirect_to licitacao_pedido_path(orcamento_da_despesa_por_pedido.pedido) + "?tab=dotacoes_do_pedido", mensagem
	end

	# PATCH licitacao/pedidos/1/abrir_para_outras_unidades
	def abrir_para_outras_unidades
		return if bloqueia_usuario_com_base_em 'editar_unidades_orcamentarias'
		if @pedido.abrir_para_outras_unidades! && @pedido.verifica_acesso_do_usuario(current_usuario)
			redirect_to @pedido, notice: 'Pedido agora está aberto para outras unidades.'
		else
			mensagem_de_erro = if @pedido.errors.any?
				"Ocorreu um erro com pedido, por favor confira se este está consistente"
			else
				"Não é possível passar da fase atual para a requisitada."
			end
			redirect_to @pedido, alert: mensagem_de_erro
		end
	end

	# PATCH licitacao/pedidos/1/coletar_precos
	def coletar_precos
		return if bloqueia_usuario_com_base_em 'update'
		if @pedido.coletar_precos! && @pedido.verifica_acesso_do_usuario(current_usuario)
			redirect_to @pedido, notice: 'Pedido agora está aberto para coleta de preços.'
		else
			mensagem_de_erro = if @pedido.errors.any?
				@pedido.errors.full_messages.join(",")
			else
				"Não é possível passar da fase atual para a requisitada."
			end
			redirect_to @pedido, alert: mensagem_de_erro
		end
	end

	# PATCH /licitacao/pedidos/1/convidar/1
	def convidar
		return if bloqueia_usuario_com_base_em 'enviar_cotacao','licitacao/pessoas_do_pedido'
		pessoa_do_pedido = Licitacao::PessoaDoPedido.find_by(id: params[:pessoa_do_pedido_id])

		if pessoa_do_pedido && pessoa_do_pedido.pedido_id = @pedido.id
			if !pessoa_do_pedido.valido?
				redirect_to pessoa_do_pedido, alert: "Essa cotação está anulada"
			elsif pessoa_do_pedido.convidar
				redirect_to pessoa_do_pedido, notice: "#{pessoa_do_pedido.pessoa.try(:cpf_ou_cnpj_e_nome)} foi convidado por e-mail a enviar a cotação."
			else
				redirect_to pessoa_do_pedido, alert: "Fornecedor não tem e-mail informado, altere o cadastro informando um e-mail válido."
			end
		else
			redirect_to licitacao_pedido_path(@pedido) + "?tab=fornecedores", alert: "Fornecedor não existe" and return
		end
	end

	# GET /licitacao/pedidos/1/motivo_anular_item/1
	def motivo_anular_item
		return if bloqueia_usuario_com_base_em 'anular_item'
		if @pedido.verifica_acesso_do_usuario(current_usuario)
			if Licitacao::ItemDoPedido.exists?(params[:item_do_pedido_id])
				@item_do_pedido = Licitacao::ItemDoPedido.find(params[:item_do_pedido_id])
			else
				mensagem_de_erro = if @pedido.errors.any?
					"Ocorreu um erro com pedido, por favor confira se este está consistente"
				else
					"Item não existe"
				end
				redirect_to @pedido, alert: mensagem_de_erro
			end
		else
			redirect_to @pedido, notice: 'Você não tem autorização para anular itens desse pedido'
		end
	end

	# POST /licitacao/pedidos/1/anular_item/1
	def anular_item
		@item_do_pedido = Licitacao::ItemDoPedido.find(params[:item_do_pedido_id])
		if @pedido.verifica_acesso_do_usuario(current_usuario)
			if @item_do_pedido.update(licitacao_item_do_pedido_params)
				if @item_do_pedido.valido == false
					@item_do_pedido.itens_do_pedido_por_pessoa.each do |item_pedido|
						item_pedido.valido = false
						item_pedido.motivo = @item_do_pedido.motivo
						item_pedido.save
					end
				end
				redirect_to licitacao_pedido_path(@pedido) + "?tab=itens_do_pedido", notice: 'Item anulado com sucesso'
			else
				render :motivo_anular_item
			end
		else
			redirect_to @pedido, notice: 'Você não tem autorização para anular intens desse pedido'
		end
	end

	# POST /licitacao/pedidos/1/reativar_item_da_cotacao/1
	def reativar_item_da_cotacao
		return if bloqueia_usuario_com_base_em 'enviar_cotacao','licitacao/pessoas_do_pedido'
		@item_do_pedido_por_pessoa = Licitacao::ItemDoPedidoPorPessoa.find(params[:item_do_pedido_por_pessoa_id])
		if @item_do_pedido_por_pessoa.update(valido: true, motivo: '')
			mensagem = 'Valor reativado com sucesso'
		else
			mensagem = "Não foi possível alterar devido ao seguintos erros: #{@item_do_pedido_por_pessoa.errors.to_a.join(", ")}"
		end
		if params[:cotacao] && !params[:pessoa_do_pedido_id].nil?
			redirect_to licitacao_pessoa_do_pedido_path(params[:pessoa_do_pedido_id])
		else
			redirect_to mapa_licitacao_pedido_path(@item_do_pedido_por_pessoa.pessoa_do_pedido.pedido), notice: mensagem
		end
	end

	# GET /licitacao/pedidos/1/motivo_anular_cotacao/1
	def motivo_anular_cotacao
		return if bloqueia_usuario_com_base_em 'anular_cotacao'
		if Licitacao::PessoaDoPedido.exists?(params[:pessoa_do_pedido_id])
			@pessoa_do_pedido = Licitacao::PessoaDoPedido.find(params[:pessoa_do_pedido_id])
		else
			mensagem_de_erro = if @pedido.errors.any?
				"Ocorreu um erro com pedido, por favor confira se este está consistente"
			else
				"Fornecedor não existe"
			end
			redirect_to @pedido, alert: mensagem_de_erro
		end
	end

	# POST /licitacao/pedidos/1/anular_cotacao/1
	def anular_cotacao
		@pessoa_do_pedido = Licitacao::PessoaDoPedido.find(params[:pessoa_do_pedido_id])
		if @pedido.verifica_acesso_do_usuario(current_usuario)
			if @pessoa_do_pedido.update(licitacao_pessoa_do_pedido_params)
				redirect_to @pessoa_do_pedido, notice: 'Cotação anulada com sucesso'
			else
				render :motivo_anular_cotacao
			end
		else
			redirect_to @pedido, notice: 'Você não tem autorização para anular intens desse pedido'
		end
	end

	# GET /licitacao/pedidos/1/reativar_cotacao/1
	def reativar_cotacao
		return if bloqueia_usuario_com_base_em 'anular_cotacao'
		@pessoa_do_pedido = Licitacao::PessoaDoPedido.find(params[:pessoa_do_pedido_id])
		if @pedido.verifica_acesso_do_usuario(current_usuario)
			if @pedido.pessoas_do_pedido.where(valido:true, pessoa_id: @pessoa_do_pedido.pessoa.id) == []
				if @pessoa_do_pedido.update(valido: true, motivo: '')
					mensagem = 'Cotação reativada com sucesso'
				else
					mensagem = "Não foi possível alterar devido ao seguintos erros: #{@pessoa_do_pedido.errors.to_a.join(", ")}"
				end
				redirect_to @pessoa_do_pedido, notice: mensagem
			else
				redirect_to @pessoa_do_pedido, notice: 'Não foi possivel reativer essa cotação, por que já existe outra cotação ativa para esse forneçedor.'
			end
		else
			redirect_to @pedido, notice: 'Você não tem autorização para reeativar cotações desse pedido'
		end
	end

	# GET /licitacao/preco/1
	def preco
		return if bloqueia_usuario_com_base_em 'enviar_cotacao','licitacao/pessoas_do_pedido'
		if Licitacao::ItemDoPedidoPorPessoa.exists?(params[:item_do_pedido_por_pessoa_id])
			@item_do_pedido_por_pessoa = Licitacao::ItemDoPedidoPorPessoa.find(params[:item_do_pedido_por_pessoa_id])
		else
			mensagem_de_erro = if @pedido.errors.any?
				"Ocorreu um erro com pedido, por favor confira se este está consistente"
			else
				"Fornecedor não existe"
			end
			redirect_to @pedido, alert: mensagem_de_erro
		end
	end

	# POST /licitacao/anular_preco/1
	def anular_preco
		return if bloqueia_usuario_com_base_em 'enviar_cotacao', 'licitacao/pessoas_do_pedido'
		@item_do_pedido_por_pessoa = Licitacao::ItemDoPedidoPorPessoa.find(params[:item_do_pedido_por_pessoa_id])

		if @item_do_pedido_por_pessoa.update(licitacao_item_do_pedido_por_pessoa_params)
			if params[:cotacao] && !params[:pessoa_do_pedido_id].nil?
				redirect_to licitacao_pessoa_do_pedido_path(params[:pessoa_do_pedido_id]), notice: 'Preço anulado com sucesso.'
			else
				redirect_to mapa_licitacao_pedido_path(@pedido), notice: 'Preço anulado com sucesso.'
			end
		else
			render :preco
		end
	end

	# GET /licitacao/pedidos/1/justificativa_da_cotacao
	def editar_justificativa_da_cotacao
	end

	# PATCH /licitacao/pedidos/1/justificativa_da_cotacao
	def atualizar_justificativa_da_cotacao
		return if bloqueia_usuario_com_base_em 'editar_justificativa_da_cotacao','licitacao/pedidos'
		@pedido.update(justificativa_da_cotacao_params)
		redirect_to licitacao_pedido_path(@pedido) + "?tab=fornecedores", notice: 'Justificativa da cotação foi atualizado com sucesso.'
	end

	# GET /licitacao/pedidos/1/responsavel_pelo_setor_de_compras
	def adicionar_responsavel_setor_de_compras
	end

	# PATCH /licitacao/pedidos/1/responsavel_pelo_setor_de_compras
	def atualizar_responsavel_setor_de_compras
		return if bloqueia_usuario_com_base_em('adicionar_responsavel_setor_de_compras', 'licitacao/pedidos')
		@pedido.update(responsavel_setor_de_compras_params)
		redirect_to licitacao_pedido_path(@pedido) + "?tab=fornecedores", notice: 'Responsavel foi atualizado com sucesso.'
	end

	# GET /licitacao/pedidos/1/mapa
	def mapa
		return if bloqueia_usuario_com_base_em 'enviar_cotacao', 'licitacao/pessoas_do_pedido'
		redirect_to @pedido, alert: 'Não é possível acessar o mapa nesse momento.' unless (@pedido.fechado? || @pedido.projeto_gerado?)
	end

	# GET /licitacao/pedidos/1/mapa/editar_data_do_mapa
	def editar_data_do_mapa
		return if bloqueia_usuario_com_base_em 'enviar_cotacao', 'licitacao/pessoas_do_pedido'
		redirect_to @pedido, alert: 'Não é possível atualizar a data de impressão do mapa nesse momento.' unless (@pedido.fechado? || @pedido.projeto_gerado?)
	end

	# PATCH /licitacao/pedidos/1/mapa/atualizar_data_do_mapa
	def atualizar_data_do_mapa
		@pedido.update(data_do_mapa_params)
		redirect_to mapa_licitacao_pedido_path(@pedido), notice: "Data de impressão do mapa de cotação foi atualizado."
	end

	# GET	/licitacao/pedidos/1/arquivo_itens_do_pedido
	def arquivo_itens_do_pedido
		respond_to do |format|
			format.xlsx {
				response.headers['Content-Disposition'] = "attachment; filename=\"itens_do_pedido.xlsx\""
			}
		end
	end

	# PATCH /licitacao/pedidos/1/voltar_status_aberto
	def voltar_para_aberto
		return if bloqueia_usuario_com_base_em 'editar_pessoas'
		if @pedido.verifica_acesso_do_usuario(current_usuario)
			if @pedido.voltar_para_aberto!
				redirect_to @pedido, success: 'Pedido reaberto com sucesso.'
			else
				redirect_to @pedido, alert: 'Não foi possivel reabrir o pedido.'
			end
		else
			redirect_to @pedido, notice: 'Você não tem autorização para reabrir esse pedido'
		end
	end

	# GET /licitacao/pedidos/1/cancelar
	def confirmar_cancelamento
		return if bloqueia_usuario_com_base_em 'cancelar'
	end

	# PATCH /licitacao/pedidos/1/cancelar
	def cancelar
		@pedido.motivo_do_cancelamento = cancelamento_params[:motivo_do_cancelamento]
		if @pedido.cancelar! && @pedido.verifica_acesso_do_usuario(current_usuario)
			redirect_to @pedido, notice: 'Pedido foi cancelado com sucesso.'
		else
			render :confirmar_cancelamento
		end
	end

	# PATCH /licitacao/pedidos/1/finalizar
	def finalizar_pedido
		return if bloqueia_usuario_com_base_em 'editar_pessoas'
		if @pedido.verifica_acesso_do_usuario(current_usuario)
			if @pedido.fechar!
				redirect_to @pedido, success: 'Pedido finalizado com sucesso.'
			else
				redirect_to @pedido, alert: 'Não foi possivel finalizar o pedido.'
			end
		else
			redirect_to @pedido, notice: 'Você não tem autorização para finalizar esse pedido'
		end
	end

	# POST /licitacao/pedidos/1/duplicar
	def duplicar
		if @pedido.duplica_pedido(contexto_atual, params[:com_cotacao].present?)
			redirect_to Licitacao::Pedido.last, success: 'Pedido foi duplicado com sucesso.'
		else
			redirect_to @pedido, alert: "Não foi possível duplicar o pedido. #{@pedido.erro_duplicacao_de_pedido}"
		end
	end

	def cadastrar_transferencia_do_orcamento
	end

	def transferir_orcamento
		if @pedido.transferir_orcamento
			redirect_to contabilidade_pedido_path(@pedido), success: "Pedido foi transferido com sucesso"
		else
			flash[:alert] = @pedido.errors[:transferencia].join(", ")
			render :cadastrar_transferencia_do_orcamento
		end
	end

	def cadastrar_responsavel_da_unidade
		@unidade_orcamentaria_por_pedido = Licitacao::UnidadeOrcamentariaPorPedido.find_by(id: params[:unidade_orcamentaria_por_pedido_id])
	end

	def atualizar_responsavel_da_unidade
		if @pedido.update(unidades_orcamentarias_params)
			redirect_to @pedido, notice: 'Responsável cadastrado com sucesso'
		else
			render :cadastrar_responsavel_do_pedido
		end
	end

	private

	def set_pedido
		@pedido = Pedido.find( params[:id] )
	end

	def disponibiliza_dependencias
		@configuracao = Configuracao.last
		if current_usuario.tipo_de_poder == 'ambos'
			@orgaos = contexto_atual.orgaos_do_usuario(current_usuario).joins(:tipo_de_unidade_administrativa).where.not(base_tipos_de_unidades_administrativas: {codigo: '99'}).order( :codigo )
		else
			poder_usuario = current_usuario.tipo_de_poder == 'legislativo' ? 0 : 1
			@orgaos = contexto_atual.orgaos_do_usuario(current_usuario).joins(:tipo_de_unidade_administrativa).where(base_tipos_de_unidades_administrativas: {poder_associado: poder_usuario}).order( :codigo )
		end
		@status = Licitacao::Pedido.status.except("cancelado").collect { |t| [ "#{t[0].humanize}", t[0] ] }
	end

	def disponibiliza_dependencias_itens
		@item = Base::Item.new
		@itens = Base::Item.where(categoria: @pedido.categorias_dos_itens).where(esconder: false).includes(:unidade_de_medida)
		@unidades_de_medida = UnidadeDeMedida.all
		@ncms = Ncm.order(:descricao).all
		@tipos = Licitacao::ItemDoPedido.tipos
		
		if @pedido.possui_periodicidade_nos_itens?
			@tipos = @tipos.slice(:por_preco)
		end
	end

	def disponibiliza_dependencias_pessoas
		@pessoa = Base::Pessoa.new
		@pessoas = Base::Pessoa.includes(:tipo_de_pessoa).all
	end

	def disponibiliza_dependencias_unidades_convidadas
		configuracao = Configuracao.last
		poder_associado = configuracao.camara_municipal? ? '0' : '1'
		@unidades_orcamentarias = contexto_atual.unidades_orcamentarias.joins(:tipo_de_unidade_administrativa).where.not(loa_unidades_orcamentarias: { id: @pedido.unidade_orcamentaria_id }, base_tipos_de_unidades_administrativas: {codigo: '99'}).where(base_tipos_de_unidades_administrativas: {poder_associado: poder_associado})
	end

	def disponibiliza_dependencias_busca_itens
		@categorias = @pedido.categorias_dos_itens
	end

	def disponibiliza_dependencias_busca_pessoas
		@tipos_de_pessoa = Base::TipoDePessoa.all
		@cnaes = Base::Cnae.all
	end

	def disponibiliza_dependencias_categorias
		@categorias = Base::Categoria.principais.order(:codigo)
		@subcategorias = Base::Categoria.subcategorias
	end

	def disponibiliza_dependencias_subcategorias
		@subcategorias = Base::Categoria.includes([:subcategorias]).all.select(&:pode_ter_itens?).sort_by {|categoria| categoria.titulo}
	end

	def carrega_select_box
		if @orcamento_da_despesa_por_pedido.persisted? && !@orcamento_da_despesa_por_pedido.unidade_orcamentaria.nil?
			@orcamento_da_despesa_por_pedido.subacao_id =  @orcamento_da_despesa_por_pedido.subacao.id
			@orcamento_da_despesa_por_pedido.elemento_de_despesa_por_subacao_id =  @orcamento_da_despesa_por_pedido.elemento_de_despesa_por_subacao.id
			@preenchimento_orcamento_da_despesa_por_pedido = @orcamento_da_despesa_por_pedido.try(:unidade_orcamentaria).try(:id)

			@unidades_orcamentarias = [@orcamento_da_despesa_por_pedido.unidade_orcamentaria]
			@elementos_de_despesa_por_subacao = Loa::ElementoDeDespesaPorSubacao.includes(:elemento_de_despesa).where(subacao_id:  @orcamento_da_despesa_por_pedido.try(:orcamento_da_despesa).try(:elemento_de_despesa_por_subacao).try(:subacao_id) ).order('base_elementos_de_despesa.codigo').all
			@orcamentos_da_despesa = Loa::OrcamentoDaDespesa.where( elemento_de_despesa_por_subacao_id:  @orcamento_da_despesa_por_pedido.try(:orcamento_da_despesa).try(:elemento_de_despesa_por_subacao_id) ).order(:fonte_de_recursos_id)
			elemento_de_despesa_por_subacao = Loa::ElementoDeDespesaPorSubacao.where( id: @orcamento_da_despesa_por_pedido.try(:orcamento_da_despesa).try(:elemento_de_despesa_por_subacao_id) ).first
			@sub_elementos_de_despesa = Contabilidade::SubElementoDeDespesa.ativos.where( elemento_de_despesa_id: elemento_de_despesa_por_subacao.try(:elemento_de_despesa_id) )

			clausulas = { unidade_orcamentaria_id: @orcamento_da_despesa_por_pedido.unidade_orcamentaria.id }
			@subacoes = contexto_atual.subacoes.joins(:elementos_de_despesa_por_subacao).where(clausulas).distinct

		elsif params[:licitacao_orcamento_da_despesa_por_pedido].present?
			@preenchimento_orcamento_da_despesa_por_pedido = params[:licitacao_orcamento_da_despesa_por_pedido][:unidade_orcamentaria_id]

			@orcamento_da_despesa_por_pedido.subacao_id =  params[:licitacao_orcamento_da_despesa_por_pedido][:subacao_id]
			@orcamento_da_despesa_por_pedido.elemento_de_despesa_por_subacao_id =  params[:licitacao_orcamento_da_despesa_por_pedido][:elemento_de_despesa_por_subacao_id]

			@unidades_orcamentarias = Loa::UnidadeOrcamentaria.where(id: params[:licitacao_orcamento_da_despesa_por_pedido][:unidade_orcamentaria_id])
			@elementos_de_despesa_por_subacao = Loa::ElementoDeDespesaPorSubacao.includes(:elemento_de_despesa).where(subacao_id: params[:licitacao_orcamento_da_despesa_por_pedido][:subacao_id]).order('base_elementos_de_despesa.codigo').all
				
			@orcamentos_da_despesa = Loa::OrcamentoDaDespesa.where( elemento_de_despesa_por_subacao_id:  params[:licitacao_orcamento_da_despesa_por_pedido][:elemento_de_despesa_por_subacao_id]).order(:fonte_de_recursos_id)

			if @orcamento_da_despesa_por_pedido.elemento_de_despesa_por_subacao_id.present?
				elemento_de_despesa_por_subacao = Loa::ElementoDeDespesaPorSubacao.find(@orcamento_da_despesa_por_pedido.elemento_de_despesa_por_subacao_id)
				@sub_elementos_de_despesa = Contabilidade::SubElementoDeDespesa.ativos.where( elemento_de_despesa_id: elemento_de_despesa_por_subacao.elemento_de_despesa_id ).order(:codigo)
			else
				@sub_elementos_de_despesa = []
			end

			clausulas = { unidade_orcamentaria_id: params[:licitacao_orcamento_da_despesa_por_pedido][:unidade_orcamentaria_id] }
			@subacoes = Loa::Subacao.joins('left join loa_acoes as b on loa_subacoes.acao_id = b.id left join contabilidade_solicitacao_de_alteracao_orcamentarias as c on b.solicitacao_de_alteracao_orcamentaria_id = c.id').where('(c.status = ? or b.solicitacao_de_alteracao_orcamentaria_id is null)', Contabilidade::SolicitacaoDeAlteracaoOrcamentaria.status["confirmado"]).where(clausulas).distinct
		else
			#@unidades_orcamentarias = @pedido.unidades_orcamentarias
			if @pedido.verifica_acesso_do_usuario_principal(current_usuario)
				@unidades_orcamentarias = @pedido.unidades_orcamentarias
			else
				unidades_do_usuario = current_usuario.unidades_orcamentarias.pluck(:id)
				@unidades_orcamentarias = @pedido.unidades_orcamentarias.where('loa_unidades_orcamentarias.id in (?)', unidades_do_usuario)
			end

			@elementos_de_despesa_por_subacao = []
			@orcamentos_da_despesa = []
			@sub_elementos_de_despesa = []
			@subacoes = []
		end
	end

	# Params
	def pedido_params
		begin
			params.require(:licitacao_pedido).permit( :criado_na_contabilidade,
				:projeto_simplificado, :justificativa, :local_de_entrega, :outras_informacoes, :informacoes_da_cotacao, :vigencia,
				:objeto, :prazo_de_entrega, :status, :data_do_pedido, :data_limite_para_complementacao, :usuario_id,:dfd, :dod, :fundamentacao_de_contratacao,
				:unidade_orcamentaria_id, :convidar_unidades, :possui_periodicidade_nos_itens, :dotacoes_no_pedido,
				:agente_publico_municipal_id, :material_de_consumo, :material_permanente, :premiacoes, :servico_continuado, :servico_nao_continuado,
				:obra, :servico_de_engenharia, :resultados_pretendidos, :horas_diarias, :prazo_de_encerramento, :divide_lote_no_pedido, :locacao_de_imoveis,
				categorias_do_pedido_attributes: [:id, :categoria_id, :subcategoria_id, :pedido_id, :_destroy]
			)
		rescue ActionController::ParameterMissing
			nil
		end
	end

	def unidades_orcamentarias_params
		begin
			params.require(:licitacao_pedido).permit(unidades_orcamentarias_por_pedido_attributes: [:id, :unidade_orcamentaria_id, :responsavel_do_pedido_id, :_destroy])
		rescue ActionController::ParameterMissing
			nil
		end
	end

	def pessoas_params
		begin
			params.require(:licitacao_pedido).permit(pessoas_do_pedido_attributes: [:id, :pessoa_id, :interno, :valido, :_destroy])
		rescue ActionController::ParameterMissing
			nil
		end
	end

	def itens_params
		begin
			params.require(:licitacao_pedido).permit(itens_do_pedido_attributes: [:preco_estimativo, :id, :tipo, :marca, :item_id, :lote_do_pedido, :sequencia_do_lote, :sequencia, :_destroy,
				itens_do_pedido_por_unidade_orcamentaria_attributes: [:id, :quantidade, :valor_previsto_desconto, :periodicidade, :unidade_de_medida_id, :unidade_orcamentaria_por_pedido_id]])
		rescue ActionController::ParameterMissing
			nil
		end
	end

	def quantidade_params
		begin
			params.require(:licitacao_pedido).permit(itens_do_pedido_attributes: [:preco_estimativo,:id,
				itens_do_pedido_por_unidade_orcamentaria_attributes: [:id, :quantidade, :valor_previsto_desconto, :periodicidade, :unidade_de_medida_id, :unidade_orcamentaria_por_pedido_id]
			])
		rescue ActionController::ParameterMissing
			nil
		end
	end

	def dotacao_params
		params.require(:licitacao_orcamento_da_despesa_por_pedido).permit(
			:id, :unidade_orcamentaria_id, :subacao_id, :elemento_de_despesa_por_subacao_id, :sub_elemento_de_despesa_id,
			:orcamento_da_despesa_id, :valor
		)
	end

	def cancelamento_params
		params.require(:licitacao_pedido).permit(:motivo_do_cancelamento).merge(status: 'cancelado')
	end

	def licitacao_item_do_pedido_params
		params.require(:licitacao_item_do_pedido).permit(:motivo).merge(valido: false)
	end

	def licitacao_item_do_pedido_por_pessoa_params
		params.require(:licitacao_item_do_pedido_por_pessoa).permit(:motivo).merge(valido: false)
	end

	def licitacao_pessoa_do_pedido_params
		params.require(:licitacao_pessoa_do_pedido).permit(:motivo).merge(valido: false)
	end

	def verifica_edicao_do_pedido
		redirect_to @pedido, alert: "Pedido não pode ser editado nessa etapa" unless @pedido.pode_editar?
	end

	def acao_corresponde_ao_status_do_pedido?
		redirect_to @pedido, alert: "Essa ação não é permitida nessa etapa" if !acao_permitida?(@pedido, action_name.to_sym) && !@pedido.importado_do_tcm?
	end

	def mensagem_complementacao_pedido
		if @pedido.unidade_orcamentaria_id != params[:unidade_id]
			@pedido.cria_mensagem_complementacao_pedido(params[:unidade_id])
		end
	end

	def justificativa_da_cotacao_params
		params.require(:licitacao_pedido).permit(:justificativa_da_cotacao)
	end

	def responsavel_setor_de_compras_params
		params.require(:licitacao_pedido).permit(:responsavel_pelo_setor_de_compras)
	end

	def data_do_mapa_params
		params.require(:licitacao_pedido).permit(:data_impressao_mapa)
	end
end
end
