class Contabilidade::PagamentosController < ApplicationController
	include ContabilidadeHelper
	include ControllerConcern
	include GeradorDeEventosContabeisController
	include PessoasSemContasBancariasController

	before_action -> { verifica_modulo_na_sessao(["administrativo", "controladoria", "contabilidade", "financeiro"]) }
	before_action :authenticate_usuario!
	before_action :autoriza_usuario!, except: [:enviar_para_administrativo, :atualiza_unidade_do_pagamento, :atualiza_retencoes_de_folha, :editar_retencoes_de_folha, :cancelar_estorno]
	before_action :set_pagamento, except: [:index, :new, :create]
	before_action :set_liquidacao, only: [:new, :create]
	before_action :disponibiliza_eventos_contabeis, only: [:new, :edit, :create, :update, :atualizar_prepagamento_em_pagamento]
	before_action :verifica_conta_bancaria, only: [:new, :show]
	before_action :disponibiliza_dependencias, only: [:edit, :update]
	before_action -> { usuario_pode_visualizar?(@pagamento) }, except: [:index, :new, :create]
	before_action -> { verifica_mes_bloqueado(@pagamento)}, only: [:edit, :destroy, :confirmar_pagamento, :editar_retencoes_de_folha, :cancelar_estorno]
	before_action -> { redirect_to @pagamento, alert: 'Não é possível excluir o pagamento, pois já está em um lote bancário.' if @pagamento.lote_gerado? }, only: [:destroy]

	# GET /contabilidade/pagamentos
	def index
		restos_a_pagar = (params[:restos_a_pagar].present?)
		if params[:restos_a_pagar].present?
			
			ransack_params = Hash.new
			if params[:q].present?

				if params[:q][:liquidacao_empenho_unidade_orcamentaria_id_eq] != '' && params[:q][:liquidacao_empenho_unidade_orcamentaria_id_eq] != nil
					unidades_orcamentarias_ids = Loa::UnidadeOrcamentaria.find(params[:q][:liquidacao_empenho_unidade_orcamentaria_id_eq]).unidade_gestora.unidades_orcamentarias.pluck(:id)
					ransack_params["liquidacao_empenho_unidade_orcamentaria_id_in"] = unidades_orcamentarias_ids
				end
				
				@unidade_utilizada = params[:q][:liquidacao_empenho_unidade_orcamentaria_id_eq]
				ransack_params["data_gteq"] = params[:q][:data_gteq] if params[:q][:data_gteq] != ''
				ransack_params["data_lteq"] = params[:q][:data_lteq] if params[:q][:data_lteq] != ''
				ransack_params["numero_eq"] = params[:q][:numero_eq] if params[:q][:numero_eq] != ''
				ransack_params["liquidacao_empenho_numero_formatado_liquidacao_eq"] = params[:q][:liquidacao_empenho_numero_formatado_liquidacao_eq] if params[:q][:liquidacao_empenho_numero_formatado_liquidacao_eq] != ''
				ransack_params["status_eq"] = params[:q][:status_eq] if params[:q][:status_eq] != ''
				ransack_params["liquidacao_empenho_projeto_modalidade_de_licitacao_eq"] = params[:q][:liquidacao_empenho_projeto_modalidade_de_licitacao_eq] if params[:q][:liquidacao_empenho_projeto_modalidade_de_licitacao_eq] != ''
				ransack_params["liquidacao_empenho_projeto_numero_do_processo_eq"] = params[:q][:liquidacao_empenho_projeto_numero_do_processo_eq] if params[:q][:liquidacao_empenho_projeto_numero_do_processo_eq] != ''
				ransack_params["liquidacao_contrato_numero_eq"] = params[:q][:liquidacao_contrato_numero_eq] if params[:q][:liquidacao_contrato_numero_eq] != ''
				ransack_params["liquidacao_contrato_obra_codigo_eq"] = params[:q][:liquidacao_contrato_obra_codigo_eq] if params[:q][:liquidacao_contrato_obra_codigo_eq] != ''
				ransack_params["liquidacao_empenho_orcamento_da_despesa_elemento_de_despesa_por_subacao_subacao_acao_natureza_da_acao_codigo_completo_eq"] = params[:q][:liquidacao_empenho_orcamento_da_despesa_elemento_de_despesa_por_subacao_subacao_acao_natureza_da_acao_codigo_completo_eq] if params[:q][:liquidacao_empenho_orcamento_da_despesa_elemento_de_despesa_por_subacao_subacao_acao_natureza_da_acao_codigo_completo_eq] != ''
				ransack_params["liquidacao_empenho_orcamento_da_despesa_elemento_de_despesa_por_subacao_elemento_de_despesa_codigo_eq"] = params[:q][:liquidacao_empenho_orcamento_da_despesa_elemento_de_despesa_por_subacao_elemento_de_despesa_codigo_eq] if params[:q][:liquidacao_empenho_orcamento_da_despesa_elemento_de_despesa_por_subacao_elemento_de_despesa_codigo_eq] != ''
				ransack_params["liquidacao_empenho_sub_elemento_de_despesa_codigo_eq"] = params[:q][:liquidacao_empenho_sub_elemento_de_despesa_codigo_eq] if params[:q][:liquidacao_empenho_sub_elemento_de_despesa_codigo_eq] != ''
				ransack_params["liquidacao_empenho_orcamento_da_despesa_fonte_de_recursos_codigo_completo_eq"] = params[:q][:liquidacao_empenho_orcamento_da_despesa_fonte_de_recursos_codigo_completo_eq] if params[:q][:liquidacao_empenho_orcamento_da_despesa_fonte_de_recursos_id_eq] != ''
				ransack_params["liquidacao_empenho_pessoa_id_eq"] = params[:q][:liquidacao_empenho_pessoa_id_eq] if params[:q][:liquidacao_empenho_pessoa_id_eq] != ''
				ransack_params["liquidacao_nota_fiscal_tipo_eq"] = params[:q][:liquidacao_nota_fiscal_tipo_eq] if params[:q][:liquidacao_nota_fiscal_tipo_eq] != ''
				ransack_params["valor_gteq"] = params[:q][:valor_gteq] if params[:q][:valor_gteq] != ''
				ransack_params["valor_lteq"] = params[:q][:valor_lteq] if params[:q][:valor_lteq] != ''
				ransack_params["liquidacao_nota_fiscal_numero_eq"] = params[:q][:liquidacao_nota_fiscal_numero_eq] if params[:q][:liquidacao_nota_fiscal_numero_eq] != ''
				ransack_params["contas_bancarias_por_pagamento_conta_bancaria_numero_da_conta_eq"] = params[:q][:contas_bancarias_por_pagamento_conta_bancaria_numero_da_conta_eq] if params[:q][:contas_bancarias_por_pagamento_conta_bancaria_numero_da_conta_eq] != ''
			end

			@fontes_de_recursos = contexto_atual.fontes_de_recursos

			if params[:liquidacao_id]
				@liquidacao = Contabilidade::Liquidacao.find( params[:liquidacao_id] )
				@q = @liquidacao.pagamentos.joins(liquidacao: [empenho: [orcamento_da_despesa: [elemento_de_despesa_por_subacao: [subacao: :unidade_orcamentaria], fonte_de_recursos: :fonte_stn]]]).includes(liquidacao: [empenho: [orcamento_da_despesa: [elemento_de_despesa_por_subacao: [subacao: :unidade_orcamentaria], fonte_de_recursos: :fonte_stn]]]).where(resto_a_pagar: restos_a_pagar).where(loa_unidades_orcamentarias: {id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id) }).order('contabilidade_pagamentos.data DESC').ransack(ransack_params)
			else
				if params[:pendentes]
					@q = contexto_atual.pagamentos.joins(liquidacao: [empenho: [orcamento_da_despesa: [elemento_de_despesa_por_subacao: [subacao: :unidade_orcamentaria], fonte_de_recursos: :fonte_stn]]]).includes(liquidacao: [empenho: [orcamento_da_despesa: [elemento_de_despesa_por_subacao: [subacao: :unidade_orcamentaria], fonte_de_recursos: :fonte_stn]]]).where(loa_unidades_orcamentarias: {id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id) }).where("resto_a_pagar is ?", restos_a_pagar).order('data DESC').where(status: :solicitado).ransack(ransack_params)
				else
					@q = contexto_atual.pagamentos.joins(liquidacao: [empenho: [orcamento_da_despesa: [elemento_de_despesa_por_subacao: [subacao: :unidade_orcamentaria], fonte_de_recursos: :fonte_stn]]]).includes(liquidacao: [empenho: [orcamento_da_despesa: [elemento_de_despesa_por_subacao: [subacao: :unidade_orcamentaria], fonte_de_recursos: :fonte_stn]]]).where("resto_a_pagar is ?", restos_a_pagar).order('data DESC').ransack(ransack_params)
				end
			end
		else
			@fontes_de_recursos = contexto_atual.fontes_de_recursos

			if params[:liquidacao_id]
				@liquidacao = Contabilidade::Liquidacao.find( params[:liquidacao_id] )
				@q = @liquidacao.pagamentos.joins(liquidacao: [empenho: [orcamento_da_despesa: [elemento_de_despesa_por_subacao: [subacao: :unidade_orcamentaria], fonte_de_recursos: :fonte_stn]]]).includes(liquidacao: [empenho: [orcamento_da_despesa: [elemento_de_despesa_por_subacao: [subacao: :unidade_orcamentaria], fonte_de_recursos: :fonte_stn]]]).where(resto_a_pagar: restos_a_pagar).where(loa_unidades_orcamentarias: {id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id) }).order('contabilidade_pagamentos.data DESC').search(params[:q])
			else
				if params[:pendentes]
					@q = contexto_atual.pagamentos.joins(liquidacao: [empenho: [orcamento_da_despesa: [elemento_de_despesa_por_subacao: [subacao: :unidade_orcamentaria], fonte_de_recursos: :fonte_stn]]]).includes(liquidacao: [empenho: [orcamento_da_despesa: [elemento_de_despesa_por_subacao: [subacao: :unidade_orcamentaria], fonte_de_recursos: :fonte_stn]]]).where(loa_unidades_orcamentarias: {id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id) }).where("resto_a_pagar is ?", restos_a_pagar).order('data DESC').where(status: :solicitado).search(params[:q])
				else
					@q = contexto_atual.pagamentos.joins(liquidacao: [empenho: [orcamento_da_despesa: [elemento_de_despesa_por_subacao: [subacao: :unidade_orcamentaria], fonte_de_recursos: :fonte_stn]]]).includes(liquidacao: [empenho: [orcamento_da_despesa: [elemento_de_despesa_por_subacao: [subacao: :unidade_orcamentaria], fonte_de_recursos: :fonte_stn]]]).where(loa_unidades_orcamentarias: {id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id) }).where("resto_a_pagar is ?", restos_a_pagar).order('data DESC').search(params[:q])
				end
			end
		end

		@pagamentos = @q.result(distinct: false).paginate(page: params[:page], per_page: 10)
		
		if current_usuario.desenvolvedor?
			@unidades_gestoras = Loa::UnidadeGestora.all.order("loa_unidades_gestoras.codigo::integer").uniq
			@unidades_orcamentarias = contexto_atual.unidades_orcamentarias.order("loa_unidades_orcamentarias.codigo", "loa_unidades_orcamentarias.nome").uniq
		else
			@unidades_gestoras = Loa::UnidadeGestora.all.order("loa_unidades_gestoras.codigo::integer").uniq
			@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
		@contas_bancarias = Base::ContaBancaria.where("data_de_inativacao >= ? OR data_de_inativacao is null", Date.today).all
		@credores = Base::Pessoa.includes(:tipo_de_pessoa).order(:nome)
		@elementos_de_despesa = contexto_atual.elementos_de_despesa.order(:codigo)
		@sub_elementos_de_despesa = @q.liquidacao_empenho_orcamento_da_despesa_elemento_de_despesa_por_subacao_elemento_de_despesa_codigo_eq.present? ? Contabilidade::SubElementoDeDespesa.joins(:elemento_de_despesa).where("base_elementos_de_despesa.codigo = ?", @q.liquidacao_empenho_orcamento_da_despesa_elemento_de_despesa_por_subacao_elemento_de_despesa_codigo_eq).distinct : []
		@tipos_de_nota_fiscal = Contabilidade::Liquidacao.nota_fiscal_tipos.sort_by{ |tipo| tipo }
		if request.format.pdf?
			titulo2 = ""
			titulo3 = ""
			if params[:q].present? && params[:q]["liquidacao_empenho_orcamento_da_despesa_elemento_de_despesa_por_subacao_subacao_unidade_orcamentaria_unidade_gestora_id_eq"].present?
				unidade_gestora = Loa::UnidadeGestora.find(params[:q]["liquidacao_empenho_orcamento_da_despesa_elemento_de_despesa_por_subacao_subacao_unidade_orcamentaria_unidade_gestora_id_eq"])
				titulo2 += "Unidade Gestora: #{unidade_gestora.codigo_e_nome} - "
			elsif params[:q].present? && params[:q]["liquidacao_empenho_unidade_orcamentaria_id_eq"].present?
				unidade_gestora = Loa::UnidadeOrcamentaria.find(params[:q]["liquidacao_empenho_unidade_orcamentaria_id_eq"]).unidade_gestora
				titulo2 += "Unidade Gestora: #{unidade_gestora.codigo_e_nome} - "
			else
				titulo2 += "Unidade Gestora: CONSOLIDADO - "
			end
			if params[:q].present? && params[:q]["liquidacao_empenho_pessoa_id_eq"].present?
				fornecedor = Base::Pessoa.find(params[:q]["liquidacao_empenho_pessoa_id_eq"])
				titulo3 += "Fornecedor: #{fornecedor.nome_e_cpf_ou_cnpj} - "
			end

			titulo2 += "Período: #{params[:q]["data_gteq"]} até #{params[:q]["data_lteq"]} " if params[:q].present? and (params[:q]["data_gteq"].present? || params[:q]["data_lteq"].present?)
			titulo2 += "Nº do Empenho: #{params[:q][:liquidacao_empenho_numero_do_empenho_eq]} - " if params[:q].present? and params[:q][:liquidacao_empenho_numero_do_empenho_eq].present?
			titulo3 += "Nª da Liquidação: #{params[:q][:liquidacao_empenho_numero_formatado_liquidacao_eq]} - " if params[:q].present? and params[:q][:liquidacao_empenho_numero_formatado_liquidacao_eq].present?
			titulo3 += "Nº do Processo: #{params[:q][:liquidacao_empenho_projeto_numero_do_processo_eq]} - " if params[:q].present? and params[:q][:liquidacao_empenho_projeto_numero_do_processo_eq].present?
			@lista_pagamentos = @q.result(distinct: false)
		end

		@configuracoes = Configuracao.last
		respond_to do |format|
			format.html

			format.pdf do
				render pdf: "pagamentos",
				template: 'contabilidade/pagamentos/index.pdf.slim',
				orientation: 'Landscape',
				header: {
					html: {
						template: 'layouts/_cabecalho_pdf.html.slim',
						locals: { titulo1: 'Relação de Pagamentos' , titulo2: titulo2, titulo3: titulo3 }
					},
					spacing: 0
				},
				footer: { right: '[page]', font_size: 8 },
				disable_smart_shrinking: true,
				dpi: '96',
				margin: @configuracoes.margens_customizadas(top: 4)
			end
		end
	end

	# GET /contabilidade/pagamentos/new
	def new
		if @liquidacao.present?
			if @liquidacao.estornada?
				redirect_to @liquidacao, alert: 'Não é possível realizar um pagamento para uma liquidação estornada ou sem saldo à pagar.'
			elsif !@liquidacao.liquidacao_confirmada? && !logado_na_contabilidade?
				redirect_to @liquidacao, alert: 'Não é possível realizar um pagamento antes de confirmar a liquidação.'
			elsif @liquidacao.liquidacoes_do_controle_de_pagamento.size > 0
				redirect_to @liquidacao, alert: 'Não é possível realizar um pagamento manualmente para liquidações contidas em controles de pagamento.'
			elsif @liquidacao.itens_da_nota_fiscal.any? && !@liquidacao.total_dos_itens_fecha_com_liquidacao?
				if contabilidade_atual.present?
					redirect_to contabilidade_liquidacao_path(@liquidacao), alert: 'Total dos itens não está de acordo com o valor da liquidação.'
				else
					redirect_to administrativo_liquidacao_path(@liquidacao), alert: 'Total dos itens não está de acordo com o valor da liquidação.'
				end
			# elsif @liquidacao.empenho.possui_metas_fisicas? && !@liquidacao.metas_fisicas_da_liquidacao.present?
			# 	redirect_to @liquidacao, alert: 'Na ação selecionada no empenho desta liquidação, há metas físicas. Adicione, na liquidação, as metas físicas para poder realizar o pagamento.'
			end
		end
		@pagamento = inicializa_pagamento

		if @liquidacao.present? && @liquidacao.orcamento != contexto_atual
			@pagamento.resto_a_pagar = true
		elsif params[:restos_a_pagar].present?
			@pagamento.resto_a_pagar = (params[:restos_a_pagar].present? && params[:restos_a_pagar] == "true")
		end

		@ultimo_pagamento = Contabilidade::Pagamento.find(params[:ultimo_pagamento_id]) if params[:ultimo_pagamento_id].present?

		disponibiliza_dependencias
		@pagamento[:prepagamento] = params[:prepagamento]
		if params[:atributos].present?
			reconstroi_gerador( @pagamento, params[:atributos] )
		end

		if params[:empenho_id].present?
			@pagamento.empenho_id = params[:empenho_id].to_i
			@pagamento.pagamento_de_liquidacao_filha = true
		end

		@pagamento.nao_gerar_movimentacoes = params[:nao_gerar_movimentacoes]
	end

	# POST /contabilidade/liquidacoes/1/pagamentos
	def create
		ActiveRecord::Base.transaction do
			begin
				@pagamento = inicializa_pagamento(pagamento_params)
				if @pagamento.liquidacao.confirmado? && @pagamento.resto_a_pagar?
					@pagamento.processado = true
				else
					@pagamento.processado = false
				end
				if params[:contabilidade_pagamento][:orcamento_id].blank?
					@pagamento.orcamento_id = @pagamento.try(:liquidacao).try(:orcamento_id)
				end

				@pagamento.skip_callback = true
				if @pagamento.save!
					@pagamento.skip_callback = false
					@pagamento.gerar_todos_os_movimentos(:data, contexto_atual)
					if @pagamento.esta_confirmado? && @pagamento.empenho.pessoa.email.present?
						Thread.new do
							enviar_email_pagamento_confirmado(@pagamento.id) if configuracao.envia_email_pagamento_confirmado?
						end
					end
					if @pagamento.faz_movimentacoes_validas?
						if @pagamento.saldo_final_da_conta_bancaria_valido?
							redirect_to @pagamento, notice: 'Pagamento foi criado com sucesso.'
						else
							raise StandardError.new "Conta bancariá ficará negativa, refaça o lançamento ou verifique o saldo da Conta."
						end
					else
						error = mensagem_de_erro_das_movimentacoes_erradas( @pagamento )
						redirect_to new_contabilidade_pagamento_path(liquidacao_id: @pagamento.liquidacao.id, atributos: pagamento_params), alert: error
						raise ActiveRecord::Rollback
					end
				end
			rescue => exception
				if params[:contabilidade_pagamento][:orcamento_id].present?
					@pagamento.resto_a_pagar = true
				end
				disponibiliza_dependencias
				mensagem = 'Não foi possível criar o pagamento, verifique as informações.'  + exception.message
				flash.now[:alert] = mensagem
				render :new
				raise ActiveRecord::Rollback
			end
		end
	end

	# GET /contabilidade/pagamentos/1
	def show
		@exibir_alerta_contexto = self.send(:exibir_alerta_de_contexto?, @pagamento&.data)

		respond_to do |format|
			format.json { render json: @pagamento }
			format.html
		end
	end

	# GET /contabilidade/pagamentos/1/edit
	def edit
		if @pagamento.liquidacao.estornada?
			redirect_to @pagamento, alert: 'Não é possível realizar um pagamento para uma liquidação estornada.'
		elsif @pagamento.estornado?
			redirect_to @pagamento, alert: 'Não é possível editar um pagamento que já foi estornado.'
		end
	end

	# PATCH/PUT /contabilidade/pagamentos/1
	def update
		ActiveRecord::Base.transaction do
			begin
				if contabilidade_atual.present?
					@pagamento.data = pagamento_params[:data_da_solicitacao]
				end

				@pagamento.skip_callback = true
				if @pagamento.update!(pagamento_params)
					@pagamento.skip_callback = false
					@pagamento.gerar_todos_os_movimentos(:data, contexto_atual)
				end

				if @pagamento.saldo_final_da_conta_bancaria_valido?
					redirect_to @pagamento, notice: 'Pagamento foi atualizado com sucesso.'
				else
					raise StandardError.new "Conta bancariá ficará negativa, refaça o lançamento ou verifique o saldo da Conta."
				end
			rescue => exception
				disponibiliza_contas_bancarias
				flash.now[:alert] = 'Não foi possível realizar o pagamento. , verifique as informações.' + exception.message
				render :edit
				raise ActiveRecord::Rollback
			end
		end
	end

	# DELETE /contabilidade/pagamentos/1
	def destroy
		ActiveRecord::Base.transaction do
			mensagem = apaga_e_retorna_mensagem(@pagamento)
			if contabilidade_atual.present?
				redirect_to contabilidade_liquidacao_path(@pagamento.liquidacao), mensagem
			else
				redirect_to administrativo_liquidacao_path(@pagamento.liquidacao), mensagem
			end
		end
	end

	#GET /licitacao/pedidos/1/fornecedores
	def editar_retencoes_de_folha
		return if bloqueia_usuario_com_base_em 'update'
		@tipos_de_acao = Contabilidade::Retencao.tipos_de_acao
		@contas_extra_orcamentarias = @pagamento.unidade_orcamentaria_do_exercicio.contas_extra_orcamentarias

		if params[:todos].present? && params[:todos] == "true"
			contas_extra_orcamentarias_por_unidade = @pagamento.unidade_orcamentaria_do_exercicio.contas_extra_por_unidades_orcamentarias
			contas_extra_orcamentarias_por_unidade.each do |conta_extra_por_unidade|
				if conta_extra_por_unidade.conta_extra_orcamentaria.present?
					retencao = @pagamento.retencoes.find_by(conta_extra_orcamentaria_id: conta_extra_por_unidade.conta_extra_orcamentaria.id)
					@pagamento.retencoes.build(conta_extra_orcamentaria: conta_extra_por_unidade.conta_extra_orcamentaria) unless retencao.present?
				end
			end
		else
			@pagamento.retencoes.build if @pagamento.retencoes.empty?
		end
	end

	#PATCH /licitacao/pedidos/1/fornecedores
	def atualiza_retencoes_de_folha
		return if bloqueia_usuario_com_base_em 'update'
		if @pagamento.update( pagamento_params )
			redirect_to @pagamento, notice: 'Retenção foi calculada com sucesso.'
		else
			@tipos_de_acao = Contabilidade::Retencao.tipos_de_acao
			@contas_extra_orcamentarias = @pagamento.unidade_orcamentaria_do_exercicio.contas_extra_orcamentarias
			render :editar_retencoes_de_folha
		end
	end

	# PUT /contabilidade/pagamento/1/atualizar_prepagamento_em_pagamento
	def atualizar_prepagamento_em_pagamento
		ActiveRecord::Base.transaction do
			if @pagamento.estornado? || @pagamento.liquidacao.estornada?
				redirect_to @pagamento.liquidacao, alert: 'Não é possível converter de pagamento para prepagamento, pois já foi estornado.'
			else
				if @pagamento.update(prepagamento: false)
					redirect_to @pagamento.liquidacao, notice: 'Pagamento foi atualizado com sucesso.'
				else
					redirect_to @pagamento.liquidacao, notice: 'Não foi possivel converter em prepagamento.'
				end
			end
		end
	end

	# DELETE /contabilidade/pagamento/1/remover_retencoes
	def remover_retencoes
		if @pagamento.retencoes.present?
			@pagamento.remover_retencoes
			redirect_to @pagamento, notice: 'Retenções removidas com sucesso.'
		else
			redirect_to @pagamento, alert: 'Não há retenções calculadas para serem removidas.'
		end
	end

	# PATCH /contabilidade/pagamentos/1/enviar_para_controladoria
	def enviar_para_controladoria
		ActiveRecord::Base.transaction do
			@pagamento.status = 'enviado_para_controladoria'
			if @pagamento.save(validate: false)
				redirect_to @pagamento, success: 'O pagamento foi encaminhado para a controladoria com sucesso.'
			else
				redirect_to @pagamento, alert: 'Não foi possível encaminhar o pagamento. Por favor, confira se seu pagamento contém erros'
			end
		end
	end

	# PATCH /contabilidade/pagamentos/1/retornar_para_administrativo
	def retornar_para_administrativo
		ActiveRecord::Base.transaction do
			if @pagamento.retornar_para_administrativo!
				redirect_to @pagamento, success: 'O pagamento foi enviado para a administração para correção dos erros.'
			else
				redirect_to @pagamento, alert: 'Não foi possível encaminhar o pagamento. Por favor, confira se ele contém erros'
			end
		end
	end

	# PATCH /contabilidade/pagamentos/1/enviar_para_administrativo
	def enviar_para_administrativo
		return if bloqueia_usuario_com_base_em 'update'
		ActiveRecord::Base.transaction do
			if @pagamento.enviar_para_administrativo!
				redirect_to @pagamento, success: 'O pagamento foi enviado para o Setor Administrativo.'
			else
				redirect_to @pagamento, alert: 'Não foi possível encaminhar o pagamento. Por favor, confira se ele contém erros'
			end
		end
	end

	# PATCH /contabilidade/pagamentos/1/enviar_para_contabilidade
	def enviar_para_contabilidade
		ActiveRecord::Base.transaction do
			if @pagamento.enviar_para_contabilidade!
				redirect_to @pagamento, success: 'O pagamento foi enviado para a contabilidade.'
			else
				redirect_to @pagamento, alert: 'Não foi possível encaminhar o pagamento. Por favor, confira se ele contém erros'
			end
		end
	end

	# PATCH /contabilidade/pagamentos/1/confirmar_pagamento
	def confirmar_pagamento
		ActiveRecord::Base.transaction do
			if @pagamento.confirmar!
				redirect_to @pagamento, success: 'O pagamento foi confirmado.'
				Thread.new do
					enviar_email_pagamento_confirmado(@pagamento.id) if configuracao.envia_email_pagamento_confirmado?
				end
			else
				redirect_to @pagamento, alert: 'Não foi possível encaminhar o pagamento. Por favor, confira se ele contém erros'
			end
		end
	end

	def cancelar_estorno
		return if bloqueia_usuario_com_base_em 'update'

		ActiveRecord::Base.transaction do
			if @pagamento.estornado? && !@pagamento.enviado_ao_sim? && !@pagamento.esta_em_um_lote_bancario?
				if @pagamento.estorno_de_pagamento.cancela_estorno
					redirect_to @pagamento, success: 'O estorno do pagamento foi cancelado.'
				else
					redirect_to @pagamento, alert: "Cancelamento do estorno do pagamento não pode ser feito. #{@pagamento.estorno_de_pagamento.errors.full_messages.join(" ")}"
				end
			else
				redirect_to @pagamento, alert: "Cancelamento do estorno do pagamento não pode ser feito. #{@pagamento.estorno_de_pagamento.errors.full_messages.join(" ")}"
			end
		end
	end

	def atualiza_linha
		@pagamento.gera_linha_para_arquivo_do_sim
		redirect_to @pagamento, success: "Linha do SIM Atualizada"
	end


	private
	def set_pagamento
		@pagamento = Contabilidade::Pagamento.find(params[:id])
	end

	def set_liquidacao
		@liquidacao = Contabilidade::Liquidacao.find(params[:liquidacao_id]) if params[:liquidacao_id]
	end

	def inicializa_pagamento params={}

		if contabilidade_atual.present?
			status = :confirmado
			data = params[:data_da_solicitacao]
		else
			status = :solicitado
		end
		if @liquidacao.present?
			@liquidacao.pagamentos.new(params.merge(status: status, data: data))
		else
			Contabilidade::Pagamento.new(params.merge(status: status, data: data))
		end
	end

	def verifica_conta_bancaria
		if @liquidacao.present?
			@liquidacao = @pagamento.liquidacao if @liquidacao.blank?

			unless @liquidacao.empenho.pessoa.tem_contas_bancarias?
				@mensagem_de_alerta_das_pessoas_sem_contas_bancarias = mensagem_de_alerta_das_pessoas_sem_contas_bancarias( @liquidacao.empenho.pessoa )
			end
		end
	end

	def disponibiliza_dependencias
		@tipos_de_lancamento = Contabilidade::Pagamento.tipo_de_lancamentos
		@unidades_orcamentarias = []
		@pessoas_contas_bancarias = @pagamento.liquidacao.empenho.pessoa.pessoas_contas_bancarias rescue []

		if params[:liquidacao_id].blank?
			disponibiliza_empenhos
			disponibiliza_liquidacoes
		end

		disponibiliza_contas_bancarias
		verifica_conta_bancaria
		@pagamento.ultimo_pagamento_id = params[:ultimo_pagamento_id] unless @pagamento.ultimo_pagamento_id.present?
		@ultimo_pagamento_id = @pagamento.ultimo_pagamento_id
	end

	def disponibiliza_empenhos
		@orcamentos = Orcamento.all.order(exercicio: :desc).where("orcamentos.exercicio < ?", contexto_atual.exercicio)

		if @pagamento.present? && @pagamento.resto_a_pagar?

			if params[:contabilidade_pagamento].present? && params[:contabilidade_pagamento][:orcamento_da_liquidacao_id].present?
				contexto_selecionado = Orcamento.find_by_id(params[:contabilidade_pagamento][:orcamento_da_liquidacao_id])
				@empenhos = contexto_selecionado.empenhos.confirmados.de_restos_a_pagar.joins(:liquidacoes, orcamento_da_despesa: [elemento_de_despesa_por_subacao: [subacao: :unidade_orcamentaria]]).where(loa_unidades_orcamentarias: {id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id) }).merge(Contabilidade::Liquidacao.confirmadas).distinct

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

			else
				@empenhos = []
				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)).order("loa_unidades_orcamentarias.codigo")
				end
			end
		else
			orcamento = contabilidade_atual.present? ? contabilidade_atual : contexto_atual
			@empenhos = orcamento.empenhos.confirmados.do_orcamento.joins(:liquidacoes, orcamento_da_despesa: [elemento_de_despesa_por_subacao: [subacao: :unidade_orcamentaria]]).where(
				contabilidade_liquidacoes: {
					status: Contabilidade::Liquidacao.status.reject{ |k| k == "solicitado"}.values
				},
				loa_unidades_orcamentarias:{
					id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)
				}
			).distinct
		end
	end

	def disponibiliza_liquidacoes
		if params[:contabilidade_pagamento].present? && params[:contabilidade_pagamento][:orcamento_da_liquidacao_id].present?
			orcamento = Orcamento.find_by_id(params[:contabilidade_pagamento][:orcamento_da_liquidacao_id])
		else
			orcamento = contabilidade_atual.present? ? contabilidade_atual : contexto_atual
		end

		@liquidacoes_confirmadas =
			if params[:contabilidade_pagamento].present? && params[:contabilidade_pagamento][:empenho_id].present?
				empenho_id = params[:contabilidade_pagamento][:empenho_id]
				orcamento.empenhos.confirmados.find(empenho_id).liquidacoes.confirmadas
			else
				[]
			end
	end

	def disponibiliza_contas_bancarias
		@pagamento.contas_bancarias_por_pagamento.build if @pagamento.contas_bancarias_por_pagamento.empty?
		if @pagamento.empenho.present? || @pagamento.liquidacao.present?
			if @pagamento.liquidacao.try(:restos_a_pagar?)
				@unidade_orcamentaria = Loa::UnidadeOrcamentariaVinculada.where(orcamento: @pagamento.empenho.orcamento_id, unidade_orcamentaria_vinculada_id: @pagamento.empenho.unidade_orcamentaria.id).first.try(:unidade_orcamentaria)
				@contas_bancarias = @unidade_orcamentaria.contas_bancarias.left_outer_joins(agencia: :banco).order(conta_caixa_pcasp: :desc, sigla: :asc, numero_da_conta: :asc) rescue []
			else
				@contas_bancarias = @pagamento.empenho.unidade_orcamentaria.contas_bancarias.left_outer_joins(agencia: :banco).order(conta_caixa_pcasp: :desc, sigla: :asc, numero_da_conta: :asc)
			end
		else
			@contas_bancarias = []
		end
	end

	# Permite apenas os parâmetros específicos
	def pagamento_params
		params.require(:contabilidade_pagamento).permit(:orcamentario_iss,:extraorcamentario_iss,:extraorcamentario_inss_pj,:orcamentario_irpj,:extraorcamentario_irpj,:extraorcamentario_inss_pf,:orcamentario_irpf,:extraorcamentario_irpf,
			:data_da_solicitacao, :empenho_id, :liquidacao_id, :estornado, :resto_a_pagar,:remover_retencoes_do_pagamento,:unidade_orcamentaria_do_empenho_id,
			:numero, :numero_de_caixa, :data, :valor, :evento_contabil_id, :prepagamento, :decorrente_de,:orcamento_id, :orcamento_da_liquidacao_id, :forma_de_pagamento,
			:historico, :isento_de_inss, :isento_de_iss, :isento_de_irrf, :valor_do_inss, :valor_do_irrf, :valor_do_iss, :tipo_de_lancamento, :ultimo_pagamento_id, :pessoa_conta_bancaria_id,
			:pagamento_de_liquidacao_filha, :nao_gerar_movimentacoes, :numero_do_cheque, :simplificado,
			retencoes_attributes: [:id, :conta_extra_orcamentaria_id,:tipo_de_acao, :valor_calculado, :pagamento_id, :_destroy],
			contas_bancarias_por_pagamento_attributes: [:id, :conta_bancaria_id, :valor_pago, :_destroy]
		)
	end
end
