module Contabilidade
class SolicitacaoDeAlteracaoOrcamentariasController < ApplicationController
	include ControllerConcern
	before_action :authenticate_usuario!
	before_action :autoriza_usuario!, except: [:atualizar_dotacoes, :confirmar_indeferir_alteracao, :atualizar_acoes_da_solicitacao, :editar_subacoes_da_solicitacao, :atualizar_subacoes_da_solicitacao, :criar_alteracao_a_partir_do_decreto, :alteracoes_por_dotacao, :atualizar_dotacoes_administrativo]
	before_action :set_solicitacao_de_alteracao_orcamentaria, except: [:index, :new, :create, :criar_alteracao_a_partir_do_decreto, :alteracoes_por_dotacao, :editar_dotacoes_ajuste,  :atualizar_dotacoes_ajuste]
	before_action :set_projeto, only: [:new, :create]
	before_action :set_empenho, only: [:new]
	before_action :set_fonte_de_recursos, only: [:new, :create]
	before_action :set_dados_empenho, only: [:new, :create]
	before_action :set_dados_decreto, only: [:new, :create]
	before_action :set_acoes_por_unidade, only: [:show]
	before_action :set_programas_de_governo, only: [:show]

	before_action :disponibiliza_dependencias, only: [:create, :new, :update, :edit, :index]
	before_action :disponibiliza_dotacoes_destino, only: [:editar_dotacoes, :atualizar_dotacoes]
	before_action :disponibiliza_dotacoes_origem, only: [:editar_dotacoes, :atualizar_dotacoes]
	before_action :disponibiliza_dependencias_das_dotacoes_administrativo, only: [:editar_dotacoes_administrativo]
	before_action -> { usuario_pode_visualizar?(@solicitacao_de_alteracao_orcamentaria) }, except: [:index, :new, :create, :criar_alteracao_a_partir_do_decreto, :editar_dotacoes_ajuste,  :atualizar_dotacoes_ajuste]
	before_action -> {verifica_mes_bloqueado(@solicitacao_de_alteracao_orcamentaria)},  only: [:create, :new, :update, :edit, :index, :editar_dotacoes, :atualizar_dotacoes]
	# before_action -> {verifica_mes_bloqueado(@solicitacao_de_alteracao_orcamentaria)}, only: [:edit, :destroy

	# GET /contabilidade/solicitacao_de_alteracao_orcamentarias
	def index
		tipos_de_credito = Contabilidade::SolicitacaoDeAlteracaoOrcamentaria.tipo_de_creditos
		@tipos_de_credito = tipos_de_credito.select {|tc| tc.eql?('credito_suplementar') || tc.eql?('credito_especial') || tc.eql?('credito_extraordinario')}
		if contabilidade_atual.present?
			alteracoes = contabilidade_atual.solicitacao_de_alteracao_orcamentarias.order(created_at: :desc)
		else
			alteracoes = orcamento_atual.solicitacao_de_alteracao_orcamentarias.order(created_at: :desc)
		end

		if params[:suplementares]
			alteracoes = alteracoes.where(tipo_de_credito: Contabilidade::SolicitacaoDeAlteracaoOrcamentaria.tipo_de_creditos["credito_suplementar"])
			@action_solicitacao_de_alteracao_orcamentarias = "suplementares"
			@url_solicitacao_de_alteracao_orcamentarias = suplementares_contabilidade_solicitacao_de_alteracao_orcamentarias_path
		elsif params[:especiais]
			alteracoes =  alteracoes.where(tipo_de_credito: Contabilidade::SolicitacaoDeAlteracaoOrcamentaria.tipo_de_creditos["credito_especial"])
			@action_solicitacao_de_alteracao_orcamentarias = "especiais"
			@url_solicitacao_de_alteracao_orcamentarias = especiais_contabilidade_solicitacao_de_alteracao_orcamentarias_path
		elsif params[:extraordinarios]
			alteracoes = alteracoes.where(tipo_de_credito: Contabilidade::SolicitacaoDeAlteracaoOrcamentaria.tipo_de_creditos["credito_extraordinario"])
			@action_solicitacao_de_alteracao_orcamentarias = "extraordinarios"
			@url_solicitacao_de_alteracao_orcamentarias = extraordinarios_contabilidade_solicitacao_de_alteracao_orcamentarias_path
		elsif params[:confirmados]
			alteracoes = alteracoes.where(status: Contabilidade::SolicitacaoDeAlteracaoOrcamentaria.status["confirmado"])
			@action_solicitacao_de_alteracao_orcamentarias = "confirmados"
			@url_solicitacao_de_alteracao_orcamentarias = confirmados_contabilidade_solicitacao_de_alteracao_orcamentarias_path
		elsif params[:enviados_ao_planejamento]
			alteracoes = alteracoes.enviado_ao_planejamento
			@action_solicitacao_de_alteracao_orcamentarias = "enviados_ao_planejamento"
			@url_solicitacao_de_alteracao_orcamentarias = enviados_ao_planejamento_contabilidade_solicitacao_de_alteracao_orcamentarias_path
		elsif logado_no_administrativo?
			alteracoes = alteracoes.all
			@action_solicitacao_de_alteracao_orcamentarias = "empenhos"
			@url_solicitacao_de_alteracao_orcamentarias = administrativo_solicitacao_de_alteracao_orcamentarias_path
		elsif logado_na_licitacao?
			alteracoes = alteracoes.where.not(projeto: nil)
			@action_solicitacao_de_alteracao_orcamentarias = "projetos"
			@url_solicitacao_de_alteracao_orcamentarias = licitacao_solicitacao_de_alteracao_orcamentarias_path
		elsif logado_na_alteracao_orcamentaria?
			alteracoes = alteracoes.where.not(status: :confirmado)
			@action_solicitacao_de_alteracao_orcamentarias = "solicitacoes"
			@url_solicitacao_de_alteracao_orcamentarias = contabilidade_solicitacao_de_alteracao_orcamentarias_path
		elsif logado_na_contabilidade?
			alteracoes = alteracoes.where.not(empenho_id: nil)
			@action_solicitacao_de_alteracao_orcamentarias = "solicitacoes"
			@url_solicitacao_de_alteracao_orcamentarias = contabilidade_solicitacao_de_alteracao_orcamentarias_path
		else
			alteracoes = alteracoes.all
			@action_solicitacao_de_alteracao_orcamentarias = "solicitacoes"
			@url_solicitacao_de_alteracao_orcamentarias = contabilidade_solicitacao_de_alteracao_orcamentarias_path
		end

		if current_usuario.desenvolvedor?
			@q = alteracoes.search(params[:q])
		else
			@q = alteracoes
				.left_outer_joins(orcamentos_da_despesa_destino: [elemento_de_despesa_por_subacao: :subacao] )
					.where(
						"contabilidade_solicitacao_de_alteracao_orcamentarias.unidade_orcamentaria_id in (?) 
						OR loa_subacoes.unidade_orcamentaria_id in (?) 
						OR ( loa_orcamentos_da_despesa.id IS NULL AND contabilidade_solicitacao_de_alteracao_orcamentarias.unidade_orcamentaria_id is NULL)", current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id), current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id).push(nil))
						.search(params[:q])
		end

		if params[:suplementares] || params[:especiais] || params[:extraordinarios]
			@solicitacao_de_alteracao_orcamentarias = @q.result(distinct: false).paginate(page: params[:page], per_page: 10)
		else
			@solicitacao_de_alteracao_orcamentarias = @q.result(distinct: false).paginate(page: params[:page], per_page: 10)
		end
	end

	def alteracoes_por_dotacao
		if current_usuario.desenvolvedor?
			@unidades_orcamentarias = contexto_atual.unidades_orcamentarias
		else
			@unidades_orcamentarias = contexto_atual.unidades_orcamentarias.where(id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id))
		end

		@subacoes = current_usuario.subacoes.do_exercicio(exercicio_atual).includes(acao: :natureza_da_acao).order('base_naturezas_das_acoes.codigo, loa_acoes.codigo')
		@elementos_de_despesa = contexto_atual.elementos_de_despesa.where(exibir_elemento_de_despesa: true).order(:codigo)
		@fontes_de_recursos = contexto_atual.fontes_de_recursos

		filtro_de_dotacoes_de_origem
		filtro_de_dotacoes_de_destino

		dotacoes_agrupadas = filtro_de_dotacoes_de_destino.result(distinct: false) + filtro_de_dotacoes_de_origem.result(distinct: false)
		@dotacoes_das_solicitacoes = dotacoes_agrupadas.sort_by{ |t| t.solicitacao_de_alteracao_orcamentaria.try(:decreto).try(:data_da_legislacao).nil? ? Date.new : t.solicitacao_de_alteracao_orcamentaria.decreto.data_da_legislacao }.reverse.paginate(page: params[:page], per_page: 10)
	end

	def filtro_de_dotacoes_de_origem
		dotacoes_origem = contexto_atual.dotacoes_origem.order(created_at: :desc)
		@q = dotacoes_origem.ransack(params[:q])
	end

	def filtro_de_dotacoes_de_destino
		dotacoes_destino = contexto_atual.dotacoes_destino.order(created_at: :desc)
		@q = dotacoes_destino.ransack(params[:q])
	end

	# GET /contabilidade/solicitacao_de_alteracao_orcamentarias/1
	def show
	end

	# GET /contabilidade/solicitacao_de_alteracao_orcamentarias/new
	def new
		@solicitacao_de_alteracao_orcamentaria = SolicitacaoDeAlteracaoOrcamentaria.new
		if params["tipo_de_credito"].present?
			@solicitacao_de_alteracao_orcamentaria.tipo_de_credito = Contabilidade::SolicitacaoDeAlteracaoOrcamentaria.tipo_de_creditos[params["tipo_de_credito"]]
		end

		if params["decreto"].present?
			@decreto = Contabilidade::Decreto.find(params["decreto"])
			@solicitacao_de_alteracao_orcamentaria.tipo_de_credito = @decreto.tipo_de_credito
			@solicitacao_de_alteracao_orcamentaria.decreto_id = @decreto.id
		end

		if @projeto.present?
			@solicitacao_de_alteracao_orcamentaria.unidade_orcamentaria_id = @projeto.orcamentos_da_despesa_por_projetos.last.orcamento_da_despesa.elemento_de_despesa_por_subacao.subacao.unidade_orcamentaria_id rescue nil
		end
	end

	# POST /contabilidade/solicitacao_de_alteracao_orcamentarias
	def create
		@solicitacao_de_alteracao_orcamentaria = SolicitacaoDeAlteracaoOrcamentaria.new(solicitacao_de_alteracao_orcamentaria_params)

		if contabilidade_atual.present?
			@solicitacao_de_alteracao_orcamentaria.logado_na_contabilidade = true
		else
			@solicitacao_de_alteracao_orcamentaria.logado_na_contabilidade = false
		end

		if logado_na_alteracao_orcamentaria?
			@solicitacao_de_alteracao_orcamentaria.logado_na_alteracao_orcamentaria = true
		else
			@solicitacao_de_alteracao_orcamentaria.logado_na_alteracao_orcamentaria = false
		end

		if @solicitacao_de_alteracao_orcamentaria.projeto.present?
			@solicitacao_de_alteracao_orcamentaria.orcamento = @solicitacao_de_alteracao_orcamentaria.projeto.orcamento
		elsif contabilidade_atual.present?
			@solicitacao_de_alteracao_orcamentaria.orcamento = contabilidade_atual
		else
			@solicitacao_de_alteracao_orcamentaria.orcamento = orcamento_atual
		end

		@solicitacao_de_alteracao_orcamentaria.skip_callback = true
		
		if @solicitacao_de_alteracao_orcamentaria.save

			@solicitacao_de_alteracao_orcamentaria.skip_callback = false
			@solicitacao_de_alteracao_orcamentaria.gerar_todos_os_movimentos(:data_do_talao, contexto_atual) if @solicitacao_de_alteracao_orcamentaria.confirmado?

			if logado_na_alteracao_orcamentaria? && @solicitacao_de_alteracao_orcamentaria.credito_suplementar?
				redirect_to editar_dotacoes_contabilidade_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), notice: 'Alteração de Crédito Adicional foi criada com sucesso.'
			elsif contabilidade_atual.present?
				if @solicitacao_de_alteracao_orcamentaria.anulacao_de_dotacao? && !@solicitacao_de_alteracao_orcamentaria.credito_especial_ou_extraordinario?
					redirect_to editar_dotacoes_contabilidade_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), notice: 'Alteração de Crédito Adicional foi criada com sucesso.'
				else
					redirect_to contabilidade_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), success: 'Solicitação de Crédito Adicional foi criada com sucesso.'
				end
			elsif logado_na_licitacao?
				if @solicitacao_de_alteracao_orcamentaria.anulacao_de_dotacao? && !@solicitacao_de_alteracao_orcamentaria.credito_especial_ou_extraordinario?
					redirect_to editar_dotacoes_contabilidade_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), notice: 'Solicitação de Crédito Adicional foi criada com sucesso.'
				else
					redirect_to licitacao_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), success: 'Solicitação de Crédito Adicional foi criada com sucesso.'
				end
			elsif logado_no_administrativo?
				if @solicitacao_de_alteracao_orcamentaria.anulacao_de_dotacao? && !@solicitacao_de_alteracao_orcamentaria.credito_especial_ou_extraordinario? && @solicitacao_de_alteracao_orcamentaria.avulso? == false
					redirect_to editar_dotacoes_contabilidade_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), notice: 'Solicitação de Crédito Adicional foi criada com sucesso.'
				else
					redirect_to administrativo_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), success: 'Solicitação de Crédito Adicional foi criada com sucesso.'
				end
			else
				redirect_to @solicitacao_de_alteracao_orcamentaria, notice: 'Solicitação de Crédito Adicional foi criada com sucesso.'
			end
		else
			disponibiliza_dependencias
			if @solicitacao_de_alteracao_orcamentaria.empenho.present?
				@empenho = @solicitacao_de_alteracao_orcamentaria.empenho
			end

			if @solicitacao_de_alteracao_orcamentaria.orcamento_da_despesa_id.present?
				params[:orcamento_da_despesa] = @solicitacao_de_alteracao_orcamentaria.orcamento_da_despesa_id
				params[:valor_do_empenho] = @solicitacao_de_alteracao_orcamentaria.valor_do_empenho
			end
			set_dados_empenho
			render :new
		end
	end

	# GET /contabilidade/solicitacao_de_alteracao_orcamentarias/1/edit
	def edit
	end

	# PATCH/PUT /contabilidade/solicitacao_de_alteracao_orcamentarias/1
	def update
		if contabilidade_atual.present?
			@solicitacao_de_alteracao_orcamentaria.logado_na_contabilidade = true
		else
			@solicitacao_de_alteracao_orcamentaria.logado_na_contabilidade = false
		end

		if logado_na_alteracao_orcamentaria?
			@solicitacao_de_alteracao_orcamentaria.logado_na_alteracao_orcamentaria = true
		else
			@solicitacao_de_alteracao_orcamentaria.logado_na_alteracao_orcamentaria = false
		end

		if @solicitacao_de_alteracao_orcamentaria.update( solicitacao_de_alteracao_orcamentaria_params )
			if contabilidade_atual.present?
				redirect_to @solicitacao_de_alteracao_orcamentaria, notice: 'Solicitação de Crédito Adicional foi atualizada com sucesso.'
			elsif solicitacao_de_alteracao_orcamentaria_params[:projeto_id].present?
				redirect_path = licitacao_projeto_path(solicitacao_de_alteracao_orcamentaria_params[:projeto_id], tab: "sol_de_alteracoes_orcamentarias")
				redirect_to redirect_path, success: 'Solicitação de Crédito Adicional foi atualizada com sucesso.'
			else
				redirect_to administrativo_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), notice: 'Solicitação de Crédito Adicional foi atualizada com sucesso.'
			end
		else
			set_projeto
			set_fonte_de_recursos
			set_dados_decreto
			render :edit
		end
	end

	# DELETE /contabilidade/solicitacao_de_alteracao_orcamentarias/1
	def destroy
		mensagem = apaga_e_retorna_mensagem(@solicitacao_de_alteracao_orcamentaria)

		if @solicitacao_de_alteracao_orcamentaria.empenho.present? && @solicitacao_de_alteracao_orcamentaria.empenho.aguardando_alteracao_do_orcamento?
			@solicitacao_de_alteracao_orcamentaria.empenho.status = 'solicitado'
			@solicitacao_de_alteracao_orcamentaria.empenho.save(validate: false)
		end

		if contabilidade_atual.present?
			if @solicitacao_de_alteracao_orcamentaria.credito_suplementar?
				redirect_to suplementares_contabilidade_solicitacao_de_alteracao_orcamentarias_path, mensagem
			elsif @solicitacao_de_alteracao_orcamentaria.credito_especial?
				redirect_to especiais_contabilidade_solicitacao_de_alteracao_orcamentarias_path, mensagem
			elsif @solicitacao_de_alteracao_orcamentaria.credito_extraordinario?
				redirect_to extraordinarios_contabilidade_solicitacao_de_alteracao_orcamentarias_path, mensagem
			else
				redirect_to contabilidade_solicitacao_de_alteracao_orcamentarias_url, mensagem
			end
		elsif @solicitacao_de_alteracao_orcamentaria.projeto.present?
			redirect_path = licitacao_projeto_path(@solicitacao_de_alteracao_orcamentaria.projeto)
			redirect_to redirect_path, mensagem
		elsif @solicitacao_de_alteracao_orcamentaria.avulso?
			redirect_to administrativo_solicitacao_de_alteracao_orcamentarias_path, mensagem
		else
			redirect_path = empenho_path(@solicitacao_de_alteracao_orcamentaria.empenho)
			redirect_to redirect_path, mensagem
		end
	end

	# GET /contabilidade/solicitacao_de_alteracao_orcamentarias/1/editar_dotacoes
	def editar_dotacoes
		@solicitacao_de_alteracao_orcamentaria = Contabilidade::SolicitacaoDeAlteracaoOrcamentaria.find(params[:id])
		disponibiliza_dotacoes_destino

		if @solicitacao_de_alteracao_orcamentaria.dotacoes_origem.empty? && (@solicitacao_de_alteracao_orcamentaria.anulacao_de_dotacao? || @solicitacao_de_alteracao_orcamentaria.credito_de_reducao?)
			@solicitacao_de_alteracao_orcamentaria.dotacoes_origem.build
		end

		if @solicitacao_de_alteracao_orcamentaria.dotacoes_destino.empty?
			@solicitacao_de_alteracao_orcamentaria.dotacoes_destino.build
		end
	end

	# PATCH /contabilidade/solicitacao_de_alteracao_orcamentarias/1/atualizar_dotacoes
	def atualizar_dotacoes
		bloqueia_usuario_com_base_em :editar_dotacoes

		if @solicitacao_de_alteracao_orcamentaria.update( solicitacao_de_alteracao_orcamentaria_params )
			if params[:cadastrar_proxima].present?
				proxima_sol = @solicitacao_de_alteracao_orcamentaria.dup
				proxima_sol.save!
				mensagem = 'Tela redirecionada para nova Alteração Orçamentária. Não esqueça de confirmar todas as Alterações'
				redirect_to editar_dotacoes_contabilidade_solicitacao_de_alteracao_orcamentaria_path(proxima_sol), notice: mensagem
			elsif @solicitacao_de_alteracao_orcamentaria.fonte_de_recursos.present? && @solicitacao_de_alteracao_orcamentaria.decreto.present? && @solicitacao_de_alteracao_orcamentaria.solicitado?
				@solicitacao_de_alteracao_orcamentaria.confirmar!
				redirect_to contabilidade_decreto_path(@solicitacao_de_alteracao_orcamentaria.decreto), notice: 'Dotações atualizados com sucesso.'
			else
				redirect_to contabilidade_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), notice: 'Dotações atualizados com sucesso.'
			end
		else
			flash.now[:alert] = @solicitacao_de_alteracao_orcamentaria.errors.full_messages.to_sentence
			render :editar_dotacoes
		end
	end

	def editar_dotacoes_ajuste

		decreto_id = params[:decreto_id]
		@decreto = Contabilidade::Decreto.find(decreto_id)

		@solicitacao_de_alteracao_orcamentaria = Contabilidade::SolicitacaoDeAlteracaoOrcamentaria.new(
			origem_do_recurso: 0,
			decreto_id: decreto_id,
			tipo_de_credito: 3,
			fonte_de_recursos_id:	params[:fonte_de_recurso_id],
			orcamento_id: contabilidade_atual.id,
			logado_na_alteracao_orcamentaria: true
		)
		disponibiliza_dotacoes_destino

		if @solicitacao_de_alteracao_orcamentaria.dotacoes_origem.empty? && (@solicitacao_de_alteracao_orcamentaria.anulacao_de_dotacao? || @solicitacao_de_alteracao_orcamentaria.credito_de_reducao?)
			@solicitacao_de_alteracao_orcamentaria.dotacoes_origem.build
		end

		if @solicitacao_de_alteracao_orcamentaria.dotacoes_destino.empty?
			@solicitacao_de_alteracao_orcamentaria.dotacoes_destino.build
		end
	end

	def atualizar_dotacoes_ajuste
		bloqueia_usuario_com_base_em :editar_dotacoes

		@solicitacao_de_alteracao_orcamentaria = Contabilidade::SolicitacaoDeAlteracaoOrcamentaria.new( solicitacao_de_alteracao_orcamentaria_params)
		@solicitacao_de_alteracao_orcamentaria.origem_do_recurso = 0
		@solicitacao_de_alteracao_orcamentaria.tipo_de_credito = 3
		@solicitacao_de_alteracao_orcamentaria.skip_callback = true
		@solicitacao_de_alteracao_orcamentaria.logado_na_alteracao_orcamentaria = true

		if @solicitacao_de_alteracao_orcamentaria.save!
			if @solicitacao_de_alteracao_orcamentaria.fonte_de_recursos.present? && @solicitacao_de_alteracao_orcamentaria.decreto.present? && @solicitacao_de_alteracao_orcamentaria.solicitado?
				@solicitacao_de_alteracao_orcamentaria.confirmar!
				@solicitacao_de_alteracao_orcamentaria.skip_callback = false
				@solicitacao_de_alteracao_orcamentaria.gerar_todos_os_movimentos(:data_do_talao, contexto_atual)
				redirect_to contabilidade_decreto_path(@solicitacao_de_alteracao_orcamentaria.decreto), notice: 'Dotações atualizados com sucesso.'
			else
				redirect_to contabilidade_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), notice: 'Dotações atualizados com sucesso.'
			end
		else
			flash.now[:alert] = @solicitacao_de_alteracao_orcamentaria.errors.full_messages.to_sentence
			render :editar_dotacoes
		end
	end

	# GET /contabilidade/solicitacao_de_alteracao_orcamentarias/1/editar_subacoes_da_solicitacao
	def editar_subacoes_da_solicitacao
		bloqueia_usuario_com_base_em :editar_dotacoes
		disponibiliza_subacoes
		@solicitacao_de_alteracao_orcamentaria.subacoes_da_solicitacao.build if @solicitacao_de_alteracao_orcamentaria.subacoes_da_solicitacao.empty?
	end

	# PATCH /contabilidade/solicitacao_de_alteracao_orcamentarias/1/atualizar_subacoes_da_solicitacao
	def atualizar_subacoes_da_solicitacao
		bloqueia_usuario_com_base_em :editar_dotacoes
		ActiveRecord::Base.transaction do
			begin
				if @solicitacao_de_alteracao_orcamentaria.update(solicitacao_de_alteracao_orcamentaria_params)
					redirect_to contabilidade_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), notice: 'Ações foram vinculadas com sucesso.'
				else
					if @solicitacao_de_alteracao_orcamentaria.errors.messages[:valor_a_suplementar].any?
						flash.now[:alert] = @solicitacao_de_alteracao_orcamentaria.errors.messages[:valor_a_suplementar].join(",")
					end
					disponibiliza_subacoes
					render :editar_subacoes_da_solicitacao
				end
			rescue Exception => e
				flash.now[:alert] = e.message
				disponibiliza_subacoes
				render :editar_subacoes_da_solicitacao
			end
		end
	end

	# PATCH /contabilidade/solicitacao_de_alteracao_orcamentarias/1/enviar_para_contabilidade
	def enviar_para_contabilidade
		if @solicitacao_de_alteracao_orcamentaria.enviar_para_contabilidade!
			redirect_to contabilidade_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), success: 'A alteração foi enviada para o setor com sucesso.'
		else
			redirect_to contabilidade_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), alert: 'Não foi possível enviar a alteração. Por favor, confira se ela contém erros'
		end
	end

	# GET /contabilidade/solicitacao_de_alteracao_orcamentarias/1/confirmar_indeferir_alteracao
	def confirmar_indeferir_alteracao
		return if bloqueia_usuario_com_base_em 'indeferir_alteracao'
	end

	# PATCH /contabilidade/solicitacao_de_alteracao_orcamentarias/1/indeferir_alteracao
	def indeferir_alteracao
		@solicitacao_de_alteracao_orcamentaria.motivo_indeferido = params[:contabilidade_solicitacao_de_alteracao_orcamentaria][:motivo_indeferido]

		if @solicitacao_de_alteracao_orcamentaria.indeferir!
			redirect_to @solicitacao_de_alteracao_orcamentaria, notice: 'A alteração foi indeferida com sucesso.'
		else
			redirect_to contabilidade_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), alert: 'Não foi possível indeferir a alteração. Por favor, confira se ela contém erros'
		end
	end

	# PATCH /contabilidade/solicitacao_de_alteracao_orcamentarias/1/confirmar_alteracao
	def confirmar_alteracao
		if @solicitacao_de_alteracao_orcamentaria.confirmar!
			if (@solicitacao_de_alteracao_orcamentaria.empenho.present? && @solicitacao_de_alteracao_orcamentaria.empenho.aguardando_alteracao_do_orcamento?)
				@solicitacao_de_alteracao_orcamentaria.empenho.update_column(:status, :solicitado) 
				@solicitacao_de_alteracao_orcamentaria.empenho.save 
			end

			redirect_to contabilidade_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), success: 'A alteração foi confirmada com sucesso.'
		else
			redirect_to contabilidade_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), alert: 'Não foi possível confirmar a alteração. Por favor, confira se ele contém erros'
		end
	end

	def voltar_etapa
		return if bloqueia_usuario_com_base_em 'update'
		if @solicitacao_de_alteracao_orcamentaria.voltar_etapa!
			redirect_to @solicitacao_de_alteracao_orcamentaria, success: 'O alteração retornou etapa com sucesso.'
		else
			redirect_to @solicitacao_de_alteracao_orcamentaria, alert: 'Não foi possível voltar etapa da alteração orçamentaria. Por favor, confira se ela contém erros.'
		end
	end

	def criar_alteracao_a_partir_do_decreto
		bloqueia_usuario_com_base_em :editar_dotacoes

		redirect_to contabilidade_editar_dotacoes_ajuste_path(fonte_de_recurso_id: params[:fonte_de_recurso_id], decreto_id: params[:decreto_id]), notice: 'Alteração de Crédito Adicional foi criada com sucesso.'

		# if @solicitacao_de_alteracao_orcamentaria.save!
		# 	redirect_to editar_dotacoes_contabilidade_solicitacao_de_alteracao_orcamentaria_path(@solicitacao_de_alteracao_orcamentaria), notice: 'Alteração de Crédito Adicional foi criada com sucesso.'
		# else
		# 	redirect_to @decreto, alert: 'Não foi possível criar a alteração. Por favor, confira se contém erros'
		# end
	end

	def editar_dotacoes_administrativo
	end

	def atualizar_dotacoes_administrativo
		if @solicitacao_de_alteracao_orcamentaria.update(solicitacao_de_alteracao_orcamentaria_params)
			redirect_to @solicitacao_de_alteracao_orcamentaria,  success: "Dotações cadastradas com Sucesso"
		else
			disponibiliza_dependencias_das_dotacoes_administrativo
			render :editar_dotacoes_administrativo
		end
	end

	def disponibiliza_dependencias_das_dotacoes_administrativo
		@solicitacao_de_alteracao_orcamentaria.dotacoes_destino.build() if @solicitacao_de_alteracao_orcamentaria.dotacoes_destino.empty?
		@solicitacao_de_alteracao_orcamentaria.dotacoes_origem.build() if @solicitacao_de_alteracao_orcamentaria.anulacao_de_dotacao? && @solicitacao_de_alteracao_orcamentaria.dotacoes_origem.empty?

		unidades_orcamentarias_ids = @solicitacao_de_alteracao_orcamentaria.unidade_orcamentaria_id.present? ? @solicitacao_de_alteracao_orcamentaria.unidade_orcamentaria_id : contexto_atual.unidades_orcamentarias.ids
		@subacoes = current_usuario.subacoes.do_exercicio(exercicio_atual).joins(acao: [:natureza_da_acao]).where(unidade_orcamentaria_id: unidades_orcamentarias_ids).order("base_naturezas_das_acoes.codigo ASC, loa_acoes.codigo")

		if @solicitacao_de_alteracao_orcamentaria.subacao_da_solicitacao_ids.present?
			@elementos_de_despesa_da_origem = Base::ElementoDeDespesa.ativos.joins(:elementos_de_despesa_por_subacao).where(
				loa_elementos_de_despesa_por_subacao: {
					subacao_id: @solicitacao_de_alteracao_orcamentaria.subacao_da_solicitacao_ids
				},
				base_elementos_de_despesa: {
					exibir_elemento_de_despesa: true
				}
			)
		else
			@elementos_de_despesa_da_origem = Array.new
		end

		@fontes_de_recursos_da_origem = Base::FonteDeRecursos.joins(:subacoes).where(
			loa_subacoes:{
				id: @solicitacao_de_alteracao_orcamentaria.subacao_da_solicitacao_ids
			}
		)
	end

	def duplica_alteracao_orcamentaria
		duplicata = @solicitacao_de_alteracao_orcamentaria.dup
		duplicata.status = :solicitado
		duplicata.save!
		mensagem = 'Alteração Orçamentaria duplicada com sucesso!'
		redirect_to contabilidade_solicitacao_de_alteracao_orcamentaria_path(duplicata), notice: mensagem
	end

	private

	def set_acoes_por_unidade
		@acoes = Loa::Acao.where(solicitacao_de_alteracao_orcamentaria_id: @solicitacao_de_alteracao_orcamentaria.id)
	end

	def set_programas_de_governo
		@programas_de_governo = Loa::ProgramaDeGoverno.where(solicitacao_de_alteracao_orcamentaria_id: @solicitacao_de_alteracao_orcamentaria.id)
	end

	def set_solicitacao_de_alteracao_orcamentaria
		@solicitacao_de_alteracao_orcamentaria = Contabilidade::SolicitacaoDeAlteracaoOrcamentaria.find( params[:id] )
	end

	def set_projeto
		if logado_na_licitacao?
			projeto_id = params[:projeto_id] || params[:contabilidade_solicitacao_de_alteracao_orcamentaria][:projeto_id]
			@projeto = Licitacao::Projeto.find(projeto_id)
		end
	end

	def set_empenho
		if params[:orcamento_da_despesa].blank? &&  params[:empenho_id].present?
			@empenho = Contabilidade::Empenho.find( params[:empenho_id] )
		end
	end

	def set_fonte_de_recursos
		if logado_na_alteracao_orcamentaria? || contabilidade_atual.present?
			if params[:fonte_de_recurso_id].present?
				fonte_de_recurso_id = params[:fonte_de_recurso_id]
				@fonte_de_recursos = Base::FonteDeRecursos.find( fonte_de_recurso_id )
			elsif params[:contabilidade_solicitacao_de_alteracao_orcamentaria].present? && params[:contabilidade_solicitacao_de_alteracao_orcamentaria][:fonte_de_recursos_id].present?
				fonte_de_recurso_id = params[:contabilidade_solicitacao_de_alteracao_orcamentaria][:fonte_de_recursos_id]
				@fonte_de_recursos = Base::FonteDeRecursos.find( fonte_de_recurso_id )
			end
		end
	end

	def set_dados_decreto
		if logado_na_alteracao_orcamentaria? || contabilidade_atual.present?
			if params[:decreto_id].present?
				decreto_id = params[:decreto_id]
				@decreto = Contabilidade::Decreto.find(decreto_id)
			elsif params[:contabilidade_solicitacao_de_alteracao_orcamentaria].present? && params[:contabilidade_solicitacao_de_alteracao_orcamentaria][:vem_do_decreto].present?
				decreto_id = params[:contabilidade_solicitacao_de_alteracao_orcamentaria][:decreto_id]
				@decreto = Contabilidade::Decreto.find(decreto_id)
			end
		end
	end

	def set_dados_empenho
		if params[:orcamento_da_despesa].present?
			orcamento_da_despesa_id = params[:orcamento_da_despesa]
			@orcamento_da_despesa = Loa::OrcamentoDaDespesa.find(orcamento_da_despesa_id)
			@valor_do_empenho = params[:valor_do_empenho] if params[:valor_do_empenho].present?
		end
	end

	def disponibiliza_dependencias
		@origens_do_recurso = Contabilidade::SolicitacaoDeAlteracaoOrcamentaria.origens_dos_recursos_i18n

		if @empenho.present?
			@origens_do_recurso_contabilidade = @origens_do_recurso.select { |odr| odr == 'outros' || odr == 'anulacao_de_dotacao' }
		elsif ( @solicitacao_de_alteracao_orcamentaria.present? && @solicitacao_de_alteracao_orcamentaria.tipo_de_credito == "credito_suplementar" ) || ( params[:tipo_de_credito].present? && params[:tipo_de_credito] == "credito_suplementar" )
			@origens_do_recurso_contabilidade = @origens_do_recurso.reject { |key| key == "revigoramento_de_credito" }
		else
			@origens_do_recurso_contabilidade = @origens_do_recurso.select { |odr| odr != 'outros' }
			@origens_do_recurso_contabilidade = @origens_do_recurso_contabilidade.reject { |key| key == "revigoramento_de_credito_especial" || key == "revigoramento_de_credito_extraordinario" }
		end

		@origens_do_recurso_licitacao_adm = @origens_do_recurso.select { |odr| odr.eql?('anulacao_de_dotacao') || odr.eql?('outros') }
		@decretos = []
		orcamento = contabilidade_atual || contexto_atual

		@operacoes_de_credito =
			if @solicitacao_de_alteracao_orcamentaria.try(:persisted?)
				@solicitacao_de_alteracao_orcamentaria.try(:operacao_de_credito).present? ? [@solicitacao_de_alteracao_orcamentaria.operacao_de_credito] : orcamento.operacoes_de_credito
			else
				::Obra::OperacaoDeCredito.joins(unidade_orcamentaria: :orgao).where('loa_orgaos.orcamento_id = ?', orcamento.id)
			end

		if !params[:id].blank?
			solicitacao_de_alteracao_orcamentaria = SolicitacaoDeAlteracaoOrcamentaria.find( params[:id] )
			@decretos = contexto_atual.decretos.aberto.where(tipo_de_credito: Contabilidade::Decreto.tipo_de_creditos[solicitacao_de_alteracao_orcamentaria.tipo_de_credito]).order(data_da_legislacao: :desc)
		end

		if params["tipo_de_credito"].present?
			@decretos = contexto_atual.decretos.aberto.where(tipo_de_credito: Contabilidade::Decreto.tipo_de_creditos[params["tipo_de_credito"]]).order(data_da_legislacao: :desc)
		elsif params[:contabilidade_solicitacao_de_alteracao_orcamentaria].present?
			@decretos = contexto_atual.decretos.aberto.where(tipo_de_credito: Contabilidade::Decreto.tipo_de_creditos[params[:contabilidade_solicitacao_de_alteracao_orcamentaria][:tipo_de_credito]]).order(data_da_legislacao: :desc)
		end

		if current_usuario.desenvolvedor?
			@unidades_orcamentarias = contexto_atual.unidades_orcamentarias.order("loa_unidades_orcamentarias.codigo", "loa_unidades_orcamentarias.nome")
		else
			@unidades_orcamentarias = contexto_atual.unidades_orcamentarias.where(id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)).order("loa_unidades_orcamentarias.codigo", "loa_unidades_orcamentarias.nome")
		end

		@programas_de_governo = contexto_atual.programas_de_governo
		tipos_de_credito = Contabilidade::SolicitacaoDeAlteracaoOrcamentaria.tipo_de_creditos
		@tipos_de_credito = tipos_de_credito.select {|tc| tc.eql?('credito_suplementar') || tc.eql?('credito_especial') || tc.eql?('credito_extraordinario')}
	end

	def disponibiliza_dotacoes_destino
		@dotacoes_destino = @solicitacao_de_alteracao_orcamentaria.retorna_as_dotacoes_destino(contexto_atual)
		if !@solicitacao_de_alteracao_orcamentaria.credito_especial_ou_extraordinario?
			@dotacoes_destino_select = @dotacoes_destino
				.joins(elemento_de_despesa_por_subacao: [subacao: [acao: :natureza_da_acao]]).joins(elemento_de_despesa_por_subacao: :elemento_de_despesa).joins(fonte_de_recursos: :fonte_stn)
					.order('base_naturezas_das_acoes.codigo','loa_acoes.codigo','base_elementos_de_despesa.codigo','base_fontes_stn.codigo_principal','base_fontes_stn.detalhamento_sintetico')
						.map { |orcamento_da_despesa| [orcamento_da_despesa.id, orcamento_da_despesa.classificacao_detalhada] } unless @dotacoes_destino.nil?
		else
			@dotacoes_destino = @dotacoes_destino - @solicitacao_de_alteracao_orcamentaria.dotacoes_destino.map{|d| d.orcamento_da_despesa} rescue []
			if !params[:contabilidade_solicitacao_de_alteracao_orcamentaria].present? && @dotacoes_destino.present?
				@dotacoes_destino.each do |dotacao_destino|
					array_de_dotacao = []
					array_de_dotacao.push( dotacao_destino )
					if array_de_dotacao.size > 1 || ( array_de_dotacao[0].kind_of?(ActiveRecord::Associations::CollectionProxy) && array_de_dotacao[0].size > 1 )
						dotacao_destino.each do |dotacao|
							@solicitacao_de_alteracao_orcamentaria.dotacoes_destino.build(dotacao_id: dotacao.id)
						end
					elsif @solicitacao_de_alteracao_orcamentaria.nova_acao.blank? && @solicitacao_de_alteracao_orcamentaria.novo_programa.blank?
						@solicitacao_de_alteracao_orcamentaria.dotacoes_destino.build(dotacao_id: dotacao_destino.id)
					else
						if dotacao_destino.any?
							@solicitacao_de_alteracao_orcamentaria.dotacoes_destino.build(dotacao_id: dotacao_destino.last.id)
						end
					end
				end
			end
		end
	end

	def disponibiliza_dotacoes_origem
		@dotacoes_origem = @solicitacao_de_alteracao_orcamentaria.retorna_as_dotacoes_origem(contexto_atual, logado_na_alteracao_orcamentaria?)
		@dotacoes_origem_select = @dotacoes_origem
			.joins(elemento_de_despesa_por_subacao: [subacao: [acao: :natureza_da_acao]]).joins(elemento_de_despesa_por_subacao: :elemento_de_despesa).joins(fonte_de_recursos: :fonte_stn)
				.order('base_naturezas_das_acoes.codigo','loa_acoes.codigo','base_elementos_de_despesa.codigo','base_fontes_stn.codigo_principal','base_fontes_stn.detalhamento_sintetico')
					.map { |orcamento_da_despesa| [orcamento_da_despesa.id, orcamento_da_despesa.classificacao_detalhada] }
	end

	def disponibiliza_subacoes
		if @solicitacao_de_alteracao_orcamentaria.unidade_orcamentaria.present?
			@subacoes = current_usuario.subacoes.do_exercicio(exercicio_atual).where(unidade_orcamentaria: @solicitacao_de_alteracao_orcamentaria.unidade_orcamentaria).includes(acao: :natureza_da_acao).order('base_naturezas_das_acoes.codigo, loa_acoes.codigo')
		else
			@subacoes = current_usuario.subacoes.do_exercicio(exercicio_atual).includes(acao: :natureza_da_acao).order('base_naturezas_das_acoes.codigo, loa_acoes.codigo')
		end

		@elementos_por_subacao = contexto_atual.elementos_de_despesa.where(exibir_elemento_de_despesa: true).order(:codigo)
		@fontes_por_elemento = contexto_atual.fontes_de_recursos
		@iduso = Loa::OrcamentoDaDespesa.idusos
	end

	# Permite apenas os parâmetros específicos
	def solicitacao_de_alteracao_orcamentaria_params
		params.require(:contabilidade_solicitacao_de_alteracao_orcamentaria).permit(
			:logado_na_contabilidade, :orcamento_id, :programa_de_governo_da_solicitacao_id, :unidade_orcamentaria_id,
			:informacoes_adicionais, :data, :operacao_de_credito_id, :fonte_de_recursos_id,
			:origem_do_recurso, :orcamento_da_despesa_id, :valor_do_empenho, :justificativa, :status, :decreto_id, :tipo_de_credito,
			:projeto_id, :empenho_id, :nova_acao, :novo_programa, :criado_na_gestao_do_orcamento, :numero_da_alteracao_orcamentaria, :data_da_solicitacao, :avulso,
			:cadastrando_dotacao, :logado_no_administrativo,
			dotacoes_origem_attributes: [:id, :valor, :solicitacao_de_alteracao_orcamentaria_id, :dotacao_id, :_destroy, :subacao_id, :elemento_de_despesa_id, :fonte_de_recurso_id],
			dotacoes_destino_attributes: [:id, :valor, :solicitacao_de_alteracao_orcamentaria_id, :dotacao_id, :_destroy, :subacao_id, :elemento_de_despesa_id, :fonte_de_recurso_id],
			subacoes_da_solicitacao_attributes: [
				:id, :solicitacao_de_alteracao_orcamentaria_id, :subacao_id, :_destroy,
				elementos_por_subacao_da_solicitacao_attributes: [
					:id, :subacao_da_solicitacao_id, :elemento_de_despesa_id, :_destroy,
					fontes_por_elemento_da_subacao_da_solicitacao_attributes: [
						:id, :elemento_por_subacao_da_solicitacao_id, :fonte_de_recursos_id, :iduso, :_destroy
					]
				]
			]
		)
	end
end
end
