require 'active_support/concern'

module GeradorDeEventosContabeis extend ActiveSupport::Concern
	include SimConcern

	attr_accessor :evento_contabil_padrao

	attr_accessor :eventos_contabeis_por_objeto
	attr_accessor :eventos_ddr

	attr_accessor :skip_callback

	module ClassMethods
		attr_reader :acao_id, :atributo_data, :atributo_codigo_movimentacao

		#private

		def gerador_de_eventos_contabeis(params={})
			@acao_id = params[:codigo]
			@atributo_data = params[:atributo_data]
			@atributo_codigo_movimentacao = params[:atributo_codigo_movimentacao]
		end
	end

	included do
		has_many :eventos_contabeis_por_gerador, as: :gerador, class_name: "Contabilidade::EventoContabilPorGerador"#, dependent: :destroy
		has_many :movimentacoes_do_plano_de_contas, as: :gerador, class_name: "Contabilidade::MovimentacaoDoPlanoDeContas"#, dependent: :destroy
		has_many :tentativas_de_movimentacoes_do_plano_de_contas, as: :modulo,class_name: "Contabilidade::TentativaDeMovimentacaoDoPlanoDeContas"#, dependent: :destroy
		accepts_nested_attributes_for :movimentacoes_do_plano_de_contas
		accepts_nested_attributes_for :eventos_contabeis_por_gerador
		#before_validation :verifica_se_ja_existe_balancete_de_verificacao_gerado_pro_mes, if: Proc.new{ Configuracao.last.try(:utiliza_evento_contabil?) }

		#before_destroy :verifica_se_ja_existe_balancete_de_verificacao_gerado_pro_mes, if: Proc.new{ Configuracao.last.try(:utiliza_evento_contabil?) }
		validate :deve_ter_conta_debito_e_credito_nos_eventos_contabeis, if: Proc.new{ |objeto| pode_gerar_movimentacao? }, unless: Proc.new { Rails.env.test? }

		after_validation :nova_atribuicao_de_eventos_contabeis, if: Proc.new{ Configuracao.last.try(:utiliza_evento_contabil?) && executa_eventos }
		after_validation :cria_eventos_contabeis_por_gerador, if: Proc.new{ |objeto| (objeto.eventos_contabeis_por_objeto.present? || objeto.eventos_ddr.present?) && gera_movimentacoes_na_data? }
		after_validation :apagar_movimentos, if: Proc.new{ gera_movimentacoes_na_data? && executa_eventos }
		after_validation :define_tipo_de_movimentacao, if: Proc.new{ |objeto| (objeto.eventos_contabeis_por_objeto.present? || objeto.eventos_ddr.present?) && gera_movimentacoes_na_data? }

		after_save :atribui_codigo_para_movimentacoes, if: Proc.new { gera_movimentacoes_na_data? && executa_eventos }
		after_save :deleta_movimentacoes_antigas, if: Proc.new { pode_deletar_movimentacoes? && !eh_solicitacao_orcamentaria? && gera_movimentacoes_na_data? && executa_eventos }
		after_save :deleta_movimentacoes_antigas_solicitacao_orcamentaria, if: Proc.new { eh_solicitacao_orcamentaria? && gera_movimentacoes_na_data? && executa_eventos }

		after_destroy :remove_dependentes

		def remove_dependentes
			ActiveRecord::Base.connection.execute("DELETE FROM contabilidade_eventos_contabeis_por_gerador WHERE id in (#{self.eventos_contabeis_por_gerador.ids.join(",")})") if self.eventos_contabeis_por_gerador.ids.size > 0
			ActiveRecord::Base.connection.execute("DELETE FROM contabilidade_movimentacoes_do_plano_de_contas WHERE id in (#{self.movimentacoes_do_plano_de_contas.ids.join(",")})") if self.movimentacoes_do_plano_de_contas.ids.size > 0
			ActiveRecord::Base.connection.execute("DELETE FROM contabilidade_tentativas_de_movimentacoes_do_plano_de_contas WHERE id in (#{self.tentativas_de_movimentacoes_do_plano_de_contas.ids.join(",")})") if self.tentativas_de_movimentacoes_do_plano_de_contas.ids.size > 0
		end

		def pode_gerar_movimentacao?
			# validação criada pois nem todos os models que irão lançar movimentações do plano de contas possuem status confirmado ou até msm status
			# por ex. empenho só deve gerar movimentações quando confirmado.
			return false if (Configuracao.last.try(:utiliza_evento_contabil?) == false )
		end

		def executa_eventos
			exercicio_para_pcasp = Configuracao.last.try(:exercicio_para_pcasp).to_i

			# não gerar eventos para liquidação do exercício anterior (processado)
			if contexto_atual.present?
				if self.class.name == 'Contabilidade::Liquidacao' && self.data_da_liquidacao&.year.to_i > 0 && contexto_atual.present? && self.data_da_liquidacao&.year.to_i < contexto_atual.exercicio.to_i
					return false
				end
			end

			if (contexto_atual.present? && (contexto_atual.exercicio.to_i < exercicio_para_pcasp || exercicio_para_pcasp == 0))
				return false
			else
				if self.skip_callback.present? && self.skip_callback == true
					return false
				else
					return true
				end
			end
		end

		def gera_movimentacoes_na_data?(orcamento = nil, verificar_balancete = true)
			if executa_eventos
				orcamento = contexto_atual if orcamento.nil?

				nome_da_classe = self.class.name
				permite_gerar = verificar_balancete ? Configuracao.last.try(:utiliza_evento_contabil?) && !existe_balancete_gerado_na_data? : Configuracao.last.try(:utiliza_evento_contabil?)

				if nome_da_classe == "Contabilidade::Liquidacao" || nome_da_classe == "Contabilidade::AnulacaoDoEmpenho"
					empenho_origem = self.empenho.empenho_de_restos_a_pagar
					if (empenho_origem.present? && empenho_origem.orcamento.exercicio < orcamento.exercicio) || (nome_da_classe == "Contabilidade::Liquidacao" && self.respond_to?(:restos_a_pagar) &&  self.restos_a_pagar == true && orcamento.nil?)
						return false
					else
						return permite_gerar ? true : false
					end
				elsif nome_da_classe == "Contabilidade::Pagamento" || nome_da_classe == "Contabilidade::EstornoDeLiquidacao"
					empenho_origem = self.liquidacao.empenho.empenho_de_restos_a_pagar
					if empenho_origem.present? && empenho_origem.orcamento.exercicio < orcamento.exercicio
						return false
					else
						return permite_gerar ? true : false
					end
				elsif nome_da_classe == "Contabilidade::EstornoDePagamento"
					empenho_origem = self.pagamento.liquidacao.empenho.empenho_de_restos_a_pagar
					if empenho_origem.present? && empenho_origem.orcamento.exercicio < orcamento.exercicio
						return false
					else
						return permite_gerar ? true : false
					end
				else
					return permite_gerar
				end
			else
				return false
			end
		end

		def existe_balancete_gerado_na_data?
			if data_movimentada.nil?
				return false
			else 
				orcamento_id = Orcamento.find_by(exercicio: data_movimentada.year)
				balancete = 
					Contabilidade::BalanceteDeVerificacao.find_by(
						orcamento_id: orcamento_id,
						mes_de_referencia: data_movimentada.month
					)
				return balancete.present?
			end
		end

		def atribui_evento_contabil_padrao
			if evento_contabil_padrao.nil? && self.acao_do_sistema.present? && self.orcamento.present?
				evento = self.acao_do_sistema.eventos_contabeis.find_by(orcamento_id: self.orcamento.id, padrao: true)
				if evento.present?
					self.evento_contabil_padrao = evento
				end
			end
		end

		def pode_gerar_tentativa_da_movimentacao?
			if self.has_attribute?(:status)
				nome_da_classe = self.class.name
				if nome_da_classe == "Contabilidade::Empenho" || nome_da_classe == "Contabilidade::Liquidacao" || nome_da_classe == "Contabilidade::Pagamento"
					return self.solicitado? == false
				elsif nome_da_classe == "GestaoDeEstoque::RecebimentoDeMaterial" || nome_da_classe == "Administrativo::RequisicaoDeMaterial"
					return self.aberto? == false
				else
					return true
				end
			else
				return true
			end
		end

		def nova_atribuicao_de_eventos_contabeis(orcamento_atual = nil)
			if contexto_atual.present?
				@orcamento_atual = contexto_atual
			else
				@orcamento_atual = orcamento_atual
			end

			case self.class.name
			when "Contabilidade::Empenho"
				if self.respond_to?(:restos_a_pagar) &&  self.restos_a_pagar == true
					@eventos_contabeis_por_objeto = busca_eventos_do_empenho_de_restos_a_pagar
				else
					@eventos_contabeis_por_objeto = busca_eventos_do_empenho
				end
			when "Contabilidade::Liquidacao"
				@eventos_contabeis_por_objeto = busca_eventos_da_liquidacao
			when "Contabilidade::Pagamento"
				@eventos_contabeis_por_objeto = busca_eventos_do_pagamento
			when "Contabilidade::EstornoDePagamento"
				@eventos_contabeis_por_objeto = busca_eventos_do_estorno_de_pagamento
			when "GestaoDeEstoque::RecebimentoDeMaterial"
				# @eventos_contabeis_por_objeto = busca_eventos_do_recebimento
			when 'Loa::AlteracaoDeStatus'
				@eventos_contabeis_por_objeto = busca_eventos_do_ploa
			when 'Ppa::Ppa'
				@eventos_contabeis_por_objeto = busca_eventos_do_ppa
			when 'Ppa::ProjecaoDeDespesa'
				@eventos_contabeis_por_objeto = busca_eventos_da_projecao_de_despesa
			when "Projecao::CalculoPorExercicio"
				@eventos_contabeis_por_objeto = busca_eventos_de_calculo_por_exercicio
			when "Loa::OrcamentoDaDespesa"
				@eventos_contabeis_por_objeto = busca_eventos_de_orcamento_da_despesa
			when "Contabilidade::TalaoDeReceita"
				@eventos_contabeis_por_objeto = busca_eventos_do_talao_de_receita + busca_eventos_do_pagamento_da_retencao
			when 'Contabilidade::AnulacaoDoTalaoDeReceita'
				@eventos_contabeis_por_objeto = busca_eventos_da_anulacao_do_talao_de_receita
			when "Contabilidade::MedicaoDaObra"
				@eventos_contabeis_por_objeto = busca_eventos_da_medicao_da_obra
			when "Contabilidade::AnulacaoDoEmpenho"
				@eventos_contabeis_por_objeto = busca_eventos_da_anulacao_do_empenho
			when "Contabilidade::BemDoBalancete"
				@eventos_contabeis_por_objeto = busca_eventos_do_bem_do_balancete
			when "Contabilidade::SituacaoDaObra"
				@eventos_contabeis_por_objeto = busca_eventos_da_situacao_da_obra
			when "Contabilidade::Obra"
				@eventos_contabeis_por_objeto = busca_eventos_da_obra
			when "Administrativo::RequisicaoDeMaterial"
				@eventos_contabeis_por_objeto = busca_eventos_da_requisicao_de_material
			when 'Contabilidade::DespesaExtraOrcamentaria'
				@eventos_contabeis_por_objeto = busca_eventos_da_despesa_extra
			when 'Contabilidade::EstornoDeDespesaExtraOrcamentaria'
				@eventos_contabeis_por_objeto = busca_eventos_do_estorno_de_despesa_extra
			when 'Contabilidade::Retencao'
				@eventos_contabeis_por_objeto = busca_eventos_da_retencao
			when 'Contabilidade::EstornoDeLiquidacao'
				@eventos_contabeis_por_objeto = busca_eventos_do_estorno_de_liquidacao
			when 'Contabilidade::BloqueioDeDotacao'
				@eventos_contabeis_por_objeto = busca_eventos_do_bloqueio_de_dotacao
			when 'Contabilidade::SolicitacaoDeAlteracaoOrcamentaria'
				@eventos_contabeis_por_objeto = busca_eventos_da_alteracao_orcamentaria
			when 'Contabilidade::CancelamentoDeRestoAPagar'
				@eventos_contabeis_por_objeto = busca_eventos_do_cancelamento_de_resto_a_pagar
			when 'Orcamento'
				@eventos_contabeis_por_objeto = busca_eventos_do_orcamento
			when 'Contabilidade::MesDoCronogramaDoEmpenho'
				@eventos_contabeis_por_objeto = lancando_mes == true ? busca_eventos_do_cronograma_do_empenho : []
			when 'Loa::OrcamentoDaReceita'
				@eventos_contabeis_por_objeto = busca_eventos_do_orcamento_da_receita
			when 'Licitacao::Contrato'
				@eventos_contabeis_por_objeto = busca_eventos_do_contrato
			when 'Licitacao::Aditivo'
				@eventos_contabeis_por_objeto = busca_eventos_do_aditivo
			when 'Contabilidade::TransferenciaFinanceira'
				@eventos_contabeis_por_objeto = busca_eventos_da_transferencia_financeira
			when 'GestaoDeEstoque::ItemDoConsumo'
				# @eventos_contabeis_por_objeto = busca_eventos_do_item_do_consumo
			end

			@eventos_contabeis_por_objeto = @eventos_contabeis_por_objeto.select { |i| i.ativo == true } if @eventos_contabeis_por_objeto.present?
		end

		def busca_eventos_do_empenho
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[self.status.to_sym] rescue nil
			if status == 6
				status = [6, 5]
			end
			modalidade = [self.modalidade]
			uso_do_bem = Contabilidade::ConfiguracaoDoEventoContabil.status[self.uso_do_bem.to_sym] rescue nil
			tipo_de_resto_a_pagar = nil
			if (modalidade & ["global", "estimativo"] ).any?
				modalidade.push("global_ou_estimativo")
			end
			modalidade = modalidade.compact.map { |modalidade| Contabilidade::ConfiguracaoDoEventoContabil.modalidades_do_empenho[modalidade] }

			fluxo_completo_do_empenho = Configuracao.last.envia_empenho_para_contabilidade? && (status_was == 'enviado_para_contabilidade' || status_was == 'recebido')
			if fluxo_completo_do_empenho == false
				fluxo_completo_do_empenho = [false, nil]
			end

			sub_elemento_de_despesa_do_evento = sub_elemento_de_despesa

			if restos_a_pagar
				if contexto_atual.present?
					orcamento_atual = contexto_atual
				else
					orcamento_atual = @orcamento_atual
				end
				orcamento_id = orcamento_atual.id

				sub_elemento_de_despesa_do_exercicio_anterior = Contabilidade::SubElementoDeDespesa.joins(elemento_de_despesa: [ modalidade_de_aplicacao: [ grupo_de_natureza_da_despesa: :categoria_economica ] ]).where("contabilidade_sub_elementos_de_despesa.codigo = ? and base_elementos_de_despesa.codigo = ? and base_categorias_economicas.modulo_id = ? and base_categorias_economicas.modulo_type = 'Orcamento'", sub_elemento_de_despesa.try(:codigo), sub_elemento_de_despesa.try(:elemento_de_despesa).try(:codigo), orcamento_atual.id).first
				sub_elemento_de_despesa_do_evento = sub_elemento_de_despesa_do_exercicio_anterior if sub_elemento_de_despesa_do_exercicio_anterior.present?
			else
				orcamento_id = self.orcamento_id
			end

			if fonte_de_recursos_codigo_e_descricao.try(:first) == '1'
				origem_da_fonte = Contabilidade::ConfiguracaoDoEventoContabil.origens_da_fonte[:exercicio_vigente]
			else
				origem_da_fonte = Contabilidade::ConfiguracaoDoEventoContabil.origens_da_fonte[:exercicio_anterior]
			end

			if self.tipo_de_reconhecimento_do_passivo.nil?
				tipo_de_reconhecimento_do_passivo = nil
			else
				tipo_de_reconhecimento_do_passivo = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_reconhecimento_do_passivo[self.tipo_de_reconhecimento_do_passivo]
			end

			if self.classificacao_vpd.nil?
				classificacao_vpd = nil
			else
				classificacao_vpd = Contabilidade::ConfiguracaoDoEventoContabil.classificacoes_vpd[self.classificacao_vpd]
			end
			
			if movimentacao_do_plano_de_contas.present?
				originado_de_um_evento_manual = true
				conta_pcasp_do_lancamento_manual_id = movimentacao_do_plano_de_contas.conta_por_evento_contabil.conta_id
			else
				originado_de_um_evento_manual = false
				conta_pcasp_do_lancamento_manual_id = nil
			end

			fonte_comecada_em_2 = nil
			if self.fonte_de_recursos.codigo_completo.first == "2"
				aciona_em_fontes_comecadas_com_2 = true
			else
				aciona_em_fontes_comecadas_com_2 = false
			end

			eventos_inclusivos_de_dotacao_e_sem_dotacao = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:empenho],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					status: [ status, nil ],
					modalidade_do_empenho: [ modalidade, nil ],
					configurou_unidade_orcamentaria_do_empenho_na_contabilidade: [self.configurou_unidade_na_contabilidade, nil],
					empenho_complementar: [self.empenho_complementar?, nil],
					tipo_de_pessoa: [ tipos_de_pessoa_por_model, nil ],
					fluxo_completo_do_empenho: fluxo_completo_do_empenho,
					originado_de_um_evento_manual: [originado_de_um_evento_manual, nil],
					conta_pcasp_do_lancamento_manual_id: [conta_pcasp_do_lancamento_manual_id, nil],
					origem_da_fonte: [origem_da_fonte, nil],
					tipo_de_reconhecimento_do_passivo: [tipo_de_reconhecimento_do_passivo, nil],
					uso_do_bem: [uso_do_bem, nil],
					classificacao_vpd: [classificacao_vpd, nil],
					deposito: [false, nil],
					ativar_pela_subconta: [nil, false],
					aciona_em_fontes_comecadas_com_2: [aciona_em_fontes_comecadas_com_2, nil],
					abertura: [false, nil]
				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [sub_elemento_de_despesa_do_evento.try(:id), nil]
				}
			)

			eventos_exclusivos_de_dotacao = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:empenho],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:exclusivo_de_dotacoes] ,
					status: [ status, nil ],
					modalidade_do_empenho: [ modalidade, nil ],
					configurou_unidade_orcamentaria_do_empenho_na_contabilidade: [self.configurou_unidade_na_contabilidade, nil],
					empenho_complementar: [self.empenho_complementar?, nil],
					tipo_de_pessoa: [ tipos_de_pessoa_por_model, nil ],
					fluxo_completo_do_empenho: fluxo_completo_do_empenho,
					originado_de_um_evento_manual: [originado_de_um_evento_manual, nil],
					conta_pcasp_do_lancamento_manual_id: [conta_pcasp_do_lancamento_manual_id, nil],
					origem_da_fonte: [origem_da_fonte, nil],
					tipo_de_reconhecimento_do_passivo: [tipo_de_reconhecimento_do_passivo, nil],
					uso_do_bem: [uso_do_bem, nil],
					classificacao_vpd: [classificacao_vpd, nil],
					deposito: [false, nil],
					ativar_pela_subconta: [nil, false],
					aciona_em_fontes_comecadas_com_2: [aciona_em_fontes_comecadas_com_2, nil],
					abertura: [false, nil]
				}
			).where.not(
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: sub_elemento_de_despesa_do_evento.try(:id)
				}
			).uniq

			eventos_ativados_por_subconta = []
			eventos_ativados_por_subconta_parcial = []
			eventos_ativados_por_subconta_debito = []
			eventos_ativados_por_subconta_credito = []
			if self.sub_conta_pcasp_id.present?
				if self.movimentacao_do_plano_de_contas_id.present?
					movimentacao_associada_ao_empenho = Contabilidade::MovimentacaoDoPlanoDeContas.find(self.movimentacao_do_plano_de_contas_id)
					conta_pcasp_da_movimentacao = movimentacao_associada_ao_empenho.conta_por_evento_contabil.conta
					contas_pcasps_da_movimentacao_ids = Contabilidade::Conta.where('codigo = ?', conta_pcasp_da_movimentacao.codigo).pluck(:id) rescue nil
					conta_pcasp_da_movimentacao_par = movimentacao_associada_ao_empenho.conta_por_evento_contabil&.conta_par
					contas_pcasps_da_movimentacao_par_ids = Contabilidade::Conta.where('codigo = ?', conta_pcasp_da_movimentacao_par.codigo).pluck(:id) rescue nil
				else
					if self.operacao_de_credito_id.present?
						conta_pcasp_da_movimentacao = self.operacao_de_credito.conta
						contas_pcasps_da_movimentacao_ids = Contabilidade::Conta.where('codigo = ?', conta_pcasp_da_movimentacao.codigo).pluck(:id) rescue nil
					end
				end				

				eventos_ativados_por_subconta_parcial = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:empenho],
						orcamento_id: orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						ativar_pela_subconta: true,
						status: [ status, nil ],
						abertura: [false, nil]
					}
				).where(
					contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
						sub_elemento_de_despesa_id: sub_elemento_de_despesa_do_evento.try(:id)
					}
				).uniq

				eventos_ativados_por_subconta_debito = Contabilidade::EventoContabil.joins(:contas_por_eventos_contabeis).where(
					contabilidade_eventos_contabeis: {
						id: eventos_ativados_por_subconta_parcial.pluck(:id)
					},
					contabilidade_contas_por_eventos_contabeis: {
						tipo_de_lancamento: 0,
						conta_id: contas_pcasps_da_movimentacao_ids
					}
				).uniq

				eventos_ativados_por_subconta_credito = Contabilidade::EventoContabil.joins(:contas_por_eventos_contabeis).where(
					contabilidade_eventos_contabeis: {
						id: eventos_ativados_por_subconta_parcial.pluck(:id)
					},
					contabilidade_contas_por_eventos_contabeis: {
						tipo_de_lancamento: 0,
						conta_id: contas_pcasps_da_movimentacao_par_ids
					}
				).uniq
			end

			return (eventos_inclusivos_de_dotacao_e_sem_dotacao + eventos_exclusivos_de_dotacao + eventos_ativados_por_subconta_debito + eventos_ativados_por_subconta_credito).uniq
		end

		def busca_eventos_do_empenho_de_restos_a_pagar
			if contexto_atual.present?
				orcamento_atual = contexto_atual
			else
				orcamento_atual = @orcamento_atual
			end
			
			exercicio_restos_a_pagar = self.orcamento.exercicio == (orcamento_atual.exercicio - 1) ? 1 : 2

			eventos = Contabilidade::EventoContabil.left_outer_joins(:configuracao_do_evento_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:empenho],
					orcamento_id: orcamento_atual
				},
				contabilidade_configuracoes_do_evento_contabil: {
					resto_a_pagar: true,
					exercicio_restos_a_pagar: exercicio_restos_a_pagar
				}
			)

			return eventos
		end

		def busca_eventos_da_liquidacao
			#status = Contabilidade::ConfiguracaoDoEventoContabil.status[self.status.to_sym] rescue nil
			status_confirmado = ["confirmado","enviado_para_o_financeiro","recebido_pelo_financeiro","autorizado"].include?(self.status) ? "confirmado" : self.status
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[status_confirmado.to_sym] rescue nil
			tipo_de_resto_a_pagar = nil
			
			if self.restos_a_pagar? || self.empenho.restos_a_pagar
				liquidacao_de_restos_a_pagar = true
			else
				liquidacao_de_restos_a_pagar = [false, nil]
			end

			modalidade = [self.empenho.try(:modalidade)]
			if (modalidade & ["global", "estimativo"] ).any?
				modalidade.push("global_ou_estimativo")
			end

			modalidade = modalidade.compact.map { |modalidade| Contabilidade::ConfiguracaoDoEventoContabil.modalidades_do_empenho[modalidade] }

			sub_elemento_de_despesa_do_evento = sub_elemento_de_despesa

			if self.data_da_liquidacao.present?
				orcamento_atual = Orcamento.where(exercicio: self.data_da_liquidacao.year).first
			else
				orcamento_atual = @orcamento_atual
			end

			if liquidacao_de_restos_a_pagar

				if self.data_da_liquidacao.present? && self.data_da_liquidacao.year < orcamento_atual.exercicio
					tipo_de_resto_a_pagar = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_resto_a_pagar['rp_processado']
				else
					tipo_de_resto_a_pagar = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_resto_a_pagar['rp_nao_processado']
				end

				sub_elemento_de_despesa_do_exercicio_anterior = Contabilidade::SubElementoDeDespesa.joins(elemento_de_despesa: [ modalidade_de_aplicacao: [ grupo_de_natureza_da_despesa: :categoria_economica ] ]).where("contabilidade_sub_elementos_de_despesa.codigo = ? and base_elementos_de_despesa.codigo = ? and base_categorias_economicas.modulo_id = ? and base_categorias_economicas.modulo_type = 'Orcamento'", sub_elemento_de_despesa.try(:codigo), sub_elemento_de_despesa.try(:elemento_de_despesa).try(:codigo), orcamento_atual.id).first
				sub_elemento_de_despesa_do_evento = sub_elemento_de_despesa_do_exercicio_anterior if sub_elemento_de_despesa_do_exercicio_anterior.present?
			end

			if self.empenho.classificacao_pcasp.nil?
				classificacao_pcasp_do_empenho = nil
			else
				classificacao_pcasp_do_empenho = Contabilidade::ConfiguracaoDoEventoContabil.classificacoes_pcasp[self.empenho.classificacao_pcasp]
			end

			originado_de_um_contrato = empenho.contrato.present?

			eventos_inclusivos_de_dotacao_e_sem_dotacao = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:liquidacao],
					orcamento_id: orcamento_atual
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					status: [ status, nil ],
					modalidade_do_empenho: [ modalidade, nil ],
					resto_a_pagar: [liquidacao_de_restos_a_pagar],
					tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
					tipo_de_pessoa: [ tipos_de_pessoa_por_model, nil ],
					originado_de_um_contrato: [originado_de_um_contrato, nil],
					classificacao_pcasp: [classificacao_pcasp_do_empenho, nil]
				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [sub_elemento_de_despesa_do_evento.try(:id), nil]
				}
			)

			eventos_exclusivos_de_dotacao =  Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:liquidacao],
					orcamento_id: orcamento_atual
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:exclusivo_de_dotacoes], nil],
					status: [ status, nil ],
					modalidade_do_empenho: [ modalidade, nil ],
					resto_a_pagar: [liquidacao_de_restos_a_pagar],
					tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
					tipo_de_pessoa: [ tipos_de_pessoa_por_model, nil ],
					originado_de_um_contrato: [originado_de_um_contrato, nil],
					classificacao_pcasp: [classificacao_pcasp_do_empenho, nil]
				}
			).where.not(
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: sub_elemento_de_despesa_do_evento.try(:id)
				}
			).uniq

			#Reconhecido na Liquidação da Despesa

			eventos_com_reconhecimento = [] 

			if (self.empenho.tipo_de_reconhecimento_do_passivo == "reconhecido_na_liquidacao_da_despesa" || self.empenho.tipo_de_reconhecimento_do_passivo == "reconhecimento_no_exercicio_vigente" || self.empenho.tipo_de_reconhecimento_do_passivo == "reconhecimento_no_exercicio_anterior")
				if self.empenho.classificacao_vpd.nil?
					classificacao_vpd = nil
				else
					classificacao_vpd = Contabilidade::ConfiguracaoDoEventoContabil.classificacoes_vpd[self.empenho.classificacao_vpd]
				end

				if self.empenho.regime.nil?
					regime = nil
				else
					regime = Contabilidade::ConfiguracaoDoEventoContabil.regimes[self.empenho.regime]
				end

				if self.empenho.tipo_de_entidade.nil?
					tipo_de_entidade = nil
				else
					tipo_de_entidade = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_entidade[self.empenho.tipo_de_entidade]
				end

				detalhamento_por_vpd = self.detalhamentos_por_subelementos.map { |i| i if i.valor.to_d.positive? }.compact

				if !detalhamento_por_vpd.nil? && detalhamento_por_vpd.size > 0
					eventos_com_reconhecimento_ids = []
					detalhamento_por_vpd.each do |detalhamento_vpd|
						tipo_de_detalhamento_vpd = Contabilidade::ConfiguracaoDoEventoContabil.detalhamentos_vpd_da_liquidacao[tipo_detalhamento_vpd_da_liquidacao(detalhamento_vpd.conta.nome)]

						eventos_com_reconhecimento_parcial = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
							contabilidade_eventos_contabeis: {
								modelo: Contabilidade::EventoContabil.modelos[self.empenho.tipo_de_reconhecimento_do_passivo.to_sym],
								orcamento_id: orcamento_atual
							},
							contabilidade_configuracoes_do_evento_contabil: {
								status: [ status, nil ],
								modalidade_do_empenho: [ modalidade, nil ],
								resto_a_pagar: [liquidacao_de_restos_a_pagar],
								tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
								classificacao_vpd: [classificacao_vpd, nil],
								estorno: [false, nil],
								regime: [regime, nil],
								tipo_de_entidade: [tipo_de_entidade, nil],
								tipo_de_pessoa: [ tipos_de_pessoa_por_model, nil ],
								detalhamento_vpd_da_liquidacao: tipo_de_detalhamento_vpd,
								classificacao_pcasp: [classificacao_pcasp_do_empenho, nil]
							}
						).where(
							contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
								sub_elemento_de_despesa_id: sub_elemento_de_despesa_do_evento.try(:id)
							}
						).uniq

						eventos_com_reconhecimento_ids = eventos_com_reconhecimento_ids + eventos_com_reconhecimento_parcial.pluck(:id)
					end
					eventos_com_reconhecimento = Contabilidade::EventoContabil.where('id in (?)', eventos_com_reconhecimento_ids)
				else
					eventos_com_reconhecimento = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
						contabilidade_eventos_contabeis: {
							modelo: Contabilidade::EventoContabil.modelos[self.empenho.tipo_de_reconhecimento_do_passivo.to_sym],
							orcamento_id: orcamento_atual
						},
						contabilidade_configuracoes_do_evento_contabil: {
							status: [ status, nil ],
							modalidade_do_empenho: [ modalidade, nil ],
							resto_a_pagar: [liquidacao_de_restos_a_pagar],
							tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
							classificacao_vpd: [classificacao_vpd, nil],
							estorno: [false, nil],
							regime: [regime, nil],
							tipo_de_entidade: [tipo_de_entidade, nil],
							tipo_de_pessoa: [ tipos_de_pessoa_por_model, nil ],
							classificacao_pcasp: [classificacao_pcasp_do_empenho, nil]
						}
					).where(
						contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
							sub_elemento_de_despesa_id: sub_elemento_de_despesa_do_evento.try(:id)
						}
					).uniq
					
				end
			end

			eventos_ddr =  Contabilidade::EventoContabil.joins( :configuracao_do_evento_contabil ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:liquidacao],
					orcamento_id: orcamento_atual
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: nil,
					status: Contabilidade::ConfiguracaoDoEventoContabil.status['confirmado'.to_sym],
					resto_a_pagar: nil
				}
			)

			return (eventos_inclusivos_de_dotacao_e_sem_dotacao + eventos_exclusivos_de_dotacao + eventos_com_reconhecimento + eventos_ddr).uniq
		end

		def busca_eventos_do_pagamento
			#status = lote_bancario? ? 'aguardando_lote' : 'confirmado'
			status = 'confirmado'
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[status.to_sym]
			contas_bancarias_ids = self.contas_bancarias_por_pagamento.map{|t| t.conta_bancaria_id }
			#ids_contas_pcasp_das_contas_bancaria = Contabilidade::ContaPcaspDaContaBancariaPorOrcamento.where(conta_bancaria_id: contas_bancarias_ids).pluck(:conta_id)
			#conta_pcasp_da_conta_bancaria_id = conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.find_by(orcamento_id: orcamento_id).try(:conta_id) rescue nil
			tipo_de_resto_a_pagar = nil

			conta_pcasp_da_conta_bancaria_ids = []
			self.contas_bancarias_por_pagamento.each do |conta_bancaria|
				conta_pcasp_da_conta_bancaria_ids << self.contas_bancarias_por_pagamento.last.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.pluck(:conta_id)
			end

			if empenho.ordinario?
				modalidade_do_empenho = 'ordinario'
			else
				modalidade_do_empenho = 'global_ou_estimativo'
			end

			modalidade_do_empenho = Contabilidade::ConfiguracaoDoEventoContabil.modalidades_do_empenho[modalidade_do_empenho]

			if empenho.movimentacao_do_plano_de_contas.present?
				originado_de_um_evento_manual = true
				conta_pcasp_do_lancamento_manual_id = empenho.movimentacao_do_plano_de_contas.conta_por_evento_contabil.conta_id
			else
				originado_de_um_evento_manual = false
				conta_pcasp_do_lancamento_manual_id = nil
			end

			sub_elemento_de_despesa_do_evento = sub_elemento_de_despesa

			if try(:liquidacao).try(:restos_a_pagar?) || (liquidacao.orcamento&.exercicio&.to_i > 0 && liquidacao.orcamento&.exercicio&.to_i < orcamento.exercicio.to_i)
				pagamento_de_restos_a_pagar = true

				if self.orcamento_id.present?
					orcamento_atual = self.orcamento
				else
					orcamento_atual = @orcamento_atual
				end

				valor_processado_do_empenho = self.empenho.liquidacoes.valida.where('extract(year from data_da_liquidacao) <= ?', orcamento_atual).sum(&:valor)

				if self.liquidacao.data_da_liquidacao.present? && self.liquidacao.data_da_liquidacao.year < orcamento_atual.exercicio
					tipo_de_resto_a_pagar = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_resto_a_pagar['rp_processado']
				else
					tipo_de_resto_a_pagar = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_resto_a_pagar['rp_nao_processado']
				end

				sub_elemento_de_despesa_do_exercicio_anterior = Contabilidade::SubElementoDeDespesa.joins(elemento_de_despesa: [ modalidade_de_aplicacao: [ grupo_de_natureza_da_despesa: :categoria_economica ] ]).where("contabilidade_sub_elementos_de_despesa.codigo = ? and base_elementos_de_despesa.codigo = ? and base_categorias_economicas.modulo_id = ? and base_categorias_economicas.modulo_type = 'Orcamento'", sub_elemento_de_despesa.try(:codigo), sub_elemento_de_despesa.try(:elemento_de_despesa).try(:codigo), orcamento_atual.id).first
				sub_elemento_de_despesa_do_evento = sub_elemento_de_despesa_do_exercicio_anterior if sub_elemento_de_despesa_do_exercicio_anterior.present?
			else
				pagamento_de_restos_a_pagar = [false, nil]
			end

			if self.empenho.classificacao_vpd.nil?
				classificacao_vpd = nil
			else
				classificacao_vpd = Contabilidade::ConfiguracaoDoEventoContabil.classificacoes_vpd[self.empenho.classificacao_vpd]
			end

			if self.empenho.regime.nil?
				regime = nil
			else
				regime = Contabilidade::ConfiguracaoDoEventoContabil.regimes[self.empenho.regime]
			end

			if empenho.tipo_de_entidade.nil?
				tipo_de_entidade = nil
			else
				tipo_de_entidade = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_entidade[self.empenho.tipo_de_entidade]
			end

			eventos_inclusivos_de_dotacao_e_sem_dotacao = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:pagamento],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					resto_a_pagar: [pagamento_de_restos_a_pagar],
					status: [status, nil],
					processado: [self.processado?, nil],
					conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
					modalidade_do_empenho: [nil, modalidade_do_empenho],
					tipo_de_pessoa: [tipos_de_pessoa_por_model, nil],
					originado_de_um_evento_manual: [originado_de_um_evento_manual, nil],
					conta_pcasp_do_lancamento_manual_id: [conta_pcasp_do_lancamento_manual_id, nil],
					tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
					tipo_de_entidade: [tipo_de_entidade, nil],
					classificacao_vpd: [classificacao_vpd, nil],
					regime: [regime, nil],
					ativar_pela_subconta: [false, nil]
				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [sub_elemento_de_despesa_do_evento.try(:id), nil]
				}
			)

			eventos_exclusivos_de_dotacao =  Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:pagamento],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:exclusivo_de_dotacoes]] ,
					status: [ status, nil ],
					resto_a_pagar: [pagamento_de_restos_a_pagar],
					processado: [self.processado?, nil],
					conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
					modalidade_do_empenho: [nil, modalidade_do_empenho],
					tipo_de_pessoa: [tipos_de_pessoa_por_model, nil],
					originado_de_um_evento_manual: [originado_de_um_evento_manual, nil],
					conta_pcasp_do_lancamento_manual_id: [conta_pcasp_do_lancamento_manual_id, nil],
					tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
					tipo_de_entidade: [tipo_de_entidade, nil],
					classificacao_vpd: [classificacao_vpd, nil],
					regime: [regime, nil],
					ativar_pela_subconta: [false, nil]
				}
			).where.not(
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: sub_elemento_de_despesa_do_evento.try(:id)
				}
			).uniq

			eventos_sem_tipo =  Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:pagamento],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: nil,
					status: [ status, nil ],
					resto_a_pagar: [pagamento_de_restos_a_pagar],
					processado: [self.processado?, nil],
					conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
					modalidade_do_empenho: [nil, modalidade_do_empenho],
					tipo_de_pessoa: [tipos_de_pessoa_por_model, nil],
					originado_de_um_evento_manual: [originado_de_um_evento_manual, nil],
					conta_pcasp_do_lancamento_manual_id: [conta_pcasp_do_lancamento_manual_id, nil],
					tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
					tipo_de_entidade: [tipo_de_entidade, nil],
					classificacao_vpd: [classificacao_vpd, nil],
					regime: [regime, nil],
					ativar_pela_subconta: [false, nil]
				}
			).uniq

			eventos_ativados_por_subconta = []
			eventos_ativados_por_subconta_parcial = []
			eventos_ativados_por_subconta_debito = []
			eventos_ativados_por_subconta_credito = []
			if self.liquidacao.empenho.sub_conta_pcasp_id.present?
				if self.liquidacao.empenho.movimentacao_do_plano_de_contas_id.present?
					movimentacao_associada_ao_empenho = Contabilidade::MovimentacaoDoPlanoDeContas.find(self.liquidacao.empenho.movimentacao_do_plano_de_contas_id)
					conta_pcasp_da_movimentacao = movimentacao_associada_ao_empenho.conta_por_evento_contabil.conta
					contas_pcasps_da_movimentacao_ids = Contabilidade::Conta.where('codigo = ?', conta_pcasp_da_movimentacao.codigo).pluck(:id) rescue nil
					conta_pcasp_da_movimentacao_par = movimentacao_associada_ao_empenho.conta_por_evento_contabil&.conta_par
					contas_pcasps_da_movimentacao_par_ids = Contabilidade::Conta.where('codigo = ?', conta_pcasp_da_movimentacao_par.codigo).pluck(:id) rescue nil
				else
					if self.liquidacao.empenho.operacao_de_credito_id.present?
						conta_pcasp_da_movimentacao = self.liquidacao.empenho.operacao_de_credito.conta
						contas_pcasps_da_movimentacao_ids = Contabilidade::Conta.where('codigo = ?', conta_pcasp_da_movimentacao.codigo).pluck(:id) rescue nil
					end
				end

				eventos_ativados_por_subconta_parcial = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:pagamento],
						orcamento_id: orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						ativar_pela_subconta: true,
						conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten
					}
				).where(
					contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
						sub_elemento_de_despesa_id: sub_elemento_de_despesa_do_evento.try(:id)
					}
				).uniq

				eventos_ativados_por_subconta_debito = Contabilidade::EventoContabil.joins(:contas_por_eventos_contabeis).where(
					contabilidade_eventos_contabeis: {
						id: eventos_ativados_por_subconta_parcial.pluck(:id)
					},
					contabilidade_contas_por_eventos_contabeis: {
						tipo_de_lancamento: 0,
						conta_id: contas_pcasps_da_movimentacao_ids
					}
				).uniq

				eventos_ativados_por_subconta_credito = Contabilidade::EventoContabil.joins(:contas_por_eventos_contabeis).where(
					contabilidade_eventos_contabeis: {
						id: eventos_ativados_por_subconta_parcial.pluck(:id)
					},
					contabilidade_contas_por_eventos_contabeis: {
						tipo_de_lancamento: 0,
						conta_id: contas_pcasps_da_movimentacao_par_ids
					}
				).uniq
			end

			eventos_ativados_por_subconta = (eventos_ativados_por_subconta_debito + eventos_ativados_por_subconta_credito).uniq

			eventos_ddr = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:pagamento],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					status: Contabilidade::ConfiguracaoDoEventoContabil.status['confirmado'.to_sym],
					aciona_sem_valor_de_retencoes: true
				}
			)

			return (eventos_inclusivos_de_dotacao_e_sem_dotacao + eventos_exclusivos_de_dotacao + eventos_sem_tipo + eventos_ativados_por_subconta + eventos_ddr).uniq
		end

		def busca_eventos_do_estorno_de_pagamento
			contas_bancarias_ids = self.pagamento.contas_bancarias_por_pagamento.map{|t| t.conta_bancaria_id }
			#ids_contas_pcasp_das_contas_bancaria = Contabilidade::ContaPcaspDaContaBancariaPorOrcamento.where(conta_bancaria_id: contas_bancarias_ids).pluck(:conta_id)
			#conta_pcasp_da_conta_bancaria_id = conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.find_by(orcamento_id: orcamento_id).try(:conta_id) rescue nil
			tipo_de_resto_a_pagar = nil

			conta_pcasp_da_conta_bancaria_ids = []
			self.pagamento.contas_bancarias_por_pagamento.each do |conta_bancaria|
				conta_pcasp_da_conta_bancaria_ids << self.pagamento.contas_bancarias_por_pagamento.last.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.pluck(:conta_id)
			end

			if pagamento.empenho.ordinario?
				modalidade_do_empenho = 'ordinario'
			else
				modalidade_do_empenho = 'global_ou_estimativo'
			end
			modalidade_do_empenho = Contabilidade::ConfiguracaoDoEventoContabil.modalidades_do_empenho[modalidade_do_empenho]

			if pagamento.empenho.movimentacao_do_plano_de_contas.present?
				originado_de_um_evento_manual = true
				conta_pcasp_do_lancamento_manual_id = pagamento.empenho.movimentacao_do_plano_de_contas.conta_por_evento_contabil.conta_id
			else
				originado_de_um_evento_manual = false
				conta_pcasp_do_lancamento_manual_id = nil
			end

			sub_elemento_de_despesa_do_evento = self.pagamento.sub_elemento_de_despesa

			if self.pagamento.try(:liquidacao).try(:restos_a_pagar?) || (self.pagamento&.liquidacao&.orcamento&.exercicio&.to_i > 0 && self.pagamento&.liquidacao.orcamento&.exercicio&.to_i < self.pagamento.orcamento.exercicio.to_i)
				pagamento_de_restos_a_pagar = true
				if self.pagamento.orcamento_id.present?
					orcamento_atual = self.pagamento.orcamento
				else
					orcamento_atual = @orcamento_atual
				end

				if pagamento.liquidacao.data_da_liquidacao.present? && pagamento.liquidacao.data_da_liquidacao.year < orcamento_atual.exercicio
					tipo_de_resto_a_pagar = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_resto_a_pagar['rp_processado']
				else
					tipo_de_resto_a_pagar = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_resto_a_pagar['rp_nao_processado']
				end

				sub_elemento_de_despesa_do_exercicio_anterior = Contabilidade::SubElementoDeDespesa.joins(elemento_de_despesa: [ modalidade_de_aplicacao: [ grupo_de_natureza_da_despesa: :categoria_economica ] ]).where("contabilidade_sub_elementos_de_despesa.codigo = ? and base_elementos_de_despesa.codigo = ? and base_categorias_economicas.modulo_id = ? and base_categorias_economicas.modulo_type = 'Orcamento'", sub_elemento_de_despesa.try(:codigo), sub_elemento_de_despesa.try(:elemento_de_despesa).try(:codigo), orcamento_atual.id).first
				sub_elemento_de_despesa_do_evento = sub_elemento_de_despesa_do_exercicio_anterior if sub_elemento_de_despesa_do_exercicio_anterior.present?
			else
				pagamento_de_restos_a_pagar = [false, nil]
			end

			if pagamento.empenho.tipo_de_entidade.nil?
				tipo_de_entidade = nil
			else
				tipo_de_entidade = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_entidade[self.pagamento.empenho.tipo_de_entidade]
			end

			if self.pagamento.empenho.classificacao_vpd.nil?
				classificacao_vpd = nil
			else
				classificacao_vpd = Contabilidade::ConfiguracaoDoEventoContabil.classificacoes_vpd[self.pagamento.empenho.classificacao_vpd]
			end

			if self.pagamento.empenho.regime.nil?
				regime = nil
			else
				regime = Contabilidade::ConfiguracaoDoEventoContabil.regimes[self.pagamento.empenho.regime]
			end

			eventos_inclusivos_de_dotacao_e_sem_dotacao = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:estorno_de_pagamento],
					orcamento_id: pagamento.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					resto_a_pagar: [pagamento_de_restos_a_pagar],
					processado: [self.pagamento.processado?, nil],
					conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
					modalidade_do_empenho: [nil, modalidade_do_empenho],
					tipo_de_pessoa: [tipos_de_pessoa_por_model, nil],
					originado_de_um_evento_manual: [originado_de_um_evento_manual, nil],
					conta_pcasp_do_lancamento_manual_id: [conta_pcasp_do_lancamento_manual_id, nil],
					tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
					classificacao_vpd: [classificacao_vpd, nil],
					regime: [regime, nil],
					ativar_pela_subconta: [false, nil]
				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [sub_elemento_de_despesa_do_evento.try(:id), nil]
				}
			)

			eventos_exclusivos_de_dotacao =  Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:estorno_de_pagamento],
					orcamento_id: pagamento.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:exclusivo_de_dotacoes] ,
					resto_a_pagar: [pagamento_de_restos_a_pagar],
					processado: [self.pagamento.processado?, nil],
					conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
					modalidade_do_empenho: [nil, modalidade_do_empenho],
					tipo_de_pessoa: [tipos_de_pessoa_por_model, nil],
					originado_de_um_evento_manual: [originado_de_um_evento_manual, nil],
					conta_pcasp_do_lancamento_manual_id: [conta_pcasp_do_lancamento_manual_id, nil],
					tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
					classificacao_vpd: [classificacao_vpd, nil],
					regime: [regime, nil],
					ativar_pela_subconta: [false, nil]
				}
			).where.not(
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: sub_elemento_de_despesa_do_evento.try(:id)
				}
			).uniq

			eventos_sem_tipo =  Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:estorno_de_pagamento],
					orcamento_id: pagamento.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: nil,
					resto_a_pagar: [pagamento_de_restos_a_pagar],
					processado: [self.pagamento.processado?, nil],
					conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
					modalidade_do_empenho: [nil, modalidade_do_empenho],
					tipo_de_pessoa: [tipos_de_pessoa_por_model, nil],
					originado_de_um_evento_manual: [originado_de_um_evento_manual, nil],
					conta_pcasp_do_lancamento_manual_id: [conta_pcasp_do_lancamento_manual_id, nil],
					tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
					tipo_de_entidade: [tipo_de_entidade, nil],
					classificacao_vpd: [classificacao_vpd, nil],
					regime: [regime, nil],
					ativar_pela_subconta: [false, nil]
				}
			).uniq

			eventos_ativados_por_subconta = []
			eventos_ativados_por_subconta_parcial = []
			eventos_ativados_por_subconta_debito = []
			eventos_ativados_por_subconta_credito =  []

			if self.pagamento.liquidacao.empenho.sub_conta_pcasp_id.present?
				if self.pagamento.liquidacao.empenho.movimentacao_do_plano_de_contas_id.present?
					movimentacao_associada_ao_empenho = Contabilidade::MovimentacaoDoPlanoDeContas.find(self.pagamento.liquidacao.empenho.movimentacao_do_plano_de_contas_id)
					conta_pcasp_da_movimentacao = movimentacao_associada_ao_empenho.conta_por_evento_contabil.conta
					contas_pcasps_da_movimentacao_ids = Contabilidade::Conta.where('codigo = ?', conta_pcasp_da_movimentacao.codigo).pluck(:id) rescue nil
					conta_pcasp_da_movimentacao_par = movimentacao_associada_ao_empenho.conta_por_evento_contabil&.conta_par
					contas_pcasps_da_movimentacao_par_ids = Contabilidade::Conta.where('codigo = ?', conta_pcasp_da_movimentacao_par.codigo).pluck(:id) rescue nil
				else
					if self.pagamento.liquidacao.empenho.operacao_de_credito_id.present?
						conta_pcasp_da_movimentacao = self.pagamento.liquidacao.empenho.operacao_de_credito.conta
						contas_pcasps_da_movimentacao_ids = Contabilidade::Conta.where('codigo = ?', conta_pcasp_da_movimentacao.codigo).pluck(:id) rescue nil
					end
				end

				eventos_ativados_por_subconta_parcial = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:estorno_de_pagamento],
						orcamento_id: pagamento.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						ativar_pela_subconta: true,
						conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten
					}
				).where(
					contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
						sub_elemento_de_despesa_id: sub_elemento_de_despesa_do_evento.try(:id)
					}
				).uniq

				eventos_ativados_por_subconta_debito = Contabilidade::EventoContabil.joins(:contas_por_eventos_contabeis).where(
					contabilidade_eventos_contabeis: {
						id: eventos_ativados_por_subconta_parcial.pluck(:id)
					},
					contabilidade_contas_por_eventos_contabeis: {
						tipo_de_lancamento: 1,
						conta_id: contas_pcasps_da_movimentacao_ids
					}
				).uniq

				eventos_ativados_por_subconta_credito = Contabilidade::EventoContabil.joins(:contas_por_eventos_contabeis).where(
					contabilidade_eventos_contabeis: {
						id: eventos_ativados_por_subconta_parcial.pluck(:id)
					},
					contabilidade_contas_por_eventos_contabeis: {
						tipo_de_lancamento: 1,
						conta_id: contas_pcasps_da_movimentacao_par_ids
					}
				).uniq
			end

			eventos_ativados_por_subconta = (eventos_ativados_por_subconta_debito + eventos_ativados_por_subconta_credito).uniq

			eventos_ddr = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:estorno_de_pagamento],
					orcamento_id: pagamento.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					status: Contabilidade::ConfiguracaoDoEventoContabil.status['confirmado'.to_sym],
					aciona_sem_valor_de_retencoes: true
				}
			)

			return (eventos_inclusivos_de_dotacao_e_sem_dotacao + eventos_exclusivos_de_dotacao + eventos_sem_tipo + eventos_ativados_por_subconta + eventos_ddr).uniq
		end

		def busca_eventos_do_pagamento_da_retencao
			eventos_inclusivos_de_dotacao_e_sem_dotacao = []
			eventos_exclusivos_de_dotacao = []

			if self.pagamento.present? && self.conta_bancaria_por_unidade_orcamentaria.nil?
				if self.pagamento.empenho.regime.nil?
					regime = nil
				else
					regime = Contabilidade::ConfiguracaoDoEventoContabil.regimes[self.pagamento.empenho.regime]
				end

				conta_pcasp_origem = self.conta_extra_orcamentaria.try(:conta_id) rescue nil

				sub_elemento_de_despesa_do_evento = pagamento.sub_elemento_de_despesa

				if self.try(:pagamento).try(:liquidacao).try(:restos_a_pagar?) || (self.pagamento&.liquidacao&.orcamento&.exercicio&.to_i > 0 && self.pagamento&.liquidacao&.orcamento&.exercicio&.to_i < orcamento.exercicio.to_i)
					if contexto_atual.present?
						orcamento_atual = contexto_atual
					else
						orcamento_atual = @orcamento_atual
					end
					
					sub_elemento_de_despesa_do_exercicio_anterior = Contabilidade::SubElementoDeDespesa.joins(elemento_de_despesa: [ modalidade_de_aplicacao: [ grupo_de_natureza_da_despesa: :categoria_economica ] ]).where("contabilidade_sub_elementos_de_despesa.codigo = ? and base_elementos_de_despesa.codigo = ? and base_categorias_economicas.modulo_id = ? and base_categorias_economicas.modulo_type = 'Orcamento'", pagamento.sub_elemento_de_despesa.try(:codigo), pagamento.sub_elemento_de_despesa.try(:elemento_de_despesa).try(:codigo), orcamento_atual.id).first
					sub_elemento_de_despesa_do_evento = sub_elemento_de_despesa_do_exercicio_anterior if sub_elemento_de_despesa_do_exercicio_anterior.present?
				end

				eventos_inclusivos_de_dotacao_e_sem_dotacao = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:talao_de_receita],
						orcamento_id: pagamento.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
						tipo_de_pessoa: [tipos_de_pessoa_por_model, nil],
						regime: [regime, nil]
					},
					contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
						sub_elemento_de_despesa_id: [sub_elemento_de_despesa_do_evento.try(:id), nil]
					}
				)

				eventos_inclusivos_de_dotacao_e_sem_dotacao = eventos_inclusivos_de_dotacao_e_sem_dotacao.joins(:contas_por_eventos_contabeis).where({
					contabilidade_contas_por_eventos_contabeis: {
						conta_id: conta_pcasp_origem
					}
				})

				eventos_exclusivos_de_dotacao =  Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:talao_de_receita],
						orcamento_id: pagamento.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_de_evento: Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:exclusivo_de_dotacoes] ,
						regime: [regime, nil]
					}
				).where.not(
					contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
						sub_elemento_de_despesa_id: sub_elemento_de_despesa_do_evento.try(:id)
					}
				)

				eventos_exclusivos_de_dotacao = eventos_exclusivos_de_dotacao.joins(:contas_por_eventos_contabeis).where({
					contabilidade_contas_por_eventos_contabeis: {
						conta_id: conta_pcasp_origem
					}
				})
			end
			
			return (eventos_inclusivos_de_dotacao_e_sem_dotacao + eventos_exclusivos_de_dotacao).uniq
		end

		def busca_eventos_do_recebimento
			if self.recebido? || self.recebido_parcialmente?
				status = :recebido
			else
				status = self.status.to_sym
			end

			if self.ordem_de_compra.present?
				modalidade_do_empenho = [self.ordem_de_compra.empenho.modalidade]
				if (modalidade_do_empenho & ["global", "estimativo"] ).any?
					modalidade_do_empenho.push("global_ou_estimativo")
				end
				modalidade_do_empenho = modalidade_do_empenho.compact.map { |modalidade| Contabilidade::ConfiguracaoDoEventoContabil.modalidades_do_empenho[modalidade] }
				resto_a_pagar = ordem_de_compra.empenho.restos_a_pagar
			else
				modalidade_do_empenho = nil
				resto_a_pagar = nil
			end

			status = Contabilidade::ConfiguracaoDoEventoContabil.status[status] rescue nil

			eventos_inclusivos_de_dotacao_e_sem_dotacao = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:recebimento_de_material],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					status: status,
					tipo_de_material: read_attribute_before_type_cast(:tipo_de_material),
					ativar_pela_subconta: [true, nil],
					status_de_reconhecimento: Contabilidade::ConfiguracaoDoEventoContabil.status_de_reconhecimentos[:reconhecido]
				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [sub_elemento_de_despesa.try(:id), nil]
				}
			)

			eventos_exclusivos_de_dotacao = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:recebimento_de_material],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					status: status,
					tipo_de_material: read_attribute_before_type_cast(:tipo_de_material),
					ativar_pela_subconta: [true, nil],
					status_de_reconhecimento: Contabilidade::ConfiguracaoDoEventoContabil.status_de_reconhecimentos[:reconhecido]
				},
			).where.not(
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: sub_elemento_de_despesa.try(:id)
				}
			).uniq

			return eventos_inclusivos_de_dotacao_e_sem_dotacao + eventos_exclusivos_de_dotacao
		end

		def busca_eventos_do_item_do_consumo
			eventos_inclusivos_de_dotacao_e_sem_dotacao = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:item_do_consumo],
					orcamento_id: consumo.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					status: Contabilidade::ConfiguracaoDoEventoContabil.status[:consumido],
					tipo_de_material: estoque.read_attribute_before_type_cast(:tipo_de_material),
					ativar_pela_subconta: [true, nil],
					status_de_reconhecimento: Contabilidade::ConfiguracaoDoEventoContabil.status_de_reconhecimentos[:reconhecido]

				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [estoque.sub_elemento_de_despesa.try(:id), nil]
				}
			)

			eventos_exclusivos_de_dotacao = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:item_do_consumo],
					orcamento_id: consumo.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					status: Contabilidade::ConfiguracaoDoEventoContabil.status[:consumido],
					tipo_de_material: estoque.read_attribute_before_type_cast(:tipo_de_material),
					ativar_pela_subconta: [true, nil],
					status_de_reconhecimento: Contabilidade::ConfiguracaoDoEventoContabil.status_de_reconhecimentos[:reconhecido]
				},
			).where.not(
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: estoque.sub_elemento_de_despesa.try(:id)
				}
			).uniq

				return eventos_inclusivos_de_dotacao_e_sem_dotacao + eventos_exclusivos_de_dotacao
		end

		def busca_eventos_do_ploa
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[self.status] rescue nil

			Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:naturezas_da_receita_da_configuracao_contabil] ).where(
				contabilidade_eventos_contabeis:{
					modelo: Contabilidade::EventoContabil.modelos[:loa],
					orcamento_id: self.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:exclusivo_de_receitas], Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_receitas], nil],
					status: [ status, nil ]
				},
				contabilidade_naturezas_da_receita_da_configuracao_contabil: {
					categoria_economica: self.orcamento.naturezas_da_receita.pluck(:categoria_economica).uniq + ["000", nil],
					origem: self.orcamento.naturezas_da_receita.pluck(:origem).uniq + ["0", nil],
					especie: self.orcamento.naturezas_da_receita.pluck(:especie).uniq + ['0', nil],
					rubrica: self.orcamento.naturezas_da_receita.pluck(:rubrica).uniq + ["0", nil],
					alinea: self.orcamento.naturezas_da_receita.pluck(:alinea).uniq + ["00", nil],
					subalinea: self.orcamento.naturezas_da_receita.pluck(:subalinea).uniq + ["0", nil],
					detalhamento_optativo: self.orcamento.naturezas_da_receita.pluck(:detalhamento_optativo).uniq + ["0", nil],
					nivel_opcional_1: self.orcamento.naturezas_da_receita.pluck(:nivel_opcional_1).uniq + ["00", nil],
					nivel_opcional_2: self.orcamento.naturezas_da_receita.pluck(:nivel_opcional_2).uniq + ["00", nil],
					nivel_opcional_3: self.orcamento.naturezas_da_receita.pluck(:nivel_opcional_3).uniq + ["00", nil]
				}
			)
		end

		def busca_eventos_do_ppa
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[self.status] rescue nil
			
			Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:ppa],
					orcamento_id: Orcamento.find_by(exercicio: Date.today.year).try(:id)
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					status: [ status, nil ]
				}
			)
		end

		def busca_eventos_da_projecao_de_despesa
			alteracao_no_saldo = define_tipo_de_alteracao_no_saldo(self.valor.to_d, self.valor_was.to_d)
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[self.orcador.ppa.status] rescue nil

			#modulo_de_ativacao: [ Contabilidade::ConfiguracaoDoEventoContabil.modulo_de_ativacoes[:planejamento], nil ],

			Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:projecao_de_despesa],
					orcamento_id: Orcamento.find_by(exercicio: Date.today.year).try(:id)
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					status: [ status, nil ],
					alteracao_no_saldo: [ Contabilidade::ConfiguracaoDoEventoContabil.alteracao_no_saldos[alteracao_no_saldo], nil]
				}
			)
		end

		def busca_eventos_de_calculo_por_exercicio
			alteracao_no_saldo = define_tipo_de_alteracao_no_saldo(self.total.to_d, self.total_was.to_d)
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[self.try(:retorna_ppa_do_calculo_por_exercicio).try(:status)] rescue nil

			#modulo_de_ativacao: [ Contabilidade::ConfiguracaoDoEventoContabil.modulo_de_ativacoes[:planejamento], nil ],

			Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:receita],
					orcamento_id: Orcamento.find_by(exercicio: Date.today.year).try(:id)
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					status: [ status, nil ],
					alteracao_no_saldo: [ Contabilidade::ConfiguracaoDoEventoContabil.alteracao_no_saldos[alteracao_no_saldo], nil]
				}
			)
		end

		def busca_eventos_de_orcamento_da_despesa
			alteracao_no_saldo = define_tipo_de_alteracao_no_saldo(self.valor.to_d, self.valor_was.to_d)
			status =  Contabilidade::ConfiguracaoDoEventoContabil.status[self.try(:elemento_de_despesa_por_subacao).try(:subacao).try(:orcamento).try(:status)] rescue nil
			#status: [status, nil ],
			#modulo_de_ativacao: [ Contabilidade::ConfiguracaoDoEventoContabil.modulo_de_ativacoes[:planejamento], nil ],

			eventos = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:orcamento_da_despesa],
					orcamento_id: self.try(:elemento_de_despesa_por_subacao).try(:subacao).try(:orcamento).try(:id)
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					alteracao_no_saldo: [ Contabilidade::ConfiguracaoDoEventoContabil.alteracao_no_saldos[alteracao_no_saldo], nil]
				}
			)

			return eventos
		end

		def busca_eventos_do_talao_de_receita
			eventos_inclusivos_de_receita = Array.new
			eventos_exclusivos_de_receita = Array.new
			eventos_inclusivos_de_fontes = Array.new
			eventos_conta_pcasp = Array.new
			evento_gerado_por_pagamento = Array.new
			evento_de_deposito = Array.new
			eventos_extra_vinda_de_pagamento = Array.new

			veio_de_um_pagamento_com_retencao = self.pagamento_id.present? ? true : false

			if conta_bancaria.present? && conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.present?
				tipo_de_conta_pcasp_do_talao = conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.last.conta.codigo[0] == "1" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo]
			else
				if veio_de_um_pagamento_com_retencao
					tipo_de_conta_pcasp_do_talao = pagamento.contas_bancarias.last.contas_pcasp_da_conta_bancaria_por_orcamento.last.conta.codigo[0] == "1" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo]
				else
					tipo_de_conta_pcasp_do_talao = nil
				end
			end

			if self.pessoa.present? && (self.pessoa.entidade_publica? || self.pessoa.tipo_de_entidade == "nenhuma")
				tipo_de_entidade = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_entidade[self.pessoa.tipo_de_entidade] rescue nil
			else
				tipo_de_entidade = nil
			end

			if self.operacao_de_credito.present?
				modalidade_operacao_de_credito = Contabilidade::ConfiguracaoDoEventoContabil.modalidade_operacoes_de_credito[self.modalidade_para_ativacao_de_evento_contabeis] rescue nil
			else
				modalidade_operacao_de_credito = nil
			end

			contapcasp_retencoes_e_consignacoes = conta_pcasp_de_retencoes_e_consignacoes(self.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.last.conta) rescue false

			if veio_de_um_pagamento_com_retencao && self.extra_orcamentario?
				contapcasp_retencoes_e_consignacoes = true
			end

			if self.natureza_da_receita.present?
				talao_eh_reducao = self.natureza_da_receita.categoria_economica == "009"
				
				if veio_de_um_pagamento_com_retencao && self.conta_bancaria.nil?
					conta_pcasp_da_conta_bancaria_ids = pagamento.contas_bancarias.last.contas_pcasp_da_conta_bancaria_por_orcamento.pluck(:conta_id) rescue nil
				else
					conta_pcasp_da_conta_bancaria_ids = conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.pluck(:conta_id) rescue nil
				end
				classificacao_da_receita = nil

				alinea = talao_eh_reducao && self.natureza_da_receita.alinea[0].to_i > 0 ? "#{self.natureza_da_receita.alinea[0]}0" : nil
				nivel_opcional_1 = talao_eh_reducao && self.natureza_da_receita.nivel_opcional_1[1].to_i == 1 ? "01" : nil # retirar após correção das receitas de dedução

				if natureza_da_receita.categoria_economica == '001' && natureza_da_receita.detalhamento_optativo == '3'
					divida = natureza_da_receita.origem == '1' ? :divida_ativa : :divida_ativa_nao_tributaria
					classificacao_da_receita = Contabilidade::ConfiguracaoDoEventoContabil.classificacoes_da_receita[divida]
				end

				# configuração possui_conta_bancaria só conta para talões extra
				if self.extra_orcamentario?
					possui_conta_bancaria = self.conta_bancaria_por_unidade_orcamentaria.present?
					codigo_sim = self.conta_extra_orcamentaria.outros? ? Contabilidade::ConfiguracaoDoEventoContabil.codigos_sim[:outros_codigo] : Contabilidade::ConfiguracaoDoEventoContabil.codigos_sim[self.conta_extra_orcamentaria.codigo_sim]
				else
					possui_conta_bancaria = [true, false]
				end

				eventos_inclusivos_de_receita = Contabilidade::EventoContabil.left_outer_joins(configuracao_do_evento_contabil: [:naturezas_da_receita_da_configuracao_contabil]).where(
					contabilidade_eventos_contabeis:{
						modelo: Contabilidade::EventoContabil.modelos[:talao_de_receita],
						orcamento_id: orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_receitas], nil],
						receita_de_deducao: [talao_eh_reducao, nil],
						conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
						tipo_de_pessoa: [tipos_de_pessoa_por_model, nil],
						conta_pcasp_id: [conta_bancaria.try(:id), nil],
						extraorcamentario: [self.extra_orcamentario?, nil],
						com_fonte_de_recursos: [lancamentos_do_orcamento_da_receita.any?, nil],
						classificacao_da_receita: [classificacao_da_receita, nil],
						tipo_de_conta_pcasp: [tipo_de_conta_pcasp_do_talao, nil],
						vem_de_pagamento_com_retencao: [veio_de_um_pagamento_com_retencao, nil],
						deposito: [false, nil],
						tipo_de_entidade: [tipo_de_entidade, nil],
						modalidade_operacao_de_credito: [modalidade_operacao_de_credito, nil],
						retencao: [contapcasp_retencoes_e_consignacoes, nil],
						consignacao: [contapcasp_retencoes_e_consignacoes, nil],
						possui_conta_bancaria: [possui_conta_bancaria, nil],
						codigo_sim: [codigo_sim, nil]
					},
					contabilidade_naturezas_da_receita_da_configuracao_contabil: {
						categoria_economica: [natureza_da_receita.categoria_economica, '000', nil ],
						origem: [natureza_da_receita.origem, '0',nil],
						especie: [natureza_da_receita.especie, '0', nil],
						rubrica: [natureza_da_receita.rubrica, '0', nil],
						alinea: [natureza_da_receita.alinea, '00', alinea, nil],
						subalinea: [natureza_da_receita.subalinea, '0', nil],
						detalhamento_optativo: [natureza_da_receita.detalhamento_optativo, '0', nil],
						nivel_opcional_1: [natureza_da_receita.nivel_opcional_1, '00', nivel_opcional_1, nil],
						nivel_opcional_2: [natureza_da_receita.nivel_opcional_2, '00', nil],
						nivel_opcional_3: [natureza_da_receita.nivel_opcional_3, '00', nil],
						conta_pcasp_id: nil,
						conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten
					}
				).where(
					"
					(contabilidade_naturezas_da_receita_da_configuracao_contabil.categoria_economica_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.categoria_economica_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.origem_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.origem_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.especie_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.especie_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.rubrica_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.rubrica_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.alinea_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.alinea_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.subalinea_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.subalinea_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.detalhamento_optativo_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.detalhamento_optativo_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_1_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_1_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_2_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_2_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_3_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_3_exclusora IS NULL)",
					natureza_da_receita.categoria_economica, natureza_da_receita.origem, natureza_da_receita.especie, natureza_da_receita.rubrica,
					natureza_da_receita.alinea, natureza_da_receita.subalinea, natureza_da_receita.detalhamento_optativo, natureza_da_receita.nivel_opcional_1, 
					natureza_da_receita.nivel_opcional_2, natureza_da_receita.nivel_opcional_3
				)

				eventos_de_ultima_opcao_de_lancamento = eventos_inclusivos_de_receita.joins(:configuracao_do_evento_contabil).where(
					contabilidade_configuracoes_do_evento_contabil: {
						ultima_opcao_de_lancamento_da_receita: true,
						classificacao_da_receita: classificacao_da_receita
					}
				)

				if eventos_de_ultima_opcao_de_lancamento.any?
					total_de_eventos_mesma_classificacao = eventos_inclusivos_de_receita.joins(:configuracao_do_evento_contabil).where(
						contabilidade_configuracoes_do_evento_contabil: {
							classificacao_da_receita: classificacao_da_receita
						}
					)

					if total_de_eventos_mesma_classificacao.size > 1
						eventos_inclusivos_de_receita = eventos_inclusivos_de_receita.where.not(
							contabilidade_eventos_contabeis: {
								id: eventos_de_ultima_opcao_de_lancamento.ids
							}
						)
					end
				end

				eventos_exclusivos_de_receita = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
					contabilidade_eventos_contabeis:{
						modelo: Contabilidade::EventoContabil.modelos[:talao_de_receita],
						orcamento_id: self.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:exclusivo_de_receitas], nil],
						receita_de_deducao: [talao_eh_reducao, nil],
						conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
						tipo_de_pessoa: [tipos_de_pessoa_por_model, nil],
						conta_pcasp_id: [conta_bancaria.try(:id), nil],
						extraorcamentario: [self.extra_orcamentario?, nil],
						com_fonte_de_recursos: [lancamentos_do_orcamento_da_receita.any?, nil],
						classificacao_da_receita: [classificacao_da_receita, nil],
						tipo_de_conta_pcasp: [tipo_de_conta_pcasp_do_talao, nil],
						vem_de_pagamento_com_retencao: [veio_de_um_pagamento_com_retencao, nil],
						deposito: [false, nil],
						tipo_de_entidade: [tipo_de_entidade, nil],
						modalidade_operacao_de_credito: [modalidade_operacao_de_credito, nil],
						retencao: [contapcasp_retencoes_e_consignacoes, nil],
						consignacao: [contapcasp_retencoes_e_consignacoes, nil]
					}
				)
			end

			# outrora foi proposto fazer eventos atrelados a fontes especificas, porém depois houve outra sugestão que é o fonte vinculada sim ou não
			# fontes_de_recurso = complementos_por_fonte_do_talao_de_receita.map{ |a| a.orcamento_da_receita.fonte_de_recursos_id } rescue nil

			# eventos_inclusivos_de_fontes = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:fontes_da_configuracao_contabil] ).where(
			# 	contabilidade_eventos_contabeis:{
			# 		modelo: Contabilidade::EventoContabil.modelos[:talao_de_receita],
			# 		orcamento_id: orcamento_id
			# 	},
			# 	contabilidade_configuracoes_do_evento_contabil: {
			# 		tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_fontes]],
			# 		tipo_de_conta_pcasp: [tipo_de_conta_pcasp_do_talao, nil],
			# 		vem_de_pagamento_com_retencao: [veio_de_um_pagamento_com_retencao, nil],
			# 		deposito: [false, nil],
			# 		tipo_de_entidade: [tipo_de_entidade, nil],
			# 		modalidade_operacao_de_credito: [modalidade_operacao_de_credito, nil],
			# 		retencao: [contapcasp_retencoes_e_consignacoes, nil],
			# 		consignacao: [contapcasp_retencoes_e_consignacoes, nil]
			# 	},
			# 	contabilidade_fontes_da_configuracao_contabil: {
			# 		fonte_de_recursos_id: [fontes_de_recurso]
			# 	}
			# )

			if conta_extra_orcamentaria.present? && (conta_bancaria.present? || veio_de_um_pagamento_com_retencao)
				conta_pcasp_da_conta_bancaria_ids = []
				conta_pcasp_da_conta_bancaria_ids = self.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.pluck(:conta_id) rescue nil
				tipo_de_conta_pcasp_do_talao_extra = self.conta_extra_orcamentaria.classe_pcasp == "passivo" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo]
				conta_pcasp_origem = self.conta_extra_orcamentaria.try(:conta_id) rescue nil
				contapcasp_deposito = conta_pcasp_de_deposito( self.conta_extra_orcamentaria.conta) rescue nil
				investimento_rpps = self.conta_extra_orcamentaria.investimento_rpps? ? true : [false, nil]
				codigo_sim = self.conta_extra_orcamentaria.outros? ? Contabilidade::ConfiguracaoDoEventoContabil.codigos_sim[:outros_codigo] : Contabilidade::ConfiguracaoDoEventoContabil.codigos_sim[self.conta_extra_orcamentaria.codigo_sim]

				eventos_conta_extra = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where({
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:talao_de_receita],
						orcamento_id: orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						conta_pcasp_id: [conta_extra_orcamentaria.conta_id, nil],
						conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
						extraorcamentario: self.extra_orcamentario?,
						tipo_de_conta_pcasp: [tipo_de_conta_pcasp_do_talao_extra, nil],
						vem_de_pagamento_com_retencao: [veio_de_um_pagamento_com_retencao, nil],
						deposito: [contapcasp_deposito, nil],
						tipo_de_entidade: [tipo_de_entidade, nil],
						modalidade_operacao_de_credito: [modalidade_operacao_de_credito, nil],
						retencao: [contapcasp_retencoes_e_consignacoes, nil],
						consignacao: [contapcasp_retencoes_e_consignacoes, nil],
						investimento_rpps: investimento_rpps
					}
				})

				if codigo_sim.present? && codigo_sim == "99999999"
					conta = self.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.where(orcamento_id: orcamento_id).first&.conta_id rescue nil

					eventos_conta_pcasp = eventos_conta_extra.joins(:contas_por_eventos_contabeis)
						.where(contabilidade_contas_por_eventos_contabeis: { tipo_de_lancamento: 0 })
						.where(
							contabilidade_configuracoes_do_evento_contabil: { codigo_sim: codigo_sim }
						)
						.where(
							'conta_id = ? OR conta_par_id = ?', conta, conta
						).distinct

				else
					eventos_conta_pcasp = eventos_conta_extra.joins(:contas_por_eventos_contabeis).where({
						contabilidade_contas_por_eventos_contabeis: {
							tipo_de_lancamento: 1,
							conta_id: conta_pcasp_origem
						}
					}) 
				end

				eventos_extra_vinda_de_pagamento = eventos_conta_extra.where({
					contabilidade_configuracoes_do_evento_contabil: {
						ativar_para_todas_as_contas: true
					}
				})
			end

			if veio_de_um_pagamento_com_retencao
				#evento gerado por pagamento
				evento_gerado_por_pagamento = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where({
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:talao_de_receita]
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_de_conta_pcasp: [tipo_de_conta_pcasp_do_talao],
						vem_de_pagamento_com_retencao: [veio_de_um_pagamento_com_retencao],
						deposito: [false, nil],
						tipo_de_entidade: [tipo_de_entidade, nil],
						modalidade_operacao_de_credito: [modalidade_operacao_de_credito, nil]
					}
				})
			else #evento de deposito
				if conta_extra_orcamentaria.present? 
					conta_para_lancamento = conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.last.conta rescue nil
					tipo_de_conta_pcasp_do_deposito = self.conta_extra_orcamentaria.classe_pcasp == "passivo" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo]
					codigo_sim = self.conta_extra_orcamentaria.outros? ? Contabilidade::ConfiguracaoDoEventoContabil.codigos_sim[:outros_codigo] : Contabilidade::ConfiguracaoDoEventoContabil.codigos_sim[self.conta_extra_orcamentaria.codigo_sim]
				else
					conta_para_lancamento = self.conta_extra_orcamentaria.conta rescue nil
					tipo_de_conta_pcasp_do_deposito = tipo_de_conta_pcasp_do_talao
				end

				if conta_para_lancamento.present? && conta_pcasp_de_deposito(conta_para_lancamento)				
					evento_de_deposito = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where({
						contabilidade_eventos_contabeis: {
							modelo: Contabilidade::EventoContabil.modelos[:talao_de_receita]
						},
						contabilidade_configuracoes_do_evento_contabil: {
							tipo_de_conta_pcasp: [tipo_de_conta_pcasp_do_deposito],
							vem_de_pagamento_com_retencao: [false, nil],
							deposito: true,
							extraorcamentario: self.extra_orcamentario?,
							tipo_de_entidade: [tipo_de_entidade, nil],
							modalidade_operacao_de_credito: [modalidade_operacao_de_credito, nil],
							codigo_sim: [codigo_sim, nil]
						}
					})
				end
			end
			
			return ( eventos_inclusivos_de_receita + eventos_exclusivos_de_receita + eventos_conta_pcasp + eventos_inclusivos_de_fontes + evento_gerado_por_pagamento + evento_de_deposito + eventos_extra_vinda_de_pagamento).uniq
		end

		def busca_eventos_da_anulacao_do_talao_de_receita
			eventos_inclusivos_de_receita = Array.new
			eventos_exclusivos_de_receita = Array.new
			eventos_inclusivos_de_fontes = Array.new
			eventos_conta_pcasp = Array.new
			evento_gerado_por_pagamento = Array.new
			evento_de_deposito = Array.new
			eventos_extra_vinda_de_pagamento = Array.new
			eventos_conta_extra = Array.new

			veio_de_um_pagamento_com_retencao = self.talao_de_receita.pagamento_id.present? ? true : false

			if self.talao_de_receita.conta_bancaria.present? && self.talao_de_receita.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.present?
				tipo_de_conta_pcasp_do_talao = self.talao_de_receita.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.last.conta.codigo[0] == "1" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo]
			else
				if veio_de_um_pagamento_com_retencao
					tipo_de_conta_pcasp_do_talao = self.talao_de_receita.pagamento.contas_bancarias.last.contas_pcasp_da_conta_bancaria_por_orcamento.last.conta.codigo[0] == "1" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo]
				else
					tipo_de_conta_pcasp_do_talao = nil
				end
			end

			if self.talao_de_receita.pessoa.entidade_publica? || self.talao_de_receita.pessoa.tipo_de_entidade == "nenhuma"
				tipo_de_entidade = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_entidade[self.talao_de_receita.pessoa.tipo_de_entidade] rescue nil
			else
				tipo_de_entidade = nil
			end

			if self.talao_de_receita.operacao_de_credito.present?
				modalidade_operacao_de_credito = Contabilidade::ConfiguracaoDoEventoContabil.modalidade_operacoes_de_credito[self.talao_de_receita.modalidade_para_ativacao_de_evento_contabeis] rescue nil
			else
				modalidade_operacao_de_credito = nil
			end

			contapcasp_retencoes_e_consignacoes = conta_pcasp_de_retencoes_e_consignacoes(self.talao_de_receita.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.last.conta) rescue false
			
			if veio_de_um_pagamento_com_retencao && self.talao_de_receita.extra_orcamentario?
				contapcasp_retencoes_e_consignacoes = true
			end

			if self.talao_de_receita.natureza_da_receita.present?
				talao_eh_reducao = self.talao_de_receita.natureza_da_receita.categoria_economica == "009"

				if veio_de_um_pagamento_com_retencao && self.talao_de_receita.conta_bancaria.nil?
					conta_pcasp_da_conta_bancaria_ids = self.talao_de_receita.pagamento.contas_bancarias.last.contas_pcasp_da_conta_bancaria_por_orcamento.pluck(:conta_id) rescue nil
				else
					conta_pcasp_da_conta_bancaria_ids = self.talao_de_receita.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.pluck(:conta_id) rescue nil
				end

				classificacao_da_receita = nil

				alinea = talao_eh_reducao && self.natureza_da_receita.alinea[0].to_i > 0 ? "#{self.natureza_da_receita.alinea[0]}0" : nil # retirar após correção das receitas de dedução
				nivel_opcional_1 = talao_eh_reducao && self.natureza_da_receita.nivel_opcional_1[1].to_i == 1 ? "01" : nil # retirar após correção das receitas de dedução

				if self.talao_de_receita.natureza_da_receita.categoria_economica == '001' && self.talao_de_receita.natureza_da_receita.detalhamento_optativo == '3'
					divida = self.talao_de_receita.natureza_da_receita.origem == '1' ? :divida_ativa : :divida_ativa_nao_tributaria
					classificacao_da_receita = Contabilidade::ConfiguracaoDoEventoContabil.classificacoes_da_receita[divida]
				end

				# configuração possui_conta_bancaria só conta para talões extra
				if self.talao_de_receita.extra_orcamentario?
					possui_conta_bancaria = self.talao_de_receita.conta_bancaria_por_unidade_orcamentaria.present?
				else
					possui_conta_bancaria = [true, false]
				end

				eventos_inclusivos_de_receita = Contabilidade::EventoContabil.left_outer_joins(configuracao_do_evento_contabil: [:naturezas_da_receita_da_configuracao_contabil]).where(
					contabilidade_eventos_contabeis:{
						modelo: Contabilidade::EventoContabil.modelos[:anulacao_do_talao_de_receita],
						orcamento_id: self.talao_de_receita.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_receitas], nil],
						receita_de_deducao: [talao_eh_reducao, nil],
						conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
						tipo_de_pessoa: [tipos_de_pessoa_por_model, nil],
						conta_pcasp_id: [self.talao_de_receita.conta_bancaria.try(:id), nil],
						extraorcamentario: [self.talao_de_receita.extra_orcamentario?, nil],
						com_fonte_de_recursos: [self.talao_de_receita.lancamentos_do_orcamento_da_receita.any?, nil],
						classificacao_da_receita: [classificacao_da_receita, nil],
						tipo_de_conta_pcasp: [tipo_de_conta_pcasp_do_talao, nil],
						vem_de_pagamento_com_retencao: [veio_de_um_pagamento_com_retencao, nil],
						deposito: [false, nil],
						tipo_de_entidade: [tipo_de_entidade, nil],
						modalidade_operacao_de_credito: [modalidade_operacao_de_credito, nil],
						retencao: [contapcasp_retencoes_e_consignacoes, nil],
						consignacao: [contapcasp_retencoes_e_consignacoes, nil],
						possui_conta_bancaria: [possui_conta_bancaria, nil]
					},
					contabilidade_naturezas_da_receita_da_configuracao_contabil: {
						categoria_economica: [self.talao_de_receita.natureza_da_receita.categoria_economica, '000', nil ],
						origem: [self.talao_de_receita.natureza_da_receita.origem, '0',nil],
						especie: [self.talao_de_receita.natureza_da_receita.especie, '0', nil],
						rubrica: [self.talao_de_receita.natureza_da_receita.rubrica, '0', nil],
						alinea: [self.talao_de_receita.natureza_da_receita.alinea, '00', alinea, nil],
						subalinea: [self.talao_de_receita.natureza_da_receita.subalinea, '0', nil],
						detalhamento_optativo: [self.talao_de_receita.natureza_da_receita.detalhamento_optativo, '0', nil],
						nivel_opcional_1: [self.talao_de_receita.natureza_da_receita.nivel_opcional_1, '00', nivel_opcional_1, nil],
						nivel_opcional_2: [self.talao_de_receita.natureza_da_receita.nivel_opcional_2, '00', nil],
						nivel_opcional_3: [self.talao_de_receita.natureza_da_receita.nivel_opcional_3, '00', nil],
						conta_pcasp_id: nil,
						conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten
					}
				).where(
						'
						(contabilidade_naturezas_da_receita_da_configuracao_contabil.categoria_economica_exclusora = ? 
						OR contabilidade_naturezas_da_receita_da_configuracao_contabil.categoria_economica_exclusora IS NULL)

						AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.origem_exclusora = ?
						OR contabilidade_naturezas_da_receita_da_configuracao_contabil.origem_exclusora IS NULL)

						AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.especie_exclusora = ?
						OR contabilidade_naturezas_da_receita_da_configuracao_contabil.especie_exclusora IS NULL)

						AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.rubrica_exclusora = ?
						OR contabilidade_naturezas_da_receita_da_configuracao_contabil.rubrica_exclusora IS NULL)

						AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.alinea_exclusora = ?
						OR contabilidade_naturezas_da_receita_da_configuracao_contabil.alinea_exclusora IS NULL)

						AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.subalinea_exclusora = ?
						OR contabilidade_naturezas_da_receita_da_configuracao_contabil.subalinea_exclusora IS NULL)

						AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.detalhamento_optativo_exclusora = ?
						OR contabilidade_naturezas_da_receita_da_configuracao_contabil.detalhamento_optativo_exclusora IS NULL)

						AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_1_exclusora = ?
						OR contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_1_exclusora IS NULL)

						AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_2_exclusora = ?
						OR contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_2_exclusora IS NULL)

						AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_3_exclusora = ?
						OR contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_3_exclusora IS NULL)',
						self.talao_de_receita.natureza_da_receita.categoria_economica, self.talao_de_receita.natureza_da_receita.origem, 
						self.talao_de_receita.natureza_da_receita.especie, self.talao_de_receita.natureza_da_receita.rubrica,
						self.talao_de_receita.natureza_da_receita.alinea, self.talao_de_receita.natureza_da_receita.subalinea, 
						self.talao_de_receita.natureza_da_receita.detalhamento_optativo, self.talao_de_receita.natureza_da_receita.nivel_opcional_1, 
						self.talao_de_receita.natureza_da_receita.nivel_opcional_2, self.talao_de_receita.natureza_da_receita.nivel_opcional_3
				)

				eventos_de_ultima_opcao_de_lancamento = eventos_inclusivos_de_receita.joins(:configuracao_do_evento_contabil).where(
					contabilidade_configuracoes_do_evento_contabil: {
						ultima_opcao_de_lancamento_da_receita: true,
						classificacao_da_receita: classificacao_da_receita
					}
				)

				if eventos_de_ultima_opcao_de_lancamento.any?
					total_de_eventos_mesma_classificacao = eventos_inclusivos_de_receita.joins(:configuracao_do_evento_contabil).where(
						contabilidade_configuracoes_do_evento_contabil: {
							classificacao_da_receita: classificacao_da_receita
						}
					)

					if total_de_eventos_mesma_classificacao.size > 1
						eventos_inclusivos_de_receita = eventos_inclusivos_de_receita.where.not(
							contabilidade_eventos_contabeis: {
								id: eventos_de_ultima_opcao_de_lancamento.ids
							}
						)
					end
				end

				eventos_exclusivos_de_receita = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
					contabilidade_eventos_contabeis:{
						modelo: Contabilidade::EventoContabil.modelos[:anulacao_do_talao_de_receita],
						orcamento_id: self.talao_de_receita.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:exclusivo_de_receitas], nil],
						receita_de_deducao: [talao_eh_reducao, nil],
						conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
						tipo_de_pessoa: [tipos_de_pessoa_por_model, nil],
						conta_pcasp_id: [self.talao_de_receita.conta_bancaria.try(:id), nil],
						extraorcamentario: [self.talao_de_receita.extra_orcamentario?, nil],
						com_fonte_de_recursos: [self.talao_de_receita.lancamentos_do_orcamento_da_receita.any?, nil],
						classificacao_da_receita: [classificacao_da_receita, nil],
						vem_de_pagamento_com_retencao: [veio_de_um_pagamento_com_retencao, nil],
						deposito: [false, nil],
						tipo_de_entidade: [tipo_de_entidade, nil],
						modalidade_operacao_de_credito: [modalidade_operacao_de_credito, nil],
						retencao: [contapcasp_retencoes_e_consignacoes, nil],
						consignacao: [contapcasp_retencoes_e_consignacoes, nil]
					}
				)
			end 

			fontes_de_recurso = self.talao_de_receita.complementos_por_fonte_do_talao_de_receita.map{ |a| a.orcamento_da_receita.fonte_de_recursos_id } rescue nil

			eventos_inclusivos_de_fontes = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:fontes_da_configuracao_contabil] ).where(
				contabilidade_eventos_contabeis:{
					modelo: Contabilidade::EventoContabil.modelos[:anulacao_do_talao_de_receita],
					orcamento_id: self.talao_de_receita.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_fontes]],
					tipo_de_conta_pcasp: [tipo_de_conta_pcasp_do_talao, nil],
					vem_de_pagamento_com_retencao: [veio_de_um_pagamento_com_retencao, nil],
					deposito: [false, nil],
					tipo_de_entidade: [tipo_de_entidade, nil],
					modalidade_operacao_de_credito: [modalidade_operacao_de_credito, nil],
					retencao: [contapcasp_retencoes_e_consignacoes, nil],
					consignacao: [contapcasp_retencoes_e_consignacoes, nil]
				},
				contabilidade_fontes_da_configuracao_contabil: {
					fonte_de_recursos_id: [fontes_de_recurso]
				}
			)
			

			if talao_de_receita.conta_extra_orcamentaria.present? && (talao_de_receita.conta_bancaria.present? || veio_de_um_pagamento_com_retencao)
				conta_pcasp_da_conta_bancaria_ids = []
				if veio_de_um_pagamento_com_retencao
					self.talao_de_receita.pagamento.contas_bancarias_por_pagamento.each do |conta_bancaria|
						conta_pcasp_da_conta_bancaria_ids << conta_bancaria.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.pluck(:conta_id)
					end
				else
					conta_pcasp_da_conta_bancaria_ids = self.talao_de_receita.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.pluck(:conta_id) rescue nil
				end
				tipo_de_conta_pcasp_do_talao_extra = self.talao_de_receita.conta_extra_orcamentaria.classe_pcasp == "passivo" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo]
				conta_pcasp_origem = self.talao_de_receita.conta_extra_orcamentaria.try(:conta_id) rescue nil
				contapcasp_deposito = self.talao_de_receita.conta_pcasp_de_deposito(self.talao_de_receita.conta_extra_orcamentaria.conta) rescue nil
				investimento_rpps = self.talao_de_receita.conta_extra_orcamentaria.investimento_rpps? ? true : [false, nil]
				codigo_sim = self.talao_de_receita.conta_extra_orcamentaria.outros? ? Contabilidade::ConfiguracaoDoEventoContabil.codigos_sim[:outros_codigo] : Contabilidade::ConfiguracaoDoEventoContabil.codigos_sim[self.conta_extra_orcamentaria.codigo_sim]

				eventos_conta_extra = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where({
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:anulacao_do_talao_de_receita],
						orcamento_id: talao_de_receita.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						conta_pcasp_id: [self.talao_de_receita.conta_extra_orcamentaria.conta_id, nil],
						conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
						extraorcamentario: self.talao_de_receita.extra_orcamentario?,
						tipo_de_conta_pcasp: [tipo_de_conta_pcasp_do_talao_extra, nil],
						vem_de_pagamento_com_retencao: [veio_de_um_pagamento_com_retencao, nil],
						deposito: [contapcasp_deposito, nil],
						tipo_de_entidade: [tipo_de_entidade, nil],
						modalidade_operacao_de_credito: [modalidade_operacao_de_credito, nil],
						retencao: [contapcasp_retencoes_e_consignacoes, nil],
						consignacao: [contapcasp_retencoes_e_consignacoes, nil],
						investimento_rpps: investimento_rpps,
						codigo_sim: [codigo_sim, nil]
					}
				})

				if codigo_sim.present? && codigo_sim == "99999999"
					conta = self.talao_de_receita.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.where(orcamento_id: orcamento_id).first&.conta_id rescue nil

					eventos_conta_pcasp = eventos_conta_extra.joins(:contas_por_eventos_contabeis)
						.where(contabilidade_contas_por_eventos_contabeis: { tipo_de_lancamento: 0 })
						.where(
							contabilidade_configuracoes_do_evento_contabil: { codigo_sim: codigo_sim }
						)
						.where(
							'conta_id = ? OR conta_par_id = ?', conta, conta
						).distinct
				else
					eventos_conta_pcasp = eventos_conta_extra.joins(:contas_por_eventos_contabeis).where({
						contabilidade_contas_por_eventos_contabeis: {
							tipo_de_lancamento: 0,
							conta_id: conta_pcasp_origem
						}
					})
				end

				eventos_extra_vinda_de_pagamento = eventos_conta_extra.where({
					contabilidade_configuracoes_do_evento_contabil: {
						ativar_para_todas_as_contas: true
					}
				})
			end

			if veio_de_um_pagamento_com_retencao
				#evento gerado por pagamento
				evento_gerado_por_pagamento = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where({
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:anulacao_do_talao_de_receita]
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_de_conta_pcasp: [tipo_de_conta_pcasp_do_talao],
						vem_de_pagamento_com_retencao: [veio_de_um_pagamento_com_retencao],
						deposito: [false, nil],
						tipo_de_entidade: [tipo_de_entidade, nil]
					}
				})
			else #evento de deposito
				if self.talao_de_receita.conta_extra_orcamentaria.present? 
					conta_para_lancamento = self.talao_de_receita.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.last.conta rescue nil
					tipo_de_conta_pcasp_do_deposito = self.talao_de_receita.conta_extra_orcamentaria.classe_pcasp == "passivo" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo]
				else
					conta_para_lancamento = self.talao_de_receita.conta_extra_orcamentaria.conta rescue nil
					tipo_de_conta_pcasp_do_deposito = tipo_de_conta_pcasp_do_talao
				end

				if conta_para_lancamento.present? && conta_pcasp_de_deposito(conta_para_lancamento)

					evento_de_deposito = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where({
						contabilidade_eventos_contabeis: {
							modelo: Contabilidade::EventoContabil.modelos[:anulacao_do_talao_de_receita]
						},
						contabilidade_configuracoes_do_evento_contabil: {
							tipo_de_conta_pcasp: [tipo_de_conta_pcasp_do_deposito],
							vem_de_pagamento_com_retencao: [false, nil],
							deposito: true,
							extraorcamentario: self.extra_orcamentario?,
							tipo_de_entidade: [tipo_de_entidade, nil]
						}
					})
				end
			end


			return ( eventos_inclusivos_de_receita + eventos_exclusivos_de_receita + eventos_conta_pcasp + eventos_inclusivos_de_fontes + evento_gerado_por_pagamento + evento_de_deposito + eventos_extra_vinda_de_pagamento).uniq
		end

		def busca_eventos_da_medicao_da_obra
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[self.status.to_sym] rescue nil

			modalidades_do_empenho = self.empenhos.pluck(:modalidade).uniq
			if (modalidades_do_empenho & ["global", "estimativo"] ).any?
				modalidades_do_empenho.push("global_ou_estimativo")
			end
			modalidades_do_empenho = modalidades_do_empenho.map { |modalidade| Contabilidade::ConfiguracaoDoEventoContabil.modalidades_do_empenho[modalidade] }

			tipo_de_obra = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_obra[self.obra.try(:tipo_de_obra)] rescue nil

			if self.obra.orcamento_id.present?
				orcamento_atual = self.obra.orcamento_id
				orcamento_id = orcamento_atual
			else
				orcamento_atual = @orcamento_atual
				orcamento_id = orcamento_atual.id
			end

			sub_elemento_de_despesa_do_evento = []
			self.sub_elementos_de_despesa.each do |sub_elemento_de_despesa|
				sub_elemento_de_despesa_do_exercicio_anterior = Contabilidade::SubElementoDeDespesa.joins(elemento_de_despesa: [ modalidade_de_aplicacao: [ grupo_de_natureza_da_despesa: :categoria_economica ] ]).where("contabilidade_sub_elementos_de_despesa.codigo = ? and base_elementos_de_despesa.codigo = ? and base_categorias_economicas.modulo_id = ? and base_categorias_economicas.modulo_type = 'Orcamento'", sub_elemento_de_despesa.try(:codigo), sub_elemento_de_despesa.try(:elemento_de_despesa).try(:codigo), orcamento_id).first
				sub_elemento_de_despesa_do_evento << sub_elemento_de_despesa_do_exercicio_anterior if sub_elemento_de_despesa_do_exercicio_anterior.present?
			end

			eventos_inclusivos_de_dotacao_e_sem_dotacao = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:medicao_da_obra],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					status: [status, nil],
					tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil],
					classificacao_da_obra: [self.obra.try(:classificacao_do_bem).try(:codigo), nil],
					modalidade_do_empenho: [modalidades_do_empenho, nil],
					tipo_de_obra: [tipo_de_obra, nil],
					tipo_de_pessoa: [tipos_de_pessoa_por_model ,nil],
					resto_a_pagar: [empenhos.any?(&:restos_a_pagar), nil]
				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [sub_elemento_de_despesa_do_evento.pluck(:id) , nil]
				}
			)

			eventos_exclusivos_de_dotacao = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:medicao_da_obra],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					status: [status, nil],
					tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:exclusivo_de_dotacoes], nil],
					classificacao_da_obra: [self.obra.try(:classificacao_do_bem).try(:codigo), nil],
					modalidade_do_empenho: [modalidades_do_empenho, nil],
					tipo_de_obra: [tipo_de_obra, nil],
					tipo_de_pessoa: [tipos_de_pessoa_por_model ,nil],
					resto_a_pagar: [empenhos.any?(&:restos_a_pagar), nil]
				}
			).where.not(
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [sub_elemento_de_despesa_do_evento.pluck(:id)]
				}
			)

			return (eventos_inclusivos_de_dotacao_e_sem_dotacao + eventos_exclusivos_de_dotacao).uniq
		end

		def busca_eventos_da_anulacao_do_empenho
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[self.status] rescue nil
			modulo_de_ativacao = Contabilidade::ConfiguracaoDoEventoContabil.modulo_de_ativacoes[self.modulo_atual.to_sym] rescue nil
			modalidade = [self.empenho.try(:modalidade)]
			if (modalidade & ["global", "estimativo"] ).any?
				modalidade.push("global_ou_estimativo")
			end
			modalidade = modalidade.compact.map { |modalidade| Contabilidade::ConfiguracaoDoEventoContabil.modalidades_do_empenho[modalidade] }

			fluxo_completo_da_anulacao_do_empenho = Configuracao.last.envia_empenho_para_contabilidade? && (self.status_was == 'enviado_para_contabilidade' || self.status_was == 'recebido')

			if indisponibilidade_de_caixa?
				tipo_de_cancelamento = true
			else
				tipo_de_cancelamento = [false, nil]
			end

			fonte_comecada_em_2 = nil
			if self.empenho.fonte_de_recursos.codigo_completo.first == "2"
				aciona_em_fontes_comecadas_com_2 = true
			else
				aciona_em_fontes_comecadas_com_2 = [false, nil]
			end

			#modulo_de_ativacao: [modulo_de_ativacao, nil],

			eventos_inclusivos_de_dotacao_e_sem_dotacao = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:anulacao_do_empenho],
					orcamento_id: self.empenho.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					status: [status, nil],
					tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil],
					modalidade_do_empenho: [modalidade, nil],
					fluxo_completo_da_anulacao_do_empenho: [fluxo_completo_da_anulacao_do_empenho, nil],
					cancelamento_por_falta_de_disponibilidade_de_caixa: tipo_de_cancelamento,
					aciona_em_fontes_comecadas_com_2: [aciona_em_fontes_comecadas_com_2, nil], 
					inversao_de_superavit_financeiro: [nil, false],
					retificadora: [self.retificadora, nil],
					ativar_pela_subconta: [false, nil]
				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [self.empenho.try(:sub_elemento_de_despesa).try(:id), nil]
				}
			)

			eventos_exclusivos_de_dotacao = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:anulacao_do_empenho],
					orcamento_id: self.empenho.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					status: [status, nil],
					tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:exclusivo_de_dotacoes], nil],
					modalidade_do_empenho: [modalidade, nil],
					fluxo_completo_da_anulacao_do_empenho: [fluxo_completo_da_anulacao_do_empenho, nil],
					cancelamento_por_falta_de_disponibilidade_de_caixa: tipo_de_cancelamento,
					aciona_em_fontes_comecadas_com_2: [aciona_em_fontes_comecadas_com_2, nil],
					retificadora: [self.retificadora, nil], 
					inversao_de_superavit_financeiro: [nil, false]
				}
			).where.not(
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil:{
					sub_elemento_de_despesa_id: self.empenho.try(:sub_elemento_de_despesa).try(:id)
				}
			)

			eventos_de_anulacao_sem_tipo_de_eventos = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:anulacao_do_empenho],
					orcamento_id: self.empenho.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					status: [status, nil],
					tipo_de_evento: [nil],
					fluxo_completo_da_anulacao_do_empenho: [fluxo_completo_da_anulacao_do_empenho, nil],
					cancelamento_por_falta_de_disponibilidade_de_caixa: tipo_de_cancelamento,
					aciona_em_fontes_comecadas_com_2: [aciona_em_fontes_comecadas_com_2, nil],
					retificadora: [self.retificadora, nil], 
					inversao_de_superavit_financeiro: [nil, false]
				}
			)

			eventos_ativados_por_subconta = []
			eventos_ativados_por_subconta_parcial = []
			eventos_ativados_por_subconta_credito = []
			eventos_ativados_por_subconta_debito = []

			if self.empenho.sub_conta_pcasp_id.present?
				if self.empenho.movimentacao_do_plano_de_contas_id.present?
					movimentacao_associada_ao_empenho = Contabilidade::MovimentacaoDoPlanoDeContas.find(self.empenho.movimentacao_do_plano_de_contas_id)
					conta_pcasp_da_movimentacao = movimentacao_associada_ao_empenho.conta_por_evento_contabil.conta
					contas_pcasps_da_movimentacao_ids = Contabilidade::Conta.where('codigo = ?', conta_pcasp_da_movimentacao.codigo).pluck(:id) rescue nil
					conta_pcasp_da_movimentacao_par = movimentacao_associada_ao_empenho.conta_por_evento_contabil&.conta_par
					contas_pcasps_da_movimentacao_par_ids = Contabilidade::Conta.where('codigo = ?', conta_pcasp_da_movimentacao_par.codigo).pluck(:id) rescue nil
				else
					if self.empenho.operacao_de_credito_id.present?
						conta_pcasp_da_movimentacao = self.empenho.operacao_de_credito.conta
						contas_pcasps_da_movimentacao_ids = Contabilidade::Conta.where('codigo = ?', conta_pcasp_da_movimentacao.codigo).pluck(:id) rescue nil
					end
				end			

				eventos_ativados_por_subconta_parcial = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:anulacao_do_empenho],
						orcamento_id: self.empenho.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						ativar_pela_subconta: true,
						abertura: [false, nil],
						retificadora: [self.retificadora, nil]
					}
				).where(
					contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
						sub_elemento_de_despesa_id: self.empenho.try(:sub_elemento_de_despesa).try(:id)
					}
				).uniq

				eventos_ativados_por_subconta_debito = Contabilidade::EventoContabil.joins(:contas_por_eventos_contabeis).where(
					contabilidade_eventos_contabeis: {
						id: eventos_ativados_por_subconta_parcial.pluck(:id)
					},
					contabilidade_contas_por_eventos_contabeis: {
						tipo_de_lancamento: 0,
						conta_id: contas_pcasps_da_movimentacao_ids
					}
				).uniq

				eventos_ativados_por_subconta_credito = Contabilidade::EventoContabil.joins(:contas_por_eventos_contabeis).where(
					contabilidade_eventos_contabeis: {
						id: eventos_ativados_por_subconta_parcial.pluck(:id)
					},
					contabilidade_contas_por_eventos_contabeis: {
						tipo_de_lancamento: 0,
						conta_id: contas_pcasps_da_movimentacao_par_ids
					}
				).uniq
			end

			return (eventos_inclusivos_de_dotacao_e_sem_dotacao + eventos_exclusivos_de_dotacao + eventos_de_anulacao_sem_tipo_de_eventos + eventos_ativados_por_subconta_debito + eventos_ativados_por_subconta_credito).uniq
		end

		def busca_eventos_do_bem_do_balancete
			uso_do_bem = Contabilidade::ConfiguracaoDoEventoContabil.uso_do_bens[self.empenho.try(:uso_do_bem_do_empenho)] rescue nil

			#modulo_de_ativacao: [Contabilidade::ConfiguracaoDoEventoContabil.modulo_de_ativacoes[:contabilidade]],

			eventos_do_bem_do_balancete = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:bem_do_balancete],
					orcamento_id: self.empenho.try(:orcamento_id)
				},
				contabilidade_configuracoes_do_evento_contabil: {
					bem_lancado: self.lancado?,
					tipo_do_imovel: Contabilidade::Conta.find_by(id: self.empenho.try(:tipo_do_bem_do_empenho)).try(:codigo),
					uso_do_bem: uso_do_bem,
				}
			)

			return eventos_do_bem_do_balancete
		end

		def busca_eventos_da_situacao_da_obra 
			uso_do_bem = self.obra.read_attribute_before_type_cast(:uso_do_bem) rescue nil
			obra_tombada = self.obra.tombada? || self.tombada?

			#modulo_de_ativacao: [ [Contabilidade::ConfiguracaoDoEventoContabil.modulo_de_ativacoes[:contabilidade]], nil ],

			eventos_da_obra = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:situacao_da_obra],
					orcamento_id: self.obra.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					obra_tombada: [ obra_tombada, nil ],
					tipo_do_bem_da_obra: [self.obra.conta_pcasp.try(:codigo), nil] ,
					classificacao_da_obra: [ Contabilidade::Conta.find(self.obra.conta_id).try(:codigo), nil ],
					uso_do_bem: [ uso_do_bem, nil ]
				}
			)

			return eventos_da_obra.distinct
		end

		def busca_eventos_da_obra
			uso_do_bem = self.read_attribute_before_type_cast(:uso_do_bem) rescue nil
			uso_do_bem = Contabilidade::ConfiguracaoDoEventoContabil.uso_do_bens[uso_do_bem] unless uso_do_bem.is_a? Numeric
			obra_tombada = self.esta_tombada?
			#modulo_de_ativacao: [ [Contabilidade::ConfiguracaoDoEventoContabil.modulo_de_ativacoes[:contabilidade]], nil ],

			eventos_da_obra = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:obra]
				},
				contabilidade_configuracoes_do_evento_contabil: {
					obra_tombada: [ obra_tombada, nil ],
					tipo_do_bem_da_obra: [self.conta_pcasp.try(:codigo), nil] ,
					classificacao_da_obra: [ Contabilidade::Conta.find(self.conta_id).try(:codigo), nil ],
					uso_do_bem: [ uso_do_bem, nil ]
				}
			)

			return eventos_da_obra.uniq
		end

		def busca_eventos_da_requisicao_de_material
			if self.atendido? || self.atendido_parcialmente?
				status = :atendido
			else
				status = self.status.to_sym
			end
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[status] rescue nil

			#modulo_de_ativacao: [ Contabilidade::ConfiguracaoDoEventoContabil.modulo_de_ativacoes[:gestao_de_estoque], nil ],
			eventos_inclusivos_de_dotacao_e_sem_dotacao = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:requisicao_de_material]
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					status: [ status, nil ],
					veio_de_uma_ordem: [self.recebimento_de_material.try(:ordem_de_compra).present?, nil]
				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [sub_elemento_de_despesa.try(:id), nil]
				}
			)

			eventos_exclusivos_de_dotacao = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:requisicao_de_material]
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:exclusivo_de_dotacoes] ,
					status: [ status, nil ],
					veio_de_uma_ordem: [self.recebimento_de_material.try(:ordem_de_compra).present?, nil]
				}
			).where.not(
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: sub_elemento_de_despesa.try(:id)
				}
			).uniq

			return eventos_inclusivos_de_dotacao_e_sem_dotacao + eventos_exclusivos_de_dotacao
		end

		def busca_eventos_da_despesa_extra
			eventos = Array.new
			eventos_a_acionar = Array.new
			eventos_de_controle = Array.new
			classe_da_conta_pcasp = conta_extra_orcamentaria.conta.read_attribute_before_type_cast(:classe) rescue nil
			conta_pcasp_da_conta_bancaria_ids = self.conta_bancaria_por_unidade_orcamentaria.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.pluck(:conta_id) rescue nil
			codigo_sim = self.conta_extra_orcamentaria.outros? ? Contabilidade::ConfiguracaoDoEventoContabil.codigos_sim[:outros_codigo] : Contabilidade::ConfiguracaoDoEventoContabil.codigos_sim[self.conta_extra_orcamentaria.codigo_sim]

			if classe_da_conta_pcasp.present? && conta_pcasp_da_conta_bancaria_ids.present?
				tipo_de_conta_pcasp = self.conta_extra_orcamentaria.classe_pcasp == "ativo" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo]
				contapcasp_deposito = conta_pcasp_de_deposito(self.conta_extra_orcamentaria.conta)
				contapcasp_retencoes_e_consignacoes = conta_pcasp_de_retencoes_e_consignacoes(self.conta_extra_orcamentaria.conta)

				investimento_rpps = self.conta_extra_orcamentaria.investimento_rpps? ? true : [false, nil]

				eventos = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:despesa_extra_orcamentaria],
						orcamento_id: orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						conta_pcasp_id: [ conta_extra_orcamentaria.try(:conta_id), nil],
						conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
						classe_da_conta_pcasp: [classe_da_conta_pcasp, nil],
						tipo_de_conta_pcasp: [tipo_de_conta_pcasp, nil],
						retencao: [contapcasp_retencoes_e_consignacoes, nil],
						consignacao: [contapcasp_retencoes_e_consignacoes, nil],
						deposito: [contapcasp_deposito, nil],
						estorno: [false, nil],
						investimento_rpps: investimento_rpps,
						codigo_sim:[nil, codigo_sim]
					}
				)

			else
				tipo_de_conta_pcasp = self.conta_extra_orcamentaria&.classe_pcasp == "ativo" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo]
				contapcasp_deposito = conta_pcasp_de_deposito(self.conta_extra_orcamentaria&.conta)
				contapcasp_retencoes_e_consignacoes = conta_pcasp_de_retencoes_e_consignacoes(self.conta_extra_orcamentaria&.conta)

				investimento_rpps = self.conta_extra_orcamentaria&.investimento_rpps? ? true : [false, nil]

				eventos = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:despesa_extra_orcamentaria],
						orcamento_id: orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						conta_pcasp_id: [ conta_extra_orcamentaria.try(:conta_id), nil],
						conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
						classe_da_conta_pcasp: [classe_da_conta_pcasp, nil],
						tipo_de_conta_pcasp: [tipo_de_conta_pcasp, nil],
						retencao: [contapcasp_retencoes_e_consignacoes, nil],
						consignacao: [contapcasp_retencoes_e_consignacoes, nil],
						deposito: [contapcasp_deposito, nil],
						estorno: [false, nil],
						investimento_rpps: investimento_rpps
					}
				)
			end

			if codigo_sim == "99999999"
				conta = self.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.where(orcamento_id: orcamento_id).first&.conta_id rescue nil

				eventos_a_acionar = eventos.joins(:contas_por_eventos_contabeis)
					.where(contabilidade_contas_por_eventos_contabeis: { tipo_de_lancamento: 0 })
					.where(
						contabilidade_configuracoes_do_evento_contabil: { codigo_sim: codigo_sim }
					)
					.where(
						'conta_id = ? OR conta_par_id = ?', conta, conta
					).distinct


			else
				eventos_a_acionar = eventos.joins(:contas_por_eventos_contabeis).where(
					contabilidade_contas_por_eventos_contabeis: {
						tipo_de_lancamento: 0,
						conta_id: conta_extra_orcamentaria.try(:conta_id)
					}
				)
			end


			eventos_de_controle = eventos.where(
				contabilidade_configuracoes_do_evento_contabil: {
					ativar_para_todas_as_contas: true
				}
			)

			return (eventos_a_acionar + eventos_de_controle).uniq
		end

		def busca_eventos_do_estorno_de_despesa_extra
			classe_da_conta_pcasp = self.despesa_extra_orcamentaria.conta_extra_orcamentaria.conta.read_attribute_before_type_cast(:classe_da_conta_pcasp) rescue nil
			conta_pcasp_da_conta_bancaria_ids = self.despesa_extra_orcamentaria.conta_bancaria_por_unidade_orcamentaria.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.pluck(:conta_id) rescue nil

			tipo_de_conta_pcasp = self.despesa_extra_orcamentaria.conta_extra_orcamentaria.classe_pcasp == "ativo" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo]
			contapcasp_deposito = conta_pcasp_de_deposito(self.despesa_extra_orcamentaria.conta_extra_orcamentaria.conta)
			contapcasp_retencoes_e_consignacoes = conta_pcasp_de_retencoes_e_consignacoes(self.despesa_extra_orcamentaria.conta_extra_orcamentaria.conta)

			investimento_rpps = self.despesa_extra_orcamentaria.conta_extra_orcamentaria.investimento_rpps? ? true : [false, nil]
			codigo_sim = self.despesa_extra_orcamentaria.conta_extra_orcamentaria.outros? ? Contabilidade::ConfiguracaoDoEventoContabil.codigos_sim[:outros_codigo] : Contabilidade::ConfiguracaoDoEventoContabil.codigos_sim[self.despesa_extra_orcamentaria.conta_extra_orcamentaria.codigo_sim]

			eventos = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:estorno_de_despesa_extra_orcamentaria],
					orcamento_id: self.despesa_extra_orcamentaria.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					conta_pcasp_id: [ self.despesa_extra_orcamentaria.conta_extra_orcamentaria.try(:conta_id), nil],
					conta_pcasp_da_conta_bancaria_id: [nil, conta_pcasp_da_conta_bancaria_ids].flatten,
					classe_da_conta_pcasp: [classe_da_conta_pcasp, nil],
					tipo_de_conta_pcasp: [tipo_de_conta_pcasp, nil],
					retencao: [contapcasp_retencoes_e_consignacoes, nil],
					consignacao: [contapcasp_retencoes_e_consignacoes, nil],
					deposito: [contapcasp_deposito, nil],
					estorno: true,
					investimento_rpps: investimento_rpps,
					codigo_sim: [codigo_sim, nil]
				}
			)

			if codigo_sim == "99999999"
				conta = self.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.where(orcamento_id: orcamento_id).first&.conta_id rescue nil

				eventos_a_acionar = eventos.joins(:contas_por_eventos_contabeis)
					.where(contabilidade_contas_por_eventos_contabeis: { tipo_de_lancamento: 1 })
					.where(
						contabilidade_configuracoes_do_evento_contabil: { codigo_sim: codigo_sim }
					)
					.where(
						'conta_id = ? OR conta_par_id = ?', conta, conta
					).distinct

			else
				eventos_a_acionar = eventos.joins(:contas_por_eventos_contabeis).where(
					contabilidade_contas_por_eventos_contabeis: {
						tipo_de_lancamento: 1,
						conta_id: self.despesa_extra_orcamentaria.conta_extra_orcamentaria.try(:conta_id)
					}
				)
			end


			#eventos_de_controle = eventos.where(
			#	contabilidade_configuracoes_do_evento_contabil: {
			#		ativar_para_todas_as_contas: true
			#	}
			#)

			return (eventos_a_acionar).uniq
		end

		def busca_eventos_da_retencao
			if get_liquidacao.empenho.ordinario?
				modalidade_do_empenho = 'ordinario'
			else
				modalidade_do_empenho = 'global_ou_estimativo'
			end

			modalidade_do_empenho = Contabilidade::ConfiguracaoDoEventoContabil.modalidades_do_empenho[modalidade_do_empenho]

			origem_da_retencao = Contabilidade::ConfiguracaoDoEventoContabil.origens_da_retencao[self.origem_da_retencao]

			Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:retencao],
					orcamento_id: orcamento.id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					conta_pcasp_id: conta_extra_orcamentaria.try(:conta_id),
					origem_da_retencao: [origem_da_retencao, nil],
					modalidade_do_empenho: [modalidade_do_empenho, nil],
					tipo_de_pessoa: [tipos_de_pessoa_por_model, nil]
				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [get_liquidacao.empenho.try(:sub_elemento_de_despesa).try(:id), nil]
				}
			).where.not(
				contabilidade_configuracoes_do_evento_contabil:{
					conta_pcasp_id: nil
				}
			)
		end

		def busca_eventos_da_transferencia_financeira
			eventos = Array.new
			eventos_ugs = Array.new
			conta_pcasp_origem = conta_bancaria_origem.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.find_by(orcamento_id: orcamento_id).try(:conta_id) rescue nil
			conta_pcasp_destino = conta_bancaria_destino.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.find_by(orcamento_id: orcamento_id).try(:conta_id) rescue nil

			ug_eh_a_mesma = (self.conta_bancaria_origem.unidade_orcamentaria.unidade_gestora == self.conta_bancaria_destino.unidade_orcamentaria.unidade_gestora)
			
			if ug_eh_a_mesma == true
				eventos = Contabilidade::EventoContabil.joins(:contas_por_eventos_contabeis).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:transferencia_financeira],
						orcamento_id: self.orcamento_id
					},
					contabilidade_contas_por_eventos_contabeis: {
						tipo_de_lancamento: 0,
						conta_id: conta_pcasp_destino
					}
				)
	
				eventos = Contabilidade::EventoContabil.joins(:contas_por_eventos_contabeis).where(id: eventos.ids).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:transferencia_financeira],
						orcamento_id: self.orcamento_id
					},
					contabilidade_contas_por_eventos_contabeis: {
						tipo_de_lancamento: 1,
						conta_id: conta_pcasp_origem
					}
				)

				eventos_ugs = eventos.joins(:configuracao_do_evento_contabil).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:transferencia_financeira],
						orcamento_id: self.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						ug_diferente: false
					}
				)

			else
				eventos_origem = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:transferencia_financeira],
						orcamento_id: self.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						ug_diferente: true,
						tipo_de_ug: Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_ug[:origem],
						conta_pcasp_da_conta_bancaria_id: conta_pcasp_origem
					}
				)

				eventos_destino = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:transferencia_financeira],
						orcamento_id: self.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						ug_diferente: true,
						tipo_de_ug: Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_ug[:destino],
						conta_pcasp_da_conta_bancaria_id: conta_pcasp_destino
					}
				)

				eventos_ugs = (eventos_origem + eventos_destino).uniq
			end

			return (eventos + eventos_ugs).uniq
		end

		def busca_eventos_do_estorno_de_liquidacao
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[self.status.to_sym] rescue nil
			liquidacao_de_restos_a_pagar = self.liquidacao.empenho.restos_a_pagar
			tipo_de_resto_a_pagar = nil
			modalidade = [self.liquidacao.empenho.try(:modalidade)]
			if (modalidade & ["global", "estimativo"] ).any?
				modalidade.push("global_ou_estimativo")
			end
			modalidade = modalidade.compact.map { |modalidade| Contabilidade::ConfiguracaoDoEventoContabil.modalidades_do_empenho[modalidade] }

			sub_elemento_de_despesa_do_evento = self.liquidacao.sub_elemento_de_despesa

			if self.empenho.restos_a_pagar
				liquidacao_de_restos_a_pagar = true
			else
				liquidacao_de_restos_a_pagar = [false, nil]
			end

			if self.liquidacao.orcamento_id.present?
				orcamento_atual = self.liquidacao.orcamento
			else
				orcamento_atual = @orcamento_atual
			end

			if liquidacao_de_restos_a_pagar

				if self.liquidacao.data_da_liquidacao.present? && self.liquidacao.data_da_liquidacao.year < orcamento_atual.exercicio
					tipo_de_resto_a_pagar = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_resto_a_pagar['rp_processado']
				else
					tipo_de_resto_a_pagar = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_resto_a_pagar['rp_nao_processado']
				end

				sub_elemento_de_despesa_do_exercicio_anterior = Contabilidade::SubElementoDeDespesa.joins(elemento_de_despesa: [ modalidade_de_aplicacao: [ grupo_de_natureza_da_despesa: :categoria_economica ] ]).where("contabilidade_sub_elementos_de_despesa.codigo = ? and base_elementos_de_despesa.codigo = ? and base_categorias_economicas.modulo_id = ? and base_categorias_economicas.modulo_type = 'Orcamento'", sub_elemento_de_despesa.try(:codigo), sub_elemento_de_despesa.try(:elemento_de_despesa).try(:codigo), orcamento_atual.id).first
				sub_elemento_de_despesa_do_evento = sub_elemento_de_despesa_do_exercicio_anterior if sub_elemento_de_despesa_do_exercicio_anterior.present?
			end

			if self.liquidacao.empenho.classificacao_pcasp.nil?
				classificacao_pcasp_do_empenho = nil
			else
				classificacao_pcasp_do_empenho = Contabilidade::ConfiguracaoDoEventoContabil.classificacoes_pcasp[self.liquidacao.empenho.classificacao_pcasp]
			end

			originado_de_um_contrato = self.liquidacao.empenho.contrato.present?

			#modulo_de_ativacao: [ Contabilidade::ConfiguracaoDoEventoContabil.modulo_de_ativacoes[self.try(:modulo_atual).try(:to_sym)], nil ],

			eventos_inclusivos_de_dotacao_e_sem_dotacao = Contabilidade::EventoContabil.left_outer_joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:estorno_de_liquidacao],
					orcamento_id: orcamento_atual
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil] ,
					status: [ status, nil ],
					modalidade_do_empenho: [ modalidade, nil ],
					resto_a_pagar: [liquidacao_de_restos_a_pagar],
					tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
					tipo_de_pessoa: [ tipos_de_pessoa_por_model, nil ],
					originado_de_um_contrato: [originado_de_um_contrato, nil],
					classificacao_pcasp: [classificacao_pcasp_do_empenho, nil]
				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [sub_elemento_de_despesa_do_evento.try(:id), nil]
				}
			)

			eventos_exclusivos_de_dotacao =  Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:estorno_de_liquidacao],
					orcamento_id: orcamento_atual
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:exclusivo_de_dotacoes], nil] ,
					status: [ status, nil ],
					modalidade_do_empenho: [ modalidade, nil ],
					resto_a_pagar: [liquidacao_de_restos_a_pagar],
					tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
					tipo_de_pessoa: [ tipos_de_pessoa_por_model, nil ],
					originado_de_um_contrato: [originado_de_um_contrato, nil],
					classificacao_pcasp: [classificacao_pcasp_do_empenho, nil]
				}
			).where.not(
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: sub_elemento_de_despesa_do_evento.try(:id)
				}
			).uniq
			
			#Reconhecido na Liquidação da Despesa

			eventos_com_reconhecimento = [] 

			if (self.liquidacao.empenho.tipo_de_reconhecimento_do_passivo == "reconhecido_na_liquidacao_da_despesa" || self.empenho.tipo_de_reconhecimento_do_passivo == "reconhecimento_no_exercicio_vigente" || self.empenho.tipo_de_reconhecimento_do_passivo == "reconhecimento_no_exercicio_anterior")
				if self.liquidacao.empenho.classificacao_vpd.nil?
					classificacao_vpd = nil
				else
					classificacao_vpd = Contabilidade::ConfiguracaoDoEventoContabil.classificacoes_vpd[self.liquidacao.empenho.classificacao_vpd]
				end

				if self.liquidacao.empenho.regime.nil?
					regime = nil
				else
					regime = Contabilidade::ConfiguracaoDoEventoContabil.regimes[self.liquidacao.empenho.regime]
				end

				if self.liquidacao.empenho.tipo_de_entidade.nil?
					tipo_de_entidade = nil
				else
					tipo_de_entidade = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_entidade[self.liquidacao.empenho.tipo_de_entidade]
				end

				detalhamento_por_vpd = self.liquidacao.detalhamentos_por_subelementos.map { |i| i if i.valor.to_d.positive? }.compact

				if detalhamento_por_vpd.size > 0
					eventos_com_reconhecimento_ids = []
					detalhamento_por_vpd.each do |detalhamento_vpd|
						tipo_de_detalhamento_vpd = Contabilidade::ConfiguracaoDoEventoContabil.detalhamentos_vpd_da_liquidacao[tipo_detalhamento_vpd_da_liquidacao(detalhamento_vpd.conta.nome)]

						eventos_com_reconhecimento_parcial = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
							contabilidade_eventos_contabeis: {
								modelo: Contabilidade::EventoContabil.modelos[self.empenho.tipo_de_reconhecimento_do_passivo.to_sym],
								orcamento_id: orcamento_atual
							},
							contabilidade_configuracoes_do_evento_contabil: {
								status: [ status, nil ],
								modalidade_do_empenho: [ modalidade, nil ],
								resto_a_pagar: [liquidacao_de_restos_a_pagar],
								tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
								classificacao_vpd: [classificacao_vpd, nil],
								regime: [regime, nil],
								tipo_de_entidade: [tipo_de_entidade, nil],
								tipo_de_pessoa: [ tipos_de_pessoa_por_model, nil ],
								detalhamento_vpd_da_liquidacao: tipo_de_detalhamento_vpd,
								classificacao_pcasp: [classificacao_pcasp_do_empenho, nil],
								estorno: true
							}
						).where(
							contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
								sub_elemento_de_despesa_id: sub_elemento_de_despesa_do_evento.try(:id)
							}
						).uniq

						eventos_com_reconhecimento_ids = eventos_com_reconhecimento_ids + eventos_com_reconhecimento_parcial.pluck(:id)
					end
					eventos_com_reconhecimento = Contabilidade::EventoContabil.where('id in (?)', eventos_com_reconhecimento_ids)
				else
					eventos_com_reconhecimento = Contabilidade::EventoContabil.joins( configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ] ).where(
						contabilidade_eventos_contabeis: {
							modelo: Contabilidade::EventoContabil.modelos[self.empenho.tipo_de_reconhecimento_do_passivo.to_sym],
							orcamento_id: orcamento_atual
						},
						contabilidade_configuracoes_do_evento_contabil: {
							status: [ status, nil ],
							modalidade_do_empenho: [ modalidade, nil ],
							resto_a_pagar: [liquidacao_de_restos_a_pagar],
							tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
							classificacao_vpd: [classificacao_vpd, nil],
							regime: [regime, nil],
							tipo_de_entidade: [tipo_de_entidade, nil],
							tipo_de_pessoa: [ tipos_de_pessoa_por_model, nil ],
							classificacao_pcasp: [classificacao_pcasp_do_empenho, nil],
							estorno: true
						}
					).where(
						contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
							sub_elemento_de_despesa_id: sub_elemento_de_despesa_do_evento.try(:id)
						}
					).uniq
				end
			end

			eventos_ddr =  Contabilidade::EventoContabil.joins( :configuracao_do_evento_contabil ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:estorno_de_liquidacao],
					orcamento_id: orcamento_atual
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: nil,
					status: Contabilidade::ConfiguracaoDoEventoContabil.status['confirmado'.to_sym],
					resto_a_pagar: nil
				}
			)

			return (eventos_inclusivos_de_dotacao_e_sem_dotacao + eventos_exclusivos_de_dotacao + eventos_com_reconhecimento + eventos_ddr).uniq
			
		end

		def busca_eventos_do_bloqueio_de_dotacao
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[self.status.to_sym] rescue nil

			#temporario enquanto esta apagando os eventos quando vão criar outros
			if status == 29
				status = [28, 29]
			end
			
			Contabilidade::EventoContabil.joins( :configuracao_do_evento_contabil ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:bloqueio_de_dotacao],
					orcamento_id: unidade_orcamentaria.orgao.orcamento.id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					status: status
				}
			)
		end

		def busca_eventos_da_alteracao_orcamentaria
			eventos_de_anulacao = Array.new
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[self.status.to_sym] rescue nil
			tipo_de_credito = Contabilidade::ConfiguracaoDoEventoContabil.tipo_de_creditos[self.tipo_de_credito.to_sym] rescue nil
			origem_do_recurso = Contabilidade::ConfiguracaoDoEventoContabil.origens_dos_recursos[self.origem_do_recurso.to_sym] rescue nil

			eventos = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:solicitacao_de_alteracao_orcamentaria],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					status: [status, nil],
					tipo_de_credito: [tipo_de_credito, nil],
					origem_do_recurso:[origem_do_recurso, nil]
				}
			).distinct

			if self.anulacao_de_dotacao?
				eventos_de_anulacao = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:solicitacao_de_alteracao_orcamentaria],
						orcamento_id: orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						status: [status, nil],
						tipo_de_credito: Contabilidade::ConfiguracaoDoEventoContabil.tipo_de_creditos[:credito_de_reducao]
					}
				).uniq
	
			end

			return (eventos + eventos_de_anulacao).uniq
		end

		def busca_eventos_do_cancelamento_de_resto_a_pagar
			if self.tipo == "nao_processado"
				tipo_de_resto_a_pagar = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_resto_a_pagar['rp_nao_processado']
			else
				tipo_de_resto_a_pagar = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_resto_a_pagar['rp_processado']
			end

			motivo_do_cancelamento = nil
			if self.motivo == "outros"
				motivo_do_cancelamento = "outros_motivos_cancelamento"
			else
				motivo_do_cancelamento = self.motivo
			end

			motivo_cancelamento = Contabilidade::ConfiguracaoDoEventoContabil.motivos_cancelamento[motivo_do_cancelamento.to_sym] rescue nil
			status_do_cancelamento = Contabilidade::ConfiguracaoDoEventoContabil.status[self.status] rescue nil
			if self.orcamento_id.present?
				orcamento_atual = self.orcamento
			else
				orcamento_atual = @orcamento_atual
			end
			sub_elemento_de_despesa_do_exercicio_anterior = Contabilidade::SubElementoDeDespesa.joins(elemento_de_despesa: [ modalidade_de_aplicacao: [ grupo_de_natureza_da_despesa: :categoria_economica ] ]).where("contabilidade_sub_elementos_de_despesa.codigo IN (?) AND base_elementos_de_despesa.codigo IN (?) AND base_categorias_economicas.modulo_id = ? AND base_categorias_economicas.modulo_type = 'Orcamento'", self.empenhos.map{|empenho| empenho.sub_elemento_de_despesa.try(:codigo)}, self.empenhos.map{|empenho| empenho.sub_elemento_de_despesa.try(:elemento_de_despesa).try(:codigo)}, orcamento_atual.id).ids

			eventos_inclusivos = Contabilidade::EventoContabil.joins(configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ]).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:cancelamento_de_resto_a_pagar],
					orcamento_id: orcamento_atual.id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					status: [status_do_cancelamento, nil],
					tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
					motivo_cancelamento: [motivo_cancelamento, nil],
					tipo_de_evento: Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes]
				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [sub_elemento_de_despesa_do_exercicio_anterior, nil]
				}
			).distinct

			#eventos_inclusivos = Contabilidade::EventoContabil.joins(configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ]).where(contabilidade_eventos_contabeis: {modelo: Contabilidade::EventoContabil.modelos[:cancelamento_de_resto_a_pagar], orcamento_id: orcamento_id}, contabilidade_configuracoes_do_evento_contabil: { status: [status_do_cancelamento, nil], tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil], motivo_cancelamento: [motivo_cancelamento, nil], tipo_de_evento: Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes]}, contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {sub_elemento_de_despesa_id: [sub_elemento_de_despesa_do_exercicio_anterior, nil].flatten}).distinct

			eventos_exclusivos = Contabilidade::EventoContabil.left_joins(configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ]).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:cancelamento_de_resto_a_pagar],
					orcamento_id: orcamento_atual.id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					status: [status_do_cancelamento, nil],
					tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil],
					motivo_cancelamento: [motivo_cancelamento],
					tipo_de_evento: Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:exclusivo_de_dotacoes]
					}
				)
			# 	.where.not(
			# 	contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
			# 		sub_elemento_de_despesa_id: [sub_elemento_de_despesa_do_exercicio_anterior, nil].flatten
			# 	}
			# ).distinct
			
			#eventos_exclusivos = Contabilidade::EventoContabil.left_joins(configuracao_do_evento_contabil: [:sub_elementos_de_despesa_da_configuracao_contabil ]).where(contabilidade_eventos_contabeis: {modelo: Contabilidade::EventoContabil.modelos[:cancelamento_de_resto_a_pagar], orcamento_id: orcamento_id}, contabilidade_configuracoes_do_evento_contabil: {status: [status_do_cancelamento, nil], tipo_de_resto_a_pagar: [tipo_de_resto_a_pagar, nil], motivo_cancelamento: [motivo_cancelamento, nil], tipo_de_evento: Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:exclusivo_de_dotacoes]},).where.not(contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {sub_elemento_de_despesa_id: [sub_elemento_de_despesa_do_exercicio_anterior, nil].flatten}).distinct

			return (eventos_inclusivos + eventos_exclusivos).uniq
		end

		def busca_eventos_do_orcamento
			Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:orcamento],
					orcamento_id: id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					plano_de_contas_encerrado: [plano_de_contas_encerrado, nil]
					}
				)
		end

		def busca_eventos_do_cronograma_do_empenho
			eventos = Contabilidade::EventoContabil.joins(configuracao_do_evento_contabil: :sub_elementos_de_despesa_da_configuracao_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[empenho.tipo_de_reconhecimento_do_passivo],
					orcamento_id: empenho.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil],
					estorno: [ estornado?, nil]
				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [empenho.sub_elemento_de_despesa_id, nil]
				}
			).distinct

			return eventos
		end

		def busca_eventos_do_contrato
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[self.status.to_sym] rescue nil
			Contabilidade::EventoContabil.left_joins(configuracao_do_evento_contabil: :sub_elementos_de_despesa_da_configuracao_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:contrato],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil],
					status: [status, nil]
				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [sub_elementos_de_despesa.ids, nil].flatten
				}
			).distinct
		end

		def busca_eventos_do_aditivo
			status = Contabilidade::ConfiguracaoDoEventoContabil.status[self.status] rescue nil
			modalidade_do_aditivo = Contabilidade::ConfiguracaoDoEventoContabil.modalidades_do_aditivo["aditivo_#{self.modalidade}"] rescue nil
			sub_elementos_ids = sub_elementos_de_despesa.any? ? sub_elementos_de_despesa.ids : contrato.sub_elementos_de_despesa.ids
			Contabilidade::EventoContabil.left_joins(configuracao_do_evento_contabil: :sub_elementos_de_despesa_da_configuracao_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:aditivo],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_dotacoes], nil],
					modalidade_do_aditivo: [modalidade_do_aditivo, nil],
					status: [status, nil]
				},
				contabilidade_sub_elementos_de_despesa_da_configuracao_contabil: {
					sub_elemento_de_despesa_id: [sub_elementos_ids, nil].flatten
				}
			).distinct
		end

		def busca_eventos_do_orcamento_da_receita
			tipos_de_previsoes = [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_previsoes[natureza_da_receita.tipo_de_alteracao]] rescue []

			if natureza_da_receita.tipo_de_alteracao == "reestimativa" || natureza_da_receita.tipo_de_alteracao == "correcao"
				tipos_de_previsoes.push(Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_previsoes[:reestimativa_ou_correcao])
			end

			if natureza_da_receita.categoria_economica == '009'
				receita_de_deducao = true
			else
				receita_de_deducao = [false, nil]
			end

			Contabilidade::EventoContabil.left_outer_joins(configuracao_do_evento_contabil: :naturezas_da_receita_da_configuracao_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:orcamento_da_receita],
					orcamento_id: unidade_orcamentaria.orgao.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_de_previsao: [tipos_de_previsoes, nil],
					receita_de_deducao: receita_de_deducao
				},
				contabilidade_naturezas_da_receita_da_configuracao_contabil: {
					categoria_economica: [natureza_da_receita.categoria_economica, '000', nil ],
					origem: [natureza_da_receita.origem, '0', nil],
					especie: [natureza_da_receita.especie, '0', nil],
					rubrica: [natureza_da_receita.rubrica, '0', nil],
					alinea: [natureza_da_receita.alinea, '00', nil],
					subalinea: [natureza_da_receita.subalinea, '0', nil],
					detalhamento_optativo: [natureza_da_receita.detalhamento_optativo, '0', nil],
					nivel_opcional_1: [natureza_da_receita.nivel_opcional_1, '00', nil],
					nivel_opcional_2: [natureza_da_receita.nivel_opcional_2, '00',nil ],
					nivel_opcional_3: [natureza_da_receita.nivel_opcional_3, '00', nil]
				}
			)
		end

		def busca_eventos_do_empenho_ddr
			fonte_comecada_em_2 = nil
			if self.fonte_de_recursos.codigo_completo.first == "2"
				aciona_em_fontes_comecadas_com_2 = true
			else
				aciona_em_fontes_comecadas_com_2 = false
			end

			eventos_ddr = Contabilidade::EventoContabil.left_outer_joins( :configuracao_do_evento_contabil ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:ddr],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:empenho_ddr], nil] ,
					aciona_em_fontes_comecadas_com_2: [aciona_em_fontes_comecadas_com_2, nil]
				}
			)

			return eventos_ddr
		end

		def busca_eventos_de_anulacao_do_empenho_ddr
			fonte_comecada_em_2 = nil
			if self.empenho.fonte_de_recursos.codigo_completo.first == "2"
				aciona_em_fontes_comecadas_com_2 = true
			else
				aciona_em_fontes_comecadas_com_2 = false
			end
		end

		def cria_eventos_contabeis_por_gerador
			ActiveRecord::Base.connection.execute("DELETE FROM contabilidade_eventos_contabeis_por_gerador WHERE id in (#{self.eventos_contabeis_por_gerador.ids.join(",")})") if self.eventos_contabeis_por_gerador.ids.size > 0

			eventos_ddr = Contabilidade::EventoContabil.left_outer_joins( :configuracao_do_evento_contabil ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:ddr],
					orcamento_id: self.empenho.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:anulacao_do_empenho_ddr], nil] ,
					aciona_em_fontes_comecadas_com_2: [aciona_em_fontes_comecadas_com_2, nil]
				}
			)

			return eventos_ddr
		end

		def busca_eventos_da_liquidacao_ddr
			eventos_ddr = Contabilidade::EventoContabil.left_outer_joins( :configuracao_do_evento_contabil ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:ddr],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:liquidacao_ddr], nil]
				}
			)

			return eventos_ddr
		end 

		def busca_eventos_do_estorno_de_liquidacao_ddr
			eventos_ddr = Contabilidade::EventoContabil.left_outer_joins( :configuracao_do_evento_contabil ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:ddr],
					orcamento_id: self.liquidacao.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:estorno_de_liquidacao_ddr], nil]
				}
			)

			return eventos_ddr
		end

		def busca_eventos_do_pagamento_ddr
			eventos_ddr = Contabilidade::EventoContabil.left_outer_joins( :configuracao_do_evento_contabil ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:ddr],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:pagamento_ddr], nil]
				}
			)

			return eventos_ddr
		end

		def busca_eventos_do_estorno_de_pagamento_ddr
			eventos_ddr = Contabilidade::EventoContabil.left_outer_joins( :configuracao_do_evento_contabil ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:ddr],
					orcamento_id: self.pagamento.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:estorno_de_pagamento_ddr], nil]
				}
			)

			return eventos_ddr
		end
		
		def apagar_movimentos(orcamento_atual = nil)
			if contexto_atual.present?
				@orcamento_atual = contexto_atual
			else
				@orcamento_atual = orcamento_atual
			end

			#Deleta todas as movimentações do orçamento antes de gerar as novas
			self.movimentacoes_do_plano_de_contas.joins(:evento_contabil).where('contabilidade_eventos_contabeis.orcamento_id = ?', @orcamento_atual.id).where("coalesce(contabilidade_movimentacoes_do_plano_de_contas.lancamento_manual, 0) != 1000").destroy_all unless @orcamento_atual.nil?
		end

		def busca_eventos_da_transferencia_financeira_ddr
			eventos_ddr = Array.new

			if self.repasse_de_duodecimo_da_camara? || self.recebimento_de_duodecimo_da_camara?
				duodecimo = true 
			else
				duodecimo = false 
			end

			if self.devolucao_de_duodecimo_da_camara?
				devolucao_duodecimo = true 
			else
				devolucao_duodecimo = false 
			end

			if duodecimo == true
				eventos_ddr = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:ddr],
						orcamento_id: self.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:transferencia_financeira_ddr]],
						duodecimo: [duodecimo]
					}
				)

			elsif devolucao_duodecimo == true
				eventos_ddr = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:ddr],
						orcamento_id: self.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:transferencia_financeira_ddr]],
						devolucao_duodecimo: [devolucao_duodecimo]
					}
				)
			end

			return eventos_ddr
		end

		def define_tipo_de_movimentacao(orcamento_atual = nil)
			if executa_eventos
				if contexto_atual.present?
					@orcamento_atual = contexto_atual
				else
					@orcamento_atual = orcamento_atual
				end

				if self.class.name == "Contabilidade::TransferenciaFinanceira"
					gera_movimentacao_de_transferencia(eventos_de_transferencia)
					gera_movimentacao(eventos_regulares)
				elsif self.class.name == "Contabilidade::Pagamento"
					gera_movimentacao(eventos_regulares)
					gera_movimentacao_pagamento_por_conta_bancaria(eventos_de_pagamento_com_conta_bancaria)
				else
					gera_movimentacao(eventos_regulares, @orcamento_atual)
				end
			end
		end

		def busca_eventos_da_despesa_extra_ddr
			tipo_de_conta_pcasp = self.conta_extra_orcamentaria.classe_pcasp == "ativo" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo]
			contapcasp_deposito = conta_pcasp_de_deposito(self.conta_extra_orcamentaria.conta)
			contapcasp_retencoes_e_consignacoes = conta_pcasp_de_retencoes_e_consignacoes(self.conta_extra_orcamentaria.conta)

			eventos_ddr = Contabilidade::EventoContabil.left_outer_joins( :configuracao_do_evento_contabil ).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:ddr],
					orcamento_id: orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:despesa_extra_orcamentaria_ddr], nil],
					tipo_de_conta_pcasp: [tipo_de_conta_pcasp, nil],
					retencao: [contapcasp_retencoes_e_consignacoes, nil],
					consignacao: [contapcasp_retencoes_e_consignacoes, nil],
					deposito: [contapcasp_deposito, nil],
					ativar_para_todas_as_contas: true
				}
			)

			eventos_ddr = Contabilidade::EventoContabil.left_outer_joins( :configuracao_do_evento_contabil ).where(contabilidade_eventos_contabeis: { modelo: Contabilidade::EventoContabil.modelos[:ddr], orcamento_id: orcamento_id }, contabilidade_configuracoes_do_evento_contabil: { tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:despesa_extra_orcamentaria_ddr], nil], tipo_de_conta_pcasp: [tipo_de_conta_pcasp, nil], retencao: [contapcasp_retencoes_e_consignacoes, nil], consignacao: [contapcasp_retencoes_e_consignacoes, nil], deposito: [contapcasp_deposito, nil], ativar_para_todas_as_contas: true})

			return eventos_ddr
		end

		def busca_eventos_do_estorno_de_despesa_extra_ddr
			tipo_de_conta_pcasp = self.despesa_extra_orcamentaria.conta_extra_orcamentaria.classe_pcasp == "ativo" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo]
			contapcasp_deposito = conta_pcasp_de_deposito(self.despesa_extra_orcamentaria.conta_extra_orcamentaria.conta)
			contapcasp_retencoes_e_consignacoes = conta_pcasp_de_retencoes_e_consignacoes(self.despesa_extra_orcamentaria.conta_extra_orcamentaria.conta)

			eventos_ddr = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where(
				contabilidade_eventos_contabeis: {
					modelo: Contabilidade::EventoContabil.modelos[:ddr],
					orcamento_id: self.despesa_extra_orcamentaria.orcamento_id
				},
				contabilidade_configuracoes_do_evento_contabil: {
					tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:estorno_de_despesa_extra_orcamentaria_ddr]],
					tipo_de_conta_pcasp: [tipo_de_conta_pcasp, nil],
					retencao: [contapcasp_retencoes_e_consignacoes, nil],
					consignacao: [contapcasp_retencoes_e_consignacoes, nil],
					deposito: [contapcasp_deposito, nil],
					ativar_para_todas_as_contas: true
				}
			)

			return eventos_ddr
		end

		def busca_eventos_do_talao_de_receita_ddr
			eventos_inclusivos_de_receita = Array.new
			eventos_conta_extra_ddr = Array.new
			eventos_ddr = Array.new

			tipo_de_poder = self.unidade_orcamentaria.tipo_de_unidade_administrativa.poder_associado
			veio_de_um_pagamento_com_retencao = self.pagamento_id.present? ? true : [false, nil]
			contapcasp_retencoes_e_consignacoes = conta_pcasp_de_retencoes_e_consignacoes(self.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.last.conta) rescue false

			if !self.conta_extra_orcamentaria.present?
				eventos_ddr = Contabilidade::EventoContabil.left_outer_joins( :configuracao_do_evento_contabil ).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:ddr],
						orcamento_id: orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:talao_de_receita_ddr]],
						tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_fontes], nil],
						tipo_de_poder: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_poder[tipo_de_poder], nil],
						extraorcamentario: [self.extra_orcamentario?, nil],
						vem_de_pagamento_com_retencao: [veio_de_um_pagamento_com_retencao],
						retencao: [contapcasp_retencoes_e_consignacoes, nil],
						consignacao: [contapcasp_retencoes_e_consignacoes, nil]
					}
				)
			end
			if conta_extra_orcamentaria.present? && (conta_bancaria.present? || veio_de_um_pagamento_com_retencao)
				
				tipo_de_conta_pcasp_do_talao_extra = self.conta_extra_orcamentaria.classe_pcasp == "passivo" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo]
				contapcasp_deposito = conta_pcasp_de_deposito( self.conta_extra_orcamentaria.conta) rescue nil
				#pagamento = veio_de_um_pagamento_com_retencao ? true : nil

				eventos_conta_extra_ddr = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where({
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:ddr],
						orcamento_id: orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:talao_de_receita_ddr]],
						extraorcamentario: self.extra_orcamentario?,
						tipo_de_conta_pcasp: [tipo_de_conta_pcasp_do_talao_extra, nil],
						vem_de_pagamento_com_retencao: [veio_de_um_pagamento_com_retencao],
						retencao: [contapcasp_retencoes_e_consignacoes, nil],
						deposito: [contapcasp_deposito, nil]
					}
				})
			end

			if self.natureza_da_receita.present?
				talao_eh_reducao = self.natureza_da_receita.categoria_economica == "009"
				conta_pcasp_da_conta_bancaria_ids = conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.pluck(:conta_id) rescue nil
				classificacao_da_receita = nil

				alinea = talao_eh_reducao && self.natureza_da_receita.alinea[0].to_i > 0 ? "#{self.natureza_da_receita.alinea[0]}0" : nil
				nivel_opcional_1 = talao_eh_reducao && self.natureza_da_receita.nivel_opcional_1[1].to_i == 1 ? "01" : nil # retirar após correção das receitas de dedução

				if natureza_da_receita.categoria_economica == '001' && natureza_da_receita.detalhamento_optativo == '3'
					divida = natureza_da_receita.origem == '1' ? :divida_ativa : :divida_ativa_nao_tributaria
					classificacao_da_receita = Contabilidade::ConfiguracaoDoEventoContabil.classificacoes_da_receita[divida]
				end

				eventos_inclusivos_de_receita = Contabilidade::EventoContabil.left_outer_joins(configuracao_do_evento_contabil: [:naturezas_da_receita_da_configuracao_contabil]).where(
					contabilidade_eventos_contabeis:{
						modelo: Contabilidade::EventoContabil.modelos[:ddr],
						orcamento_id: orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:talao_de_receita_ddr]],
						tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_receitas]]
					},
					contabilidade_naturezas_da_receita_da_configuracao_contabil: {
						categoria_economica: [natureza_da_receita.categoria_economica, '000', nil ],
						origem: [natureza_da_receita.origem, '0',nil],
						especie: [natureza_da_receita.especie, '0', nil],
						rubrica: [natureza_da_receita.rubrica, '0', nil],
						alinea: [natureza_da_receita.alinea, '00', alinea, nil],
						subalinea: [natureza_da_receita.subalinea, '0', nil],
						detalhamento_optativo: [natureza_da_receita.detalhamento_optativo, '0', nil],
						nivel_opcional_1: [natureza_da_receita.nivel_opcional_1, '00', nivel_opcional_1, nil],
						nivel_opcional_2: [natureza_da_receita.nivel_opcional_2, '00', nil],
						nivel_opcional_3: [natureza_da_receita.nivel_opcional_3, '00', nil]
					}
				).where(
					'
					(contabilidade_naturezas_da_receita_da_configuracao_contabil.categoria_economica_exclusora = ? 
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.categoria_economica_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.origem_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.origem_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.especie_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.especie_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.rubrica_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.rubrica_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.alinea_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.alinea_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.subalinea_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.subalinea_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.detalhamento_optativo_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.detalhamento_optativo_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_1_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_1_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_2_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_2_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_3_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_3_exclusora IS NULL)',
					natureza_da_receita.categoria_economica, natureza_da_receita.origem, natureza_da_receita.especie, natureza_da_receita.rubrica,
					natureza_da_receita.alinea, natureza_da_receita.subalinea, natureza_da_receita.detalhamento_optativo, natureza_da_receita.nivel_opcional_1, 
					natureza_da_receita.nivel_opcional_2, natureza_da_receita.nivel_opcional_3
				)
			end

			return (eventos_ddr + eventos_conta_extra_ddr + eventos_inclusivos_de_receita).uniq
		end

		def busca_eventos_da_anulacao_do_talao_de_receita_ddr
			eventos_inclusivos_de_receita = Array.new
			eventos_conta_extra_ddr = Array.new
			eventos_ddr = Array.new

			tipo_de_poder = self.talao_de_receita.unidade_orcamentaria.tipo_de_unidade_administrativa.poder_associado
			veio_de_um_pagamento_com_retencao = self.talao_de_receita.pagamento_id.present? ? true : [false, nil]
			contapcasp_retencoes_e_consignacoes = self.talao_de_receita.conta_pcasp_de_retencoes_e_consignacoes(self.talao_de_receita.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.last.conta) rescue false
			
			if !self.talao_de_receita.conta_extra_orcamentaria.present?
				eventos_ddr = Contabilidade::EventoContabil.left_outer_joins( :configuracao_do_evento_contabil ).where(
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:ddr],
						orcamento_id: self.talao_de_receita.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:anulacao_do_talao_de_receita_ddr]],
						tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_fontes], nil],
						tipo_de_poder: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_poder[tipo_de_poder], nil],
						extraorcamentario: [self.talao_de_receita.extra_orcamentario?, nil],
						vem_de_pagamento_com_retencao: [veio_de_um_pagamento_com_retencao],
						retencao: [contapcasp_retencoes_e_consignacoes, nil],
						consignacao: [contapcasp_retencoes_e_consignacoes, nil]
					}
				)
			end

			if self.talao_de_receita.conta_extra_orcamentaria.present? && (self.talao_de_receita.conta_bancaria.present? || veio_de_um_pagamento_com_retencao)
				
				tipo_de_conta_pcasp_do_talao_extra = self.talao_de_receita.conta_extra_orcamentaria.classe_pcasp == "passivo" ? Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:passivo] : Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_conta_pcasp[:ativo]
				contapcasp_deposito = self.talao_de_receita.conta_pcasp_de_deposito( self.talao_de_receita.conta_extra_orcamentaria.conta) rescue nil
				#pagamento = veio_de_um_pagamento_com_retencao ? true : nil

				eventos_conta_extra_ddr = Contabilidade::EventoContabil.joins(:configuracao_do_evento_contabil).where({
					contabilidade_eventos_contabeis: {
						modelo: Contabilidade::EventoContabil.modelos[:ddr],
						orcamento_id: self.talao_de_receita.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:anulacao_do_talao_de_receita_ddr]],
						extraorcamentario: self.talao_de_receita.extra_orcamentario?,
						tipo_de_conta_pcasp: [tipo_de_conta_pcasp_do_talao_extra, nil],
						retencao: [contapcasp_retencoes_e_consignacoes, nil],
						deposito: [contapcasp_deposito, nil]
					}
				})
			end

			if self.talao_de_receita.natureza_da_receita.present?
				talao_eh_reducao = self.talao_de_receita.natureza_da_receita.categoria_economica == "009"
				conta_pcasp_da_conta_bancaria_ids = self.talao_de_receita.conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.pluck(:conta_id) rescue nil
				classificacao_da_receita = nil

				alinea = talao_eh_reducao && self.talao_de_receita.natureza_da_receita.alinea[0].to_i > 0 ? "#{self.talao_de_receita.natureza_da_receita.alinea[0]}0" : nil
				nivel_opcional_1 = talao_eh_reducao && self.talao_de_receita.natureza_da_receita.nivel_opcional_1[1].to_i == 1 ? "01" : nil # retirar após correção das receitas de dedução

				if self.talao_de_receita.natureza_da_receita.categoria_economica == '001' && self.talao_de_receita.natureza_da_receita.detalhamento_optativo == '3'
					divida = self.talao_de_receita.natureza_da_receita.origem == '1' ? :divida_ativa : :divida_ativa_nao_tributaria
					classificacao_da_receita = Contabilidade::ConfiguracaoDoEventoContabil.classificacoes_da_receita[divida]
				end

				eventos_inclusivos_de_receita = Contabilidade::EventoContabil.left_outer_joins(configuracao_do_evento_contabil: [:naturezas_da_receita_da_configuracao_contabil]).where(
					contabilidade_eventos_contabeis:{
						modelo: Contabilidade::EventoContabil.modelos[:ddr],
						orcamento_id: self.talao_de_receita.orcamento_id
					},
					contabilidade_configuracoes_do_evento_contabil: {
						tipo_ddr: [ Contabilidade::ConfiguracaoDoEventoContabil.tipos_ddr[:anulacao_do_talao_de_receita_ddr]],
						tipo_de_evento: [Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_evento[:inclusivo_de_receitas]]
					},
					contabilidade_naturezas_da_receita_da_configuracao_contabil: {
						categoria_economica: [self.talao_de_receita.natureza_da_receita.categoria_economica, '000', nil ],
						origem: [self.talao_de_receita.natureza_da_receita.origem, '0',nil],
						especie: [self.talao_de_receita.natureza_da_receita.especie, '0', nil],
						rubrica: [self.talao_de_receita.natureza_da_receita.rubrica, '0', nil],
						alinea: [self.talao_de_receita.natureza_da_receita.alinea, '00', alinea, nil],
						subalinea: [self.talao_de_receita.natureza_da_receita.subalinea, '0', nil],
						detalhamento_optativo: [self.talao_de_receita.natureza_da_receita.detalhamento_optativo, '0', nil],
						nivel_opcional_1: [self.talao_de_receita.natureza_da_receita.nivel_opcional_1, '00', nivel_opcional_1, nil],
						nivel_opcional_2: [self.talao_de_receita.natureza_da_receita.nivel_opcional_2, '00', nil],
						nivel_opcional_3: [self.talao_de_receita.natureza_da_receita.nivel_opcional_3, '00', nil]
					}
				).where(
					'
					(contabilidade_naturezas_da_receita_da_configuracao_contabil.categoria_economica_exclusora = ? 
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.categoria_economica_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.origem_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.origem_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.especie_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.especie_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.rubrica_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.rubrica_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.alinea_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.alinea_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.subalinea_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.subalinea_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.detalhamento_optativo_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.detalhamento_optativo_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_1_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_1_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_2_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_2_exclusora IS NULL)

					AND (contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_3_exclusora = ?
					OR contabilidade_naturezas_da_receita_da_configuracao_contabil.nivel_opcional_3_exclusora IS NULL)',
					self.talao_de_receita.natureza_da_receita.categoria_economica, self.talao_de_receita.natureza_da_receita.origem, self.talao_de_receita.natureza_da_receita.especie, self.talao_de_receita.natureza_da_receita.rubrica,
					self.talao_de_receita.natureza_da_receita.alinea, self.talao_de_receita.natureza_da_receita.subalinea, self.talao_de_receita.natureza_da_receita.detalhamento_optativo, self.talao_de_receita.natureza_da_receita.nivel_opcional_1, 
					self.talao_de_receita.natureza_da_receita.nivel_opcional_2, self.talao_de_receita.natureza_da_receita.nivel_opcional_3
				)
			end

			return (eventos_ddr + eventos_conta_extra_ddr + eventos_inclusivos_de_receita).uniq
		end

		def define_tipo_de_alteracao_no_saldo(saldo_atual, saldo_antigo)
			saldo_atual > saldo_antigo ? :acrescimo : :decrescimo
		end

		def faz_movimentacoes_validas?
			permissao = Configuracao.last.permite_saldo_das_contas_do_plano_de_contas_vire
			return permissao || movimentacoes_sao_validas?
		end

		def cria_eventos_contabeis_por_gerador
			self.eventos_contabeis_por_gerador.delete_all

			eventos_contabeis_por_gerador.find_or_create_by(evento_contabil_id: evento_contabil_padrao.id) if !self.evento_contabil_padrao.nil?

			unless @eventos_contabeis_por_objeto.nil?
				@eventos_contabeis_por_objeto.each do |evento_contabil|
					if self.persisted?
						if !evento_contabil.nil? && eventos_contabeis_por_gerador.find_by(evento_contabil_id: evento_contabil.id).nil?
							evento = eventos_contabeis_por_gerador.new(evento_contabil_id: evento_contabil.id, evento_ddr: false)
						end
					else
						evento = eventos_contabeis_por_gerador.new(evento_contabil_id: evento_contabil.id, evento_ddr: false)
					end
				end
			end
			
			# unless @eventos_ddr
			# 	@eventos_ddr.each do |evento_contabil|
			# 		if self.persisted?
			# 			if !evento_contabil.nil? && eventos_contabeis_por_gerador.find_by(evento_contabil_id: evento_contabil.id).nil?
			# 				evento = eventos_contabeis_por_gerador.new(evento_contabil_id: evento_contabil.id, evento_ddr: true)
			# 			end
			# 		else
			# 			evento = eventos_contabeis_por_gerador.new(evento_contabil_id: evento_contabil.id, evento_ddr: true)
			# 		end
			# 	end
			# end
		end

		def atributo_saldo_eh_valido?
			if self.class.name == "Projecao::CalculoPorExercicio" || self.class.name == "Ppa::ProjecaoDeDespesa" || self.class.name == "Loa::OrcamentoDaDespesa"
				return self.try(:total_changed?) || self.try(:valor_changed?)
			else
				return true
			end
		end

		def movimentacao_pode_ter_valores_repetidos?
			self.class.name == "Projecao::CalculoPorExercicio" && self.class.name == "Ppa::ProjecaoDeDespesa" &&
			self.class.name == "Loa::OrcamentoDaDespesa"
		end

		def define_tipo_de_movimentacao(orcamento_atual = nil)
			if contexto_atual.present?
				@orcamento_atual = contexto_atual
			else
				@orcamento_atual = orcamento_atual
			end

			if self.class.name == "Contabilidade::TransferenciaFinanceira"
				gera_movimentacao_de_transferencia(eventos_de_transferencia)
				gera_movimentacao(eventos_regulares)
			elsif self.class.name == "Contabilidade::Pagamento"
				gera_movimentacao(eventos_regulares)
				gera_movimentacao_pagamento_por_conta_bancaria(eventos_de_pagamento_com_conta_bancaria)
			else
				gera_movimentacao(eventos_regulares, @orcamento_atual)
			end

			#gerando movimentos DDR
			gera_movimentacao_ddr(eventos_regulares_ddr)
		end

		def eventos_regulares
			eventos_contabeis_por_gerador.select { |evento_contabil_por_gerador| evento_contabil_por_gerador.evento_contabil.present? && evento_contabil_por_gerador.evento_contabil.orcamento? == false && evento_contabil_por_gerador.evento_de_pagamento_com_conta_bancaria? == false && evento_contabil_por_gerador.evento_ddr == false }
		end

		def eventos_de_transferencia
			eventos_contabeis_por_gerador.select { |evento_contabil_por_gerador| evento_contabil_por_gerador.evento_contabil.present? && evento_contabil_por_gerador.evento_contabil.orcamento? && evento_contabil_por_gerador.evento_ddr == false }
		end

		def eventos_de_pagamento_com_conta_bancaria
			eventos_contabeis_por_gerador.select { |evento_contabil_por_gerador| evento_contabil_por_gerador.evento_de_pagamento_com_conta_bancaria? && evento_contabil_por_gerador.evento_ddr == false} rescue nil
		end

		def eventos_regulares_ddr
			eventos_contabeis_por_gerador.select { |evento_contabil_por_gerador| evento_contabil_por_gerador.evento_contabil.present? && evento_contabil_por_gerador.evento_ddr == true }
		end

		def gera_movimentacao(eventos_contabeis_por_gerador, orcamento_atual = nil)
			eventos_contabeis_por_gerador.each do |evento_contabil_por_gerador|
				evento_contabil = evento_contabil_por_gerador.evento_contabil
				if evento_contabil.present?
					valor_a_ser_movimentado = retorna_valor_por_evento(evento_contabil_por_gerador.evento_contabil, orcamento_atual)

					#lanca_tentativa_de_movimentacao(evento_contabil_por_gerador.evento_contabil, valor_a_ser_movimentado) Está regra pode voltar no futuro
					contas_por_eventos_contabeis_para_movimentacao(evento_contabil_por_gerador).each do |conta|
						movimentacao = busca_movimentacao_por_conta(evento_contabil, conta)
						configuracao_do_evento_contabil = evento_contabil.configuracao_do_evento_contabil
						if valor_a_ser_movimentado.to_d > 0 && evento_permimte_ser_ativado?(configuracao_do_evento_contabil, evento_contabil)
							# if ( self.movimentacao_pode_ter_valores_repetidos? && self.atributo_saldo_eh_valido? ) || movimentacao.try(:valor) != valor_a_ser_movimentado
							# 	cria_movimentacao(conta, valor_a_ser_movimentado)
							# end
							# if self.movimentacao_pode_ter_valores_repetidos? == false && valor_a_ser_movimentado != movimentacao.try(:valor)
							# 	movimentacao.try(:destroy)
							# end
							if self.atributo_saldo_eh_valido? || movimentacao.try(:valor) != valor_a_ser_movimentado
								if evento_contabil.configuracao_do_evento_contabil.ativar_pela_subconta?
									if self.class.name == "Contabilidade::TalaoDeReceita" && self.orcamentario? && conta.conta.informacao_complementar_possui_fonte_de_recursos?
										if self.complementos_por_fonte_do_talao_de_receita.where("valor != 0").any?
											self.complementos_por_fonte_do_talao_de_receita.where("valor != 0").each do |complemento|
												cria_movimentacao_com_subconta(conta, complemento.valor.to_d.abs, nil, complemento.orcamento_da_receita.fonte_de_recursos)
											end
										end
									elsif self.class.name == "Contabilidade::AnulacaoDoTalaoDeReceita" && self.talao_de_receita.orcamentario? && conta.conta.informacao_complementar_possui_fonte_de_recursos?
										if self.complementos_por_fonte_da_anulacao_do_talao.where("valor != 0").any?
											self.complementos_por_fonte_da_anulacao_do_talao.where("valor != 0").each do |complemento|
												cria_movimentacao_com_subconta(conta, complemento.valor.to_d.abs, nil, complemento.orcamento_da_receita.fonte_de_recursos)
											end
										end
									else
										cria_movimentacao_com_subconta(conta, valor_a_ser_movimentado, nil, nil)
									end
								else
									if self.class.name == "Contabilidade::SolicitacaoDeAlteracaoOrcamentaria"
										cria_movimentacao_alteracao_orcamentaria(conta, valor_a_ser_movimentado)
									elsif self.class.name == "Contabilidade::CancelamentoDeRestoAPagar"
										cria_movimentacao_cancelamento_de_restos_a_pagar(conta, valor_a_ser_movimentado)
									elsif self.class.name == "Contabilidade::TransferenciaFinanceira"
										evento_contabil.contas_por_eventos_contabeis.each do |conta_evento|
											cria_movimentacao(conta_evento, valor_a_ser_movimentado, nil, nil, nil, nil) if conta_evento == conta
										end
									elsif self.class.name == "Contabilidade::TalaoDeReceita" && self.orcamentario? && conta.conta.informacao_complementar_possui_fonte_de_recursos?
										if self.complementos_por_fonte_do_talao_de_receita.where("valor != 0").any?
											self.complementos_por_fonte_do_talao_de_receita.where("valor != 0").each do |complemento|
												cria_movimentacao(conta, complemento.valor.to_d.abs, nil, nil, complemento.orcamento_da_receita.fonte_de_recursos, nil)
											end
										end
									elsif self.class.name == "Contabilidade::AnulacaoDoTalaoDeReceita" && self.talao_de_receita.orcamentario? && conta.conta.informacao_complementar_possui_fonte_de_recursos?
										if self.complementos_por_fonte_da_anulacao_do_talao.where("valor != 0").any?
											self.complementos_por_fonte_da_anulacao_do_talao.where("valor != 0").each do |complemento|
												cria_movimentacao(conta, complemento.valor.to_d.abs, nil, nil, complemento.orcamento_da_receita.fonte_de_recursos, nil)
											end
										end
									else
										cria_movimentacao(conta, valor_a_ser_movimentado, nil, nil, nil, nil)
									end
								end
							end
							if valor_a_ser_movimentado != movimentacao.try(:valor)
								movimentacao.try(:destroy)
							end
						end
					end
				end
			end
		end

		def gera_movimentacao_de_transferencia(eventos_contabeis_por_gerador)
			eventos_contabeis_por_gerador.each do |evento_contabil_por_gerador|
				evento_contabil = evento_contabil_por_gerador.evento_contabil
				if evento_contabil.present?
					evento_contabil.contas_por_eventos_contabeis.debito.each do |conta_debito|
						movimentacoes_por_unidade = Contabilidade::MovimentacaoDoPlanoDeContas.joins(:conta_por_evento_contabil).where(
							contabilidade_contas_por_eventos_contabeis: { conta_id: conta_debito.try(:id) }
						).group_by { |movimentacao| movimentacao.unidade_orcamentaria }
						conta_credito = conta_debito.conta_par
						movimentacoes_por_unidade.each do |unidade, movimentacoes|
							cria_transferencia([conta_debito.conta, conta_credito], movimentacoes.sum(&:valor), unidade)
						end
					end
				end
			end
		end

		def gera_movimentacao_pagamento_por_conta_bancaria(eventos_contabeis_por_gerador)
			contas_bancarias_ids = contas_bancarias_por_pagamento.map {|cbp| cbp.conta_bancaria_id }
			eventos_contabeis_por_gerador.each do |evento_contabil_por_gerador|
				evento_contabil = evento_contabil_por_gerador.evento_contabil

				if evento_contabil.present?
					configuracao_do_evento_contabil = evento_contabil.configuracao_do_evento_contabil
					conta_pcasp_id = configuracao_do_evento_contabil.conta_pcasp_da_conta_bancaria_id

					evento_contabil.contas_por_eventos_contabeis.each do |conta|
						Base::ContaBancaria.joins(:contas_pcasp_da_conta_bancaria_por_orcamento).where(
							base_contas_bancarias: {id: contas_bancarias_ids },
							contabilidade_contas_pcasp_da_conta_bancaria_por_orcamento: { conta_id: conta_pcasp_id }
						).each do |conta_bancaria|
							movimentacao = busca_movimentacao_por_conta_pcasp_e_bancaria(evento_contabil, conta, conta_bancaria)
							valor_a_ser_movimentado = retorna_valor_por_evento(evento_contabil)
							if valor_a_ser_movimentado > 0 && evento_permimte_ser_ativado?(configuracao_do_evento_contabil, evento_contabil)
								if ( movimentacao_pode_ter_valores_repetidos? && atributo_saldo_eh_valido? ) || movimentacao.try(:valor) != valor_a_ser_movimentado
									cria_movimentacao(conta, valor_a_ser_movimentado, unidade_orcamentaria, nil, nil, conta_bancaria)
								end

								if movimentacao_pode_ter_valores_repetidos? == false && valor_a_ser_movimentado != movimentacao.try(:valor)
									movimentacao.try(:destroy)
								end 
							end
						end
					end
				end
			end
		end

		def gera_movimentacao_ddr(eventos_contabeis_por_gerador)
			eventos_contabeis_por_gerador.each do |evento_contabil_por_gerador|
				evento_contabil = evento_contabil_por_gerador.evento_contabil
				if evento_contabil.present?
					valor_a_ser_movimentado = retorna_valor_por_evento_ddr(evento_contabil_por_gerador.evento_contabil)

					contas_por_eventos_contabeis_para_movimentacao(evento_contabil_por_gerador).each do |conta|
						movimentacao = busca_movimentacao_por_conta(evento_contabil, conta)
						configuracao_do_evento_contabil = evento_contabil.configuracao_do_evento_contabil
						if valor_a_ser_movimentado.to_d > 0 && evento_permimte_ser_ativado?(configuracao_do_evento_contabil, evento_contabil)
							if self.atributo_saldo_eh_valido? || movimentacao.try(:valor) != valor_a_ser_movimentado
								if self.class.name == "Contabilidade::TalaoDeReceita"
									if self.complementos_por_fonte_do_talao_de_receita.any?
										self.complementos_por_fonte_do_talao_de_receita.each do |complemento|
											if (complemento.orcamento_da_receita.fonte_de_recursos.fonte_vinculada == evento_contabil.configuracao_do_evento_contabil.fonte_vinculada) || (evento_contabil.configuracao_do_evento_contabil.fonte_vinculada.nil?)
												valor_da_fonte = complemento.valor.abs.to_d
												cria_movimentacao_ddr(conta, valor_da_fonte, complemento.fonte_de_recursos.id)
											end
										end
									else
										cria_movimentacao_ddr(conta, valor_a_ser_movimentado, nil)
									end
								elsif self.class.name == "Contabilidade::AnulacaoDoTalaoDeReceita"
									if self.talao_de_receita.complementos_por_fonte_do_talao_de_receita.any?
										self.talao_de_receita.complementos_por_fonte_do_talao_de_receita.each do |complemento|
											if (complemento.orcamento_da_receita.fonte_de_recursos.fonte_vinculada == evento_contabil.configuracao_do_evento_contabil.fonte_vinculada) || (evento_contabil.configuracao_do_evento_contabil.fonte_vinculada.nil?)
												valor_da_fonte = complemento.valor.abs.to_d
												cria_movimentacao_ddr(conta, valor_da_fonte, complemento.fonte_de_recursos.id)
											end
										end
									else
										cria_movimentacao_ddr(conta, valor_a_ser_movimentado, nil)
									end
								else
									cria_movimentacao_ddr(conta, valor_a_ser_movimentado, nil)
								end
							end
							if valor_a_ser_movimentado != movimentacao.try(:valor)
								movimentacao.try(:destroy)
							end
						end
					end
				end
			end
		end

		def saldo_por_conta_bancaria(conta_bancaria_id)
			contas_bancarias_por_pagamento.detect { |cbp| cbp.conta_bancaria_id == conta_bancaria_id }.try(:valor_pago).to_d
		end

		def cria_transferencia(contas, saldo, unidade)
			contas.each do |conta|
				cria_movimentacao(conta, saldo, unidade)
			end
		end

		def evento_permimte_ser_ativado?(configuracao_do_evento_contabil, evento)
			( configuracao_do_evento_contabil.ativa_apenas_uma_vez? && evento.movimentacoes_do_plano_de_contas.empty? ) || configuracao_do_evento_contabil.ativa_apenas_uma_vez? == false
		end

		def busca_movimentacao_por_conta(evento_contabil, conta)
			evento_contabil.movimentacoes_do_plano_de_contas.find_by(conta_por_evento_contabil_id: conta.id, gerador_type: self.class.name, gerador_id: id) 
			#|| Contabilidade::MovimentacaoDoPlanoDeContas.select { |m| m.conta_por_evento_contabil_id == conta.id }.last
		end

		def busca_movimentacao_por_conta_pcasp_e_bancaria(evento_contabil, conta_id, conta_bancaria_id)
			return  movimentacoes_do_plano_de_contas.detect { |m| m.conta_por_evento_contabil_id == conta_id && conta_bancaria_id == conta_bancaria_id } if new_record?

			evento_contabil.movimentacoes_do_plano_de_contas.find_by(
				conta_por_evento_contabil_id: conta_id,
				gerador_id: id,
				gerador_type: self.class.name,
				conta_bancaria_id: conta_bancaria_id
			)
		end

		# esse método foi criado pois existem alguns eventos que possuem mais de um par de contas e existem algumas regras específicas
		# que o lançamento só deve ser feito em alguns par(res) de conta de um determinado evento
		def contas_por_eventos_contabeis_para_movimentacao evento_contabil_por_gerador
			evento_contabil = evento_contabil_por_gerador.evento_contabil
			gerador = evento_contabil_por_gerador.gerador
			if ((evento_contabil_por_gerador.gerador_type == "GestaoDeEstoque::RecebimentoDeMaterial" && evento_contabil.retencoes_e_registros_de_obrigacoes?) || (evento_contabil_por_gerador.gerador_type == "Contabilidade::Liquidacao" && evento_contabil.apropriacoes_de_vpd?)) && evento_contabil.automatico?
				if gerador.empenho.ordinario?
					evento_contabil.contas_por_eventos_contabeis.select{|cpec| cpec.conta.codigo == "213110101" || cpec.conta_par.codigo == "213110101"}
				else
					evento_contabil.contas_por_eventos_contabeis.select{|cpec| cpec.conta.codigo == "213110102" || cpec.conta_par.codigo == "213110102"}
				end
			else
				evento_contabil.contas_por_eventos_contabeis
			end
		end

		def preencher_data(data)
			@atributo_data = data
		end

		def cria_movimentacao(conta, valor, unidade = nil, data_do_lancamento = nil, fonte = nil, conta_bancaria = nil)
			if conta.evento_contabil.configuracao_do_evento_contabil.abertura?				
				if self.respond_to?(:restos_a_pagar) && self.restos_a_pagar == true
					data_de_lancamento = primeiro_dia_util_do_ano(conta.evento_contabil.orcamento)
				else
					data_de_lancamento = primeiro_dia_util_do_ano
				end
			else
				data_de_lancamento = retornar_data_do_lancamento_por_objeto(conta.evento_contabil)
			end
			data_de_lancamento = Date.today if data_de_lancamento.nil?
			codigo_movimentacao = self.send(@atributo_codigo_movimentacao) if @atributo_codigo_movimentacao.present?

			unidade_orcamentaria_gerador = retorna_unidade_orcamentaria_por_objeto(conta.evento_contabil)
			if conta.try(:conta).try(:informacao_complementar_possui_fonte_de_recursos?)
				fontes_de_recursos_id_gerador = fonte.present? ? fonte.id : retorna_fontes_de_recursos_id_por_objeto(conta.evento_contabil)
			end

			if conta.credito? && self.class.name == "Contabilidade::TransferenciaFinanceira"
				fontes_de_recursos_id_gerador = self.fonte_de_recurso_destino.id
			end

			if fontes_de_recursos_id_gerador.present?
				fonte_de_recurso = Base::FonteDeRecursos.find(fontes_de_recursos_id_gerador)
				ic_fr = fonte_de_recurso.codigo_completo.first(4)
				ic_co = fonte_de_recurso.codigo_completo[4..7] if fonte_de_recurso.codigo_completo[4..7].to_i != 0
			else
				ic_fr = nil
				ic_co = nil
			end

			#  PROCURAR FONTE DE RECURSOS DE RESTOS A PAGAR QUANDO NÃO ENCONTRADA NO EXERCICIO
			if self.class.name == "Contabilidade::Empenho" 
				if self.restos_a_pagar == true && (@contexto_atual.present? || contexto_atual.presente?)
					contexto_atual = @contexto_atual if contexto_atual.nil?
					unless self.existe_fonte_no_orcamento_atual?
						fonte_de_recurso = self.fonte_de_recursos_de_restos_a_pagar_do_orcamento_atual(contexto_atual)
						if fonte_de_recurso.present?
							fontes_de_recursos_id_gerador = fonte_de_recurso.id
							ic_fr = fonte_de_recurso.codigo_completo.first(4)
							ic_co = fonte_de_recurso.codigo_completo[4..7] if fonte_de_recurso.codigo_completo[4..7].to_i != 0
						end
					end
				end
			end

			if self.new_record?
				movimentacao = self.movimentacoes_do_plano_de_contas.build(
					conta_por_evento_contabil_id: conta.id,
					valor: valor,
					data_de_lancamento: data_de_lancamento.to_date,
					tipo_de_lancamento: conta.tipo_de_lancamento,
					codigo_movimentacao: codigo_movimentacao,
					unidade_orcamentaria: unidade_orcamentaria_gerador,
					conta_bancaria_id: retornar_conta_bancaria(conta),
					fonte_de_recursos_id: fontes_de_recursos_id_gerador,
					sub_conta_pcasp_id: retorna_sub_conta_por_elemento(conta),
					ic_fr: ic_fr,
					ic_co: ic_co
				)
			else
				movimentacao = self.movimentacoes_do_plano_de_contas.create!(
					conta_por_evento_contabil_id: conta.id,
					valor: valor,
					data_de_lancamento: data_de_lancamento.to_date,
					tipo_de_lancamento: conta.tipo_de_lancamento,
					codigo_movimentacao: codigo_movimentacao,
					unidade_orcamentaria: unidade_orcamentaria_gerador,
					conta_bancaria_id: retornar_conta_bancaria(conta),
					fonte_de_recursos_id: fontes_de_recursos_id_gerador,
					sub_conta_pcasp_id: retorna_sub_conta_por_elemento(conta),
					ic_fr: ic_fr,
					ic_co: ic_co
				)
			end

			return movimentacao
		end

		def cria_movimentacao_com_subconta(conta, valor, unidade = nil, fonte = nil)
			data_de_lancamento = retornar_data_do_lancamento_por_objeto
			codigo_movimentacao = self.send(@atributo_codigo_movimentacao) if @atributo_codigo_movimentacao.present?

			unidade_orcamentaria_gerador = retorna_unidade_orcamentaria_por_objeto(conta.evento_contabil)
			fontes_de_recursos_id_gerador = fonte.present? ? fonte : retorna_fontes_de_recursos_id_por_objeto(conta.evento_contabil)

			conta_bancaria_a_utilizar = nil
			if conta.conta.codigo[0..4] == '11111' || conta.conta_par.codigo[0..4] == '11111'
				conta_bancaria_a_utilizar = (conta_bancaria.try(:id) || conta_bancaria_por_classe.try(:id)) rescue nil
			end

			if self.new_record?
				movimentacao = self.movimentacoes_do_plano_de_contas.build(
					conta_por_evento_contabil_id: conta.id,
					valor: valor,
					data_de_lancamento: data_de_lancamento.to_date,
					tipo_de_lancamento: conta.tipo_de_lancamento,
					codigo_movimentacao: codigo_movimentacao,
					unidade_orcamentaria: unidade_orcamentaria_gerador,
					sub_conta_pcasp_id: retorna_sub_conta_por_model,
					conta_bancaria_id: conta_bancaria_a_utilizar,
					fonte_de_recursos_id: fontes_de_recursos_id_gerador,
					ic_fp: "1"
				)
			else
				movimentacao = self.movimentacoes_do_plano_de_contas.create!(
					conta_por_evento_contabil_id: conta.id,
					valor: valor,
					data_de_lancamento: data_de_lancamento.to_date,
					tipo_de_lancamento: conta.tipo_de_lancamento,
					codigo_movimentacao: codigo_movimentacao,
					unidade_orcamentaria: unidade_orcamentaria_gerador,
					sub_conta_pcasp_id: retorna_sub_conta_por_model,
					conta_bancaria_id: conta_bancaria_a_utilizar,
					fonte_de_recursos_id: fontes_de_recursos_id_gerador,
					ic_fp: "1"
				)
			end
			
			return movimentacao
		end

		def cria_movimentacao_alteracao_orcamentaria(conta, valor_a_ser_movimentado)
			if conta.evento_contabil.configuracao_do_evento_contabil.dotacao_acrescimo?
				self.orcamentos_da_despesa_destino.each do |orcamento_solicitacao|
					data_de_lancamento = retornar_data_do_lancamento_por_objeto
					codigo_movimentacao = self.send(@atributo_codigo_movimentacao) if @atributo_codigo_movimentacao.present?

					unidade_orcamentaria_gerador = orcamento_solicitacao.elemento_de_despesa_por_subacao.subacao.unidade_orcamentaria
					fontes_de_recursos_id_gerador = orcamento_solicitacao.fonte_de_recursos_id

					valor_na_dotacao = self.dotacoes_destino.where(dotacao_id: orcamento_solicitacao.id).sum(:valor).to_d

					if conta.conta.informacao_complementar.to_s.include?("fs")
						ic_fs = orcamento_solicitacao.subacao.funcao.codigo + orcamento_solicitacao.subacao.subfuncao.codigo rescue nil
					else
						ic_fs = nil
					end

					ic_co = orcamento_solicitacao.fonte_de_recursos.codigo_completo[4..7] unless orcamento_solicitacao.fonte_de_recursos.codigo_completo[4..7].to_i == 0

					if self.new_record?
						movimentacao = self.movimentacoes_do_plano_de_contas.build(
							conta_por_evento_contabil_id: conta.id,
							valor: valor_na_dotacao,
							data_de_lancamento: data_de_lancamento.to_date,
							tipo_de_lancamento: conta.tipo_de_lancamento,
							codigo_movimentacao: codigo_movimentacao,
							unidade_orcamentaria: unidade_orcamentaria_gerador,
							fonte_de_recursos_id: fontes_de_recursos_id_gerador,
							ic_fr: orcamento_solicitacao.fonte_de_recursos.codigo_completo.first(4),
							ic_co: ic_co,
							ic_nd: orcamento_solicitacao.elemento_de_despesa_por_subacao.elemento_de_despesa.codigo,
							ic_fs: ic_fs
						)
					else
						movimentacao = self.movimentacoes_do_plano_de_contas.create!(
							conta_por_evento_contabil_id: conta.id,
							valor: valor_na_dotacao,
							data_de_lancamento: data_de_lancamento.to_date,
							tipo_de_lancamento: conta.tipo_de_lancamento,
							codigo_movimentacao: codigo_movimentacao,
							unidade_orcamentaria: unidade_orcamentaria_gerador,
							fonte_de_recursos_id: fontes_de_recursos_id_gerador,
							ic_fr: orcamento_solicitacao.fonte_de_recursos.codigo_completo.first(4),
							ic_co: ic_co,
							ic_nd: orcamento_solicitacao.elemento_de_despesa_por_subacao.elemento_de_despesa.codigo,
							ic_fs: ic_fs
						)
					end
				end
			elsif !conta.evento_contabil.configuracao_do_evento_contabil.dotacao_acrescimo?
				self.orcamentos_da_despesa_origem.each do |orcamento_solicitacao|
					data_de_lancamento = retornar_data_do_lancamento_por_objeto
					codigo_movimentacao = self.send(@atributo_codigo_movimentacao) if @atributo_codigo_movimentacao.present?

					unidade_orcamentaria_gerador = orcamento_solicitacao.elemento_de_despesa_por_subacao.subacao.unidade_orcamentaria
					fontes_de_recursos_id_gerador = orcamento_solicitacao.fonte_de_recursos_id

					valor_na_dotacao = self.dotacoes_origem.where(dotacao_id: orcamento_solicitacao.id).sum(:valor).to_d

					if conta.conta.informacao_complementar.to_s.include?("fs")
						ic_fs = orcamento_solicitacao.subacao.funcao.codigo + orcamento_solicitacao.subacao.subfuncao.codigo rescue nil
					else
						ic_fs = nil
					end

					ic_co = orcamento_solicitacao.fonte_de_recursos.codigo_completo[4..7] unless orcamento_solicitacao.fonte_de_recursos.codigo_completo[4..7].to_i == 0

					if self.new_record?
						movimentacao = self.movimentacoes_do_plano_de_contas.build(
							conta_por_evento_contabil_id: conta.id,
							valor: valor_na_dotacao,
							data_de_lancamento: data_de_lancamento.to_date,
							tipo_de_lancamento: conta.tipo_de_lancamento,
							codigo_movimentacao: codigo_movimentacao,
							unidade_orcamentaria: unidade_orcamentaria_gerador,
							fonte_de_recursos_id: fontes_de_recursos_id_gerador,
							ic_fr: orcamento_solicitacao.fonte_de_recursos.codigo_completo.first(4),
							ic_co: ic_co,
							ic_nd: orcamento_solicitacao.elemento_de_despesa_por_subacao.elemento_de_despesa.codigo,
							ic_fs: ic_fs
						)
					else
						movimentacao = self.movimentacoes_do_plano_de_contas.create!(
							conta_por_evento_contabil_id: conta.id,
							valor: valor_na_dotacao,
							data_de_lancamento: data_de_lancamento.to_date,
							tipo_de_lancamento: conta.tipo_de_lancamento,
							codigo_movimentacao: codigo_movimentacao,
							unidade_orcamentaria: unidade_orcamentaria_gerador,
							fonte_de_recursos_id: fontes_de_recursos_id_gerador,
							ic_fr: orcamento_solicitacao.fonte_de_recursos.codigo_completo.first(4),
							ic_co: ic_co,
							ic_nd: orcamento_solicitacao.elemento_de_despesa_por_subacao.elemento_de_despesa.codigo,
							ic_fs: ic_fs
						)
					end
				end
			else
				cria_movimentacao(conta, valor_a_ser_movimentado)
			end
		end

		def cria_movimentacao_cancelamento_de_restos_a_pagar(conta, valor_a_ser_movimentado)
			self.restos_a_pagar_cancelados.each do |restos_a_pagar|
				data_de_lancamento = retornar_data_do_lancamento_por_objeto
				codigo_movimentacao = self.send(@atributo_codigo_movimentacao) if @atributo_codigo_movimentacao.present?

				orcamento_atual = contexto_atual || @contexto_atual
				unidade_orcamentaria_gerador = restos_a_pagar.empenho.unidade_orcamentaria_do_exercicio_atual(orcamento_atual)
				fontes_de_recursos_id_gerador = restos_a_pagar.empenho.orcamento_da_despesa.fonte_de_recursos_id
				campo_fs = restos_a_pagar.empenho.orcamento_da_despesa.subacao.funcao.codigo + restos_a_pagar.empenho.orcamento_da_despesa.subacao.subfuncao.codigo rescue nil

				valor_do_resto_a_pagar = restos_a_pagar.valor_cancelado.to_d

				ic_fs = conta.conta.informacao_complementar_possui_funcao_e_subfuncao? ? campo_fs : nil
				ic_nd = conta.conta.informacao_complementar_possui_natureza_da_despesa? ? restos_a_pagar.empenho.orcamento_da_despesa.elemento_de_despesa_por_subacao.elemento_de_despesa.codigo : nil
				ic_ai = conta.conta.informacao_complementar_possui_ano_de_restos_a_pagar? ? restos_a_pagar.empenho.orcamento.exercicio : nil
				if conta.conta.informacao_complementar_possui_fonte_de_recursos?
					fonte_de_recursos_id = fontes_de_recursos_id_gerador
					ic_fr = restos_a_pagar.empenho.orcamento_da_despesa.fonte_de_recursos.codigo_completo.first(4)
				else
					fonte_de_recursos_id = nil
					ic_fr = nil
				end
				if conta.conta.informacao_complementar_possui_complemento_de_fonte?
					ic_co = restos_a_pagar.empenho.orcamento_da_despesa.fonte_de_recursos.codigo_completo[4..7] unless restos_a_pagar.empenho.orcamento_da_despesa.fonte_de_recursos.codigo_completo[4..7].to_i == 0
				else
					ic_co = nil
				end
				if self.new_record?
					movimentacao = self.movimentacoes_do_plano_de_contas.build(
						conta_por_evento_contabil_id: conta.id,
						valor: valor_do_resto_a_pagar,
						data_de_lancamento: data_de_lancamento.to_date,
						tipo_de_lancamento: conta.tipo_de_lancamento,
						codigo_movimentacao: codigo_movimentacao,
						unidade_orcamentaria: unidade_orcamentaria_gerador,
						fonte_de_recursos_id: fonte_de_recursos_id,
						ic_fs: ic_fs,
						ic_fr: ic_fr,
						ic_co: ic_co,
						ic_nd: ic_nd,
						codigo_do_sub_elemento: restos_a_pagar.empenho&.sub_elemento_de_despesa&.codigo, 
						ic_ai: ic_ai
					)
				else
					movimentacao = self.movimentacoes_do_plano_de_contas.create!(
						conta_por_evento_contabil_id: conta.id,
						valor: valor_do_resto_a_pagar,
						data_de_lancamento: data_de_lancamento.to_date,
						tipo_de_lancamento: conta.tipo_de_lancamento,
						codigo_movimentacao: codigo_movimentacao,
						unidade_orcamentaria: unidade_orcamentaria_gerador,
						fonte_de_recursos_id: fonte_de_recursos_id,
						ic_fs: ic_fs,
						ic_fr: ic_fr,
						ic_co: ic_co,
						ic_nd: ic_nd,
						codigo_do_sub_elemento: restos_a_pagar.empenho&.sub_elemento_de_despesa&.codigo, 
						ic_ai: ic_ai
					)
				end
			end
		end

		def cria_movimentacao_ddr(conta, valor, fonte = nil)
			data_de_lancamento = retornar_data_do_lancamento_por_objeto
			codigo_movimentacao = self.send(@atributo_codigo_movimentacao) if @atributo_codigo_movimentacao.present?

			unidade_orcamentaria_gerador = retorna_unidade_orcamentaria_por_objeto(conta.evento_contabil)
			fontes_de_recursos_id_gerador = fonte.present? ? fonte : retorna_fontes_de_recursos_id_por_objeto(conta.evento_contabil)
			if fontes_de_recursos_id_gerador.present?
				fonte_de_recurso = Base::FonteDeRecursos.find(fontes_de_recursos_id_gerador)
				ic_fr = fonte_de_recurso.codigo_completo.first(4)
				ic_co = fonte_de_recurso.codigo_completo[4..7]
			else
				ic_fr = nil
				ic_co = nil
			end
			
			if self.new_record?
				movimentacao = self.movimentacoes_do_plano_de_contas.build(
					conta_por_evento_contabil_id: conta.id,
					valor: valor,
					data_de_lancamento: data_de_lancamento.to_date,
					tipo_de_lancamento: conta.tipo_de_lancamento,
					codigo_movimentacao: codigo_movimentacao,
					unidade_orcamentaria: unidade_orcamentaria_gerador,
					conta_bancaria_id: retornar_conta_bancaria(conta),
					fonte_de_recursos_id: fontes_de_recursos_id_gerador,
					ic_fr: ic_fr,
					ic_co: ic_co
				)
			else
				movimentacao = self.movimentacoes_do_plano_de_contas.create!(
					conta_por_evento_contabil_id: conta.id,
					valor: valor,
					data_de_lancamento: data_de_lancamento.to_date,
					tipo_de_lancamento: conta.tipo_de_lancamento,
					codigo_movimentacao: codigo_movimentacao,
					unidade_orcamentaria: unidade_orcamentaria_gerador,
					conta_bancaria_id: retornar_conta_bancaria(conta),
					fonte_de_recursos_id: fontes_de_recursos_id_gerador,
					ic_fr: ic_fr,
					ic_co: ic_co
				)
			end

			return movimentacao
		end


		def primeiro_dia_util_do_ano(orcamento_utilizado = nil)
			if orcamento_utilizado
				ano = orcamento_utilizado.exercicio
			else
				ano = retorna_ano_pro_model
			end

			primeiro_dia_do_ano = Date.new(ano, 1, 2)

			if primeiro_dia_do_ano.saturday?
				primeiro_dia_do_ano_util = primeiro_dia_do_ano + 2
			elsif primeiro_dia_do_ano.sunday?
				primeiro_dia_do_ano_util = primeiro_dia_do_ano + 1
			else
				primeiro_dia_do_ano_util = primeiro_dia_do_ano
			end
		end

		def retorna_ano_pro_model
			if self.class.name == "Contabilidade::Empenho"
				ano = self.orcamento.exercicio
			elsif self.class.name == "Loa::OrcamentoDaDespesa"
				ano = self.unidade_orcamentaria.orcamento.exercicio
			elsif self.class.name == "Loa::OrcamentoDaReceita"
				ano = self.unidade_orcamentaria_por_natureza_da_receita.unidade_orcamentaria.orcamento.exercicio
			end
		end

		def evento_contabil_semiautomatico
			eventos_contabeis_por_gerador.joins(:evento_contabil).where(contabilidade_eventos_contabeis: {tipo: Contabilidade::EventoContabil.tipos[:semi_automatico]}).first.try(:evento_contabil)
		end

		def retorna_sub_conta_por_model
			orcamento_atual = contexto_atual || @contexto_atual
			
			if self.class.name == "Contabilidade::Empenho"
				sub_conta_id = self.sub_conta_pcasp.sub_conta_do_contexto_atual(orcamento_atual).id rescue nil
			elsif self.class.name == "Contabilidade::AnulacaoDoEmpenho"
				sub_conta_id = self.empenho.sub_conta_pcasp.sub_conta_do_contexto_atual(orcamento_atual).id rescue nil
			elsif self.class.name == "Contabilidade::TalaoDeReceita"
				if self.operacao_de_credito.present?
					sub_conta_id = self.operacao_de_credito.sub_conta_pcasp.sub_conta_do_contexto_atual(orcamento_atual).id rescue nil
				else
					sub_conta_id = self.sub_conta_pcasp.sub_conta_do_contexto_atual(orcamento_atual).id rescue nil
				end
			elsif self.class.name == "Contabilidade::AnulacaoDoTalaoDeReceita"
				if self.talao_de_receita.operacao_de_credito.present?
					sub_conta_id = self.talao_de_receita.operacao_de_credito.sub_conta_pcasp.sub_conta_do_contexto_atual(orcamento_atual).id rescue nil
				else
					sub_conta_id = self.talao_de_receita.sub_conta_pcasp.sub_conta_do_contexto_atual(orcamento_atual).id rescue nil
				end
			elsif self.class.name == "Contabilidade::Pagamento"
				sub_conta_id = self.liquidacao.empenho.sub_conta_pcasp.sub_conta_do_contexto_atual(orcamento_atual).id rescue nil
			elsif self.class.name == "Contabilidade::EstornoDePagamento"
				sub_conta_id = self.pagamento.liquidacao.empenho.sub_conta_pcasp.sub_conta_do_contexto_atual(orcamento_atual).id rescue nil
			else
				sub_conta_id = nil
			end

			return sub_conta_id
		end

		def retorna_sub_conta_por_elemento(conta)
			orcamento_atual = contexto_atual || @contexto_atual
			sub_conta_id = nil

			if self.class.name == "Contabilidade::Liquidacao"
				if (self.empenho.reconhecido_na_liquidacao_da_despesa? || self.empenho.reconhecimento_no_exercicio_vigente? || self.empenho.reconhecimento_no_exercicio_anterior?) && conta.conta.grupo_de_conta.nome == "Patrimonial"
					sub_conta_id = self.empenho.sub_elemento_de_despesa.sub_conta_pcasp.sub_conta_do_contexto_atual(orcamento_atual).id rescue nil
				end
			elsif self.class.name == "Contabilidade::EstornoDeLiquidacao"
				if (self.liquidacao.empenho.reconhecido_na_liquidacao_da_despesa? || self.liquidacao.empenho.reconhecimento_no_exercicio_vigente? || self.liquidacao.empenho.reconhecimento_no_exercicio_anterior?) && conta.conta.grupo_de_conta.nome == "Patrimonial"
					sub_conta_id = self.liquidacao.empenho.sub_elemento_de_despesa.sub_conta_pcasp.sub_conta_do_contexto_atual(orcamento_atual).id rescue nil
				end
			elsif self.class.name == "Contabilidade::Pagamento"
				if conta.evento_contabil.configuracao_do_evento_contabil.ativar_pela_subconta?
					sub_conta_id = self.liquidacao.empenho.sub_conta_pcasp.sub_conta_do_contexto_atual(orcamento_atual).id rescue nil
				end
			elsif self.class.name == "Contabilidade::EstornoDePagamento"
				if conta.evento_contabil.configuracao_do_evento_contabil.ativar_pela_subconta?
					sub_conta_id = self.pagamento.liquidacao.empenho.sub_conta_pcasp.sub_conta_do_contexto_atual(orcamento_atual).id rescue nil
				end
			end

			return sub_conta_id
		end

		def retorna_unidade_orcamentaria_por_objeto(evento_contabil = nil)
			orcamento_atual = contexto_atual || @contexto_atual
			case self.class.name
			when "Contabilidade::Empenho"
				if self.restos_a_pagar == true
					unidade_orcamentaria = self.unidade_orcamentaria_do_exercicio_atual(orcamento_atual)
				else
					unidade_orcamentaria = self.unidade_orcamentaria
				end		
			when "Contabilidade::AnulacaoDoEmpenho"
				unidade_orcamentaria = self.empenho.unidade_orcamentaria_do_exercicio_atual(orcamento_atual)
			when "Contabilidade::Liquidacao"
				unidade_orcamentaria = self.unidade_orcamentaria_do_exercicio_atual(orcamento_atual)
			when 'Contabilidade::EstornoDeLiquidacao'
				unidade_orcamentaria = self.liquidacao.unidade_orcamentaria_do_exercicio_atual(orcamento_atual)
			when "Contabilidade::Pagamento"
				unidade_orcamentaria = self.unidade_orcamentaria_atual
			when "Contabilidade::EstornoDePagamento"
				unidade_orcamentaria = self.pagamento.unidade_orcamentaria_atual
			when "GestaoDeEstoque::RecebimentoDeMaterial"
				unidade_orcamentaria = retorna_unidade_orcamentaria
			when "Loa::OrcamentoDaDespesa"
				unidade_orcamentaria = self.elemento_de_despesa_por_subacao.subacao.unidade_orcamentaria
			when "Contabilidade::TalaoDeReceita"
				unidade_orcamentaria = self.unidade_orcamentaria
			when 'Contabilidade::AnulacaoDoTalaoDeReceita'
				unidade_orcamentaria = self.talao_de_receita.unidade_orcamentaria
			when "Contabilidade::Obra"
				ids_unidades = self.empenhos.pluck(:unidade_orcamentaria_id).uniq
				unidades_orcamentarias_da_obra = Loa::UnidadeOrcamentaria.where("id in (?)", ids_unidades)
				unidade_orcamentaria = unidades_orcamentarias_da_obra.first
			when "Administrativo::RequisicaoDeMaterial"
				data_de_lancamento = self.data_da_requisicao
			when 'Contabilidade::DespesaExtraOrcamentaria'
				unidade_orcamentaria = self.unidade_orcamentaria
			when 'Contabilidade::EstornoDeDespesaExtraOrcamentaria'
				unidade_orcamentaria = self.despesa_extra_orcamentaria.unidade_orcamentaria
			when 'Contabilidade::BloqueioDeDotacao'
				unidade_orcamentaria = self.unidade_orcamentaria
			when 'Contabilidade::SolicitacaoDeAlteracaoOrcamentaria'
				unidade_orcamentaria = self.unidade_orcamentaria
			when 'Loa::OrcamentoDaReceita'
				unidade_orcamentaria = self.unidade_orcamentaria_por_natureza_da_receita.unidade_orcamentaria
			when 'Licitacao::Contrato'
				unidade_orcamentaria = self.unidade_orcamentaria_do_exercicio
			when 'Licitacao::Aditivo'
				unidade_orcamentaria = nova_unidade_orcamentaria? ? unidade_orcamentaria : contrato.unidade_orcamentaria_atual
			when 'Contabilidade::MedicaoDaObra'
				ids_unidades = self.obra.empenhos.pluck(:unidade_orcamentaria_id).uniq
				unidades_orcamentarias_da_obra = Loa::UnidadeOrcamentaria.where("id in (?)", ids_unidades)
				unidade_orcamentaria = unidades_orcamentarias_da_obra.first
			when 'Contabilidade::TransferenciaFinanceira'
				if evento_contabil.configuracao_do_evento_contabil.ug_diferente?
					if evento_contabil.configuracao_do_evento_contabil.origem?
						unidade_orcamentaria = self.conta_bancaria_origem.unidade_orcamentaria
					else
						unidade_orcamentaria = self.conta_bancaria_destino.unidade_orcamentaria
					end
				else
					unidade_orcamentaria = self.conta_bancaria_origem.unidade_orcamentaria
				end
			when 'GestaoDeEstoque::ItemDoConsumo'
				unidade_orcamentaria = self.estoque.unidade_orcamentaria
			else
				unidade_orcamentaria = defined?(unidade_orcamentaria).nil? ? nil : self.unidade_orcamentaria
			end

			return unidade_orcamentaria.try(:class).try(:name) == "Loa::UnidadeOrcamentaria" ? unidade_orcamentaria : nil
		end

		def retornar_data_do_lancamento_por_objeto(evento_contabil = nil)
			data_de_lancamento = nil
			
			case self.class.name
			when "Contabilidade::Empenho"
				data_de_lancamento = self.data_do_empenho || self.data_de_solicitacao
			when "Contabilidade::Liquidacao"
				data_de_lancamento = self.data_da_liquidacao || self.data_de_solicitacao
			when "Contabilidade::Pagamento"
				data_de_lancamento = self.data || self.data_da_solicitacao
			when "Contabilidade::EstornoDePagamento"
				data_de_lancamento = self.data_do_estorno
			when "GestaoDeEstoque::RecebimentoDeMaterial"
				data_de_lancamento = self.data_do_recebimento
			when "Loa::OrcamentoDaDespesa"
				data_de_lancamento = primeiro_dia_util_do_ano
			when "Contabilidade::TalaoDeReceita"
				data_de_lancamento = self.data_do_talao
			when 'Contabilidade::AnulacaoDoTalaoDeReceita'
				data_de_lancamento = self.data_da_anulacao
			when "Contabilidade::MedicaoDaObra"
				data_de_lancamento = self.data_inicial
			when "Contabilidade::AnulacaoDoEmpenho"
				data_de_lancamento = self.data_da_anulacao
			when "Contabilidade::Obra"
				data_de_lancamento = self.data_de_inicio
			when "Administrativo::RequisicaoDeMaterial"
				data_de_lancamento = self.data_da_requisicao
			when 'Contabilidade::DespesaExtraOrcamentaria'
				data_de_lancamento = self.data_de_emissao
			when 'Contabilidade::EstornoDeDespesaExtraOrcamentaria'
				data_de_lancamento = self.data_do_estorno
			when 'Contabilidade::EstornoDeLiquidacao'
				data_de_lancamento = self.data_do_estorno
			when 'Contabilidade::BloqueioDeDotacao'
				if evento_contabil.configuracao_do_evento_contabil.status == "desbloqueado"
					data_de_lancamento = self.data_do_desbloqueio
				else
					data_de_lancamento = self.data_do_bloqueio
				end
			when 'Contabilidade::SolicitacaoDeAlteracaoOrcamentaria'
				data_de_lancamento = self.data_da_solicitacao || self.data_da_legislacao
			when 'Loa::OrcamentoDaReceita'
				data_de_lancamento = primeiro_dia_util_do_ano
			when 'Licitacao::Contrato'
				data_de_lancamento = self.data_do_contrato || self.data_da_solicitacao
			when 'Licitacao::Aditivo'
				data_de_lancamento = self.data_do_aditivo || self.data_de_solicitacao
			when 'Contabilidade::TransferenciaFinanceira'
				data_de_lancamento = self.data
			when 'Contabilidade::CancelamentoDeRestoAPagar'
				data_de_lancamento = self.data
			else
				data_de_lancamento = Date.today
			end
			
			return data_de_lancamento
		end

		def retorna_fontes_de_recursos_id_por_objeto(evento_contabil = nil)
			fonte_id = nil
			if self.class.name == "Contabilidade::TalaoDeReceita"
				if self.extra_orcamentario?
					fonte_id = self.fonte_de_recursos_id
				else
					fonte_id = self.fonte_de_recursos_id
					if evento_contabil.configuracao_do_evento_contabil.inclusivo_de_fontes?
						if self.complementos_por_fonte_do_talao_de_receita.map{ |a| a.orcamento_da_receita.fonte_de_recursos_id }.compact.size > 0
							fontes_do_evento = evento_contabil.configuracao_do_evento_contabil.fontes_da_configuracao_contabil.pluck(:fonte_de_recursos_id)

							self.complementos_por_fonte_do_talao_de_receita.each do |complemento|
								if fontes_do_evento.include?(complemento.orcamento_da_receita.fonte_de_recursos_id)
									fonte_id = complemento.orcamento_da_receita.fonte_de_recursos_id
								end
							end
						else
							fonte_id = nil
						end
					else
						fonte_id = nil
					end
				end
			elsif self.class.name == "Contabilidade::AnulacaoDoTalaoDeReceita"
				if self.talao_de_receita.extra_orcamentario?
					fonte_id = self.talao_de_receita.fonte_de_recursos_id
				else
					if evento_contabil.configuracao_do_evento_contabil.inclusivo_de_fontes?
						if self.complementos_por_fonte_da_anulacao_do_talao.map{ |a| a.orcamento_da_receita.fonte_de_recursos_id }.compact.size > 0
							fontes_do_evento = evento_contabil.configuracao_do_evento_contabil.fontes_da_configuracao_contabil.pluck(:fonte_de_recursos_id)

							valor_da_fonte = self.valor.to_d
							self.complementos_por_fonte_da_anulacao_do_talao.each do |complemento|
								if fontes_do_evento.include?(complemento.orcamento_da_receita.fonte_de_recursos_id)
									fonte_id =  complemento.orcamento_da_receita.fonte_de_recursos_id
								end
							end
						else
							fonte_id = nil
						end
					else
						fonte_id = nil
					end
				end
			elsif self.class.name == "Contabilidade::Empenho"
				fonte_id = self.orcamento_da_despesa.fonte_de_recursos_id
			elsif self.class.name == "Contabilidade::Liquidacao" || self.class.name == "Contabilidade::AnulacaoDoEmpenho"
				fonte_id = self.empenho.orcamento_da_despesa.fonte_de_recursos_id
			elsif self.class.name == "Contabilidade::EstornoDeLiquidacao" || self.class.name == "Contabilidade::Pagamento"
				fonte_id = self.liquidacao.empenho.orcamento_da_despesa.fonte_de_recursos_id
			elsif self.class.name == "Contabilidade::EstornoDePagamento"
				fonte_id = self.pagamento.liquidacao.empenho.orcamento_da_despesa.fonte_de_recursos_id
			elsif self.class.name == "Contabilidade::TransferenciaFinanceira"
				if evento_contabil.configuracao_do_evento_contabil.ug_diferente?
					if evento_contabil.configuracao_do_evento_contabil.origem?
						fonte_id = self.fonte_de_recurso_origem.id
					else
						fonte_id = self.fonte_de_recurso_destino.id
					end
				else
					fonte_id = self.fonte_de_recurso_origem.id
				end
			elsif self.class.name == "Contabilidade::SolicitacaoDeAlteracaoOrcamentaria"
				fonte_id = self.fonte_de_recursos_id
			elsif self.class.name == "Loa::OrcamentoDaDespesa"
				fonte_id = self.fonte_de_recursos_id
			elsif self.class.name == "Loa::OrcamentoDaReceita"
				fonte_id = self.fonte_de_recursos_id
			elsif self.class.name == "Contabilidade::DespesaExtraOrcamentaria"
				fonte_id = self.fonte_de_recursos_id
			elsif self.class.name == "Contabilidade::EstornoDeDespesaExtraOrcamentaria"
				fonte_id = self.despesa_extra_orcamentaria.fonte_de_recursos_id
			end
			return fonte_id
		end

		def retorna_valor_por_evento(evento_contabil, orcamento_atual = nil)
			case evento_contabil.modelo
			when "empenho"
				if self.respond_to?(:restos_a_pagar) && self.restos_a_pagar == true
					if evento_contabil.configuracao_do_evento_contabil.rp_processado?
						self.valor_processado(orcamento_atual)
					elsif evento_contabil.configuracao_do_evento_contabil.rp_nao_processado?
						self.valor_nao_processado(orcamento_atual)
					else
						self.definir_valor_do_empenho.to_d
					end
				else
					self.definir_valor_do_empenho.to_d
				end
			when "liquidacao"
				self.valor.to_d
			when "estorno_de_liquidacao"
				self.liquidacao.valor.to_d
			when "pagamento"
				if self.retornar_data_do_lancamento_por_objeto&.year.to_i >= 2025
					self.valor.to_d
				else
					if evento_contabil.contem_conta_patrimonial?
						self.valor_liquido_para_contas_patrimoniais.to_d # alteração solicitado por icaro e issac, motivo: diferença de talões sem conta bancaria
					else
						self.valor.to_d
					end
				end
			when "estorno_de_pagamento"
				self.pagamento.valor.to_d
			when "despesa_extra_orcamentaria"
				self.valor_total.to_d
			when "recebimento_de_material"
				self.valor_total_do_recebimento.to_d
			when "requisicao_de_material"
				self.valor_total_da_requisicao.to_d
			when "cancelamento_resto_a_pagar"
				self.valor_total.to_d
			when "loa"
				valor_a_ser_lancado_do_loa(evento_contabil)
			when "ppa"
				self.valor_total_da_despesa
			when "projecao_de_despesa"
				diferenca_a_ser_lancada(valor.to_d, valor_was.to_d)
			when "calculo_por_exercicio"
				diferenca_a_ser_lancada(total.to_d, total_was.to_d)
			when "orcamento_da_despesa"
				if evento_contabil.configuracao_do_evento_contabil.abertura?
					valor.to_d
				else
					diferenca_a_ser_lancada(valor.to_d, valor_was.to_d)
				end
			when "talao_de_receita"
				if evento_contabil.configuracao_do_evento_contabil.inclusivo_de_fontes?
					if self.complementos_por_fonte_do_talao_de_receita.map{ |a| a.orcamento_da_receita.fonte_de_recursos_id }.compact.size > 0
						fontes_do_evento = evento_contabil.configuracao_do_evento_contabil.fontes_da_configuracao_contabil.pluck(:fonte_de_recursos_id)

						valor_da_fonte = self.valor.to_d
						self.complementos_por_fonte_do_talao_de_receita.each do |complemento|
							if fontes_do_evento.include?(complemento.orcamento_da_receita.fonte_de_recursos_id)
								valor_da_fonte = complemento.valor
							end
						end

						valor_da_fonte.to_d.abs
					else
						self.valor.to_d.abs
					end
				else
					self.valor.to_d.abs
				end
			when "anulacao_do_talao_de_receita"
				if evento_contabil.configuracao_do_evento_contabil.inclusivo_de_fontes?
					if self.complementos_por_fonte_da_anulacao_do_talao.map{ |a| a.orcamento_da_receita.fonte_de_recursos_id }.compact.size > 0
						fontes_do_evento = evento_contabil.configuracao_do_evento_contabil.fontes_da_configuracao_contabil.pluck(:fonte_de_recursos_id)

						valor_da_fonte = self.valor.to_d
						self.complementos_por_fonte_da_anulacao_do_talao.each do |complemento|
							if fontes_do_evento.include?(complemento.orcamento_da_receita.fonte_de_recursos_id)
								valor_da_fonte = complemento.valor
							end
						end

						valor_da_fonte.to_d.abs
					else
						self.valor.to_d.abs
					end
				else
					self.valor.to_d.abs
				end
			when "medicao_da_obra"
				self.valor.to_d
			when "anulacao_do_empenho"
				self.valor.to_d
			when "bem_do_balancete"
				self.empenho.try(:definir_valor_do_empenho).to_d
			when "estorno_de_despesa_extra_orcamentaria"
				self.valor.to_d
			when "retencao"
				self.valor_calculado.to_d
			when "retencao_de_pagamento"
				self.retencao.valor_calculado.to_d
			when "transferencia_financeira"
				self.valor.to_d
			when "solicitacao_de_alteracao_orcamentaria"
				self.soma_dotacoes_destino.to_d
			when "cancelamento_de_resto_a_pagar"
				self.valor_total.to_d
			when "obra"
				if self.class.name == "Contabilidade::SituacaoDaObra"
					self.obra.valor.to_d
				else
					self.valor.to_d
				end
			when 'reconhecimento_programado'
				self.valor.to_d
			when "orcamento_da_receita"
				if evento_contabil.configuracao_do_evento_contabil.abertura?
					valor.to_d.abs
				else
					diferenca_a_ser_lancada(valor_atual.to_d, valor_atual_was.to_d)
				end
			when "contrato"
				self.valor_do_contrato.to_d
			when "aditivo"
				self.contrato.valor_do_contrato
			when "reconhecido_na_liquidacao_da_despesa" || "reconhecimento_no_exercicio_vigente" || "reconhecimento_no_exercicio_anterior"
				if evento_contabil.configuracao_do_evento_contabil.estorno == true || self.class.name == "Contabilidade::EstornoDeLiquidacao"
					if self.liquidacao.detalhamentos_por_subelementos.map { |i| i if i.valor.to_d.positive? }.compact.size > 0
						contas = conta_do_detalhamento_vpd(evento_contabil.configuracao_do_evento_contabil.detalhamento_vpd_da_liquidacao)					
						if self.liquidacao.detalhamentos_por_subelementos.where(conta_id: contas.try(:ids)).any?
							self.liquidacao.detalhamentos_por_subelementos.where(conta_id: contas.try(:ids)).last.valor
						else
							0
						end
					else
						self.valor.to_d
					end
				else
					if self.detalhamentos_por_subelementos.map { |i| i if i.valor.to_d.positive? }.compact.size > 0
						contas = conta_do_detalhamento_vpd(evento_contabil.configuracao_do_evento_contabil.detalhamento_vpd_da_liquidacao)
						if self.detalhamentos_por_subelementos.where(conta_id: contas.try(:ids)).any?
							self.detalhamentos_por_subelementos.where(conta_id: contas.try(:ids)).last.valor
						else
							0
						end
					else
						self.valor.to_d
					end
				end
			when "item_do_consumo"
				self.total.to_d
			else
				self.valor.to_d
			end
		end

		def retorna_valor_por_evento_ddr(evento_contabil)
			case evento_contabil.configuracao_do_evento_contabil.tipo_ddr
			when "empenho_ddr"
				self.definir_valor_do_empenho.to_d
			when "liquidacao_ddr"
				self.valor.to_d
			when "estorno_de_liquidacao_ddr"
				self.liquidacao.valor.to_d
			when "pagamento_ddr"
				if evento_contabil.configuracao_do_evento_contabil.aciona_sem_valor_de_retencoes?
					self.valor_liquido_pago.to_d
				else
					self.valor.to_d
				end
			when "estorno_de_pagamento_ddr"
				if evento_contabil.configuracao_do_evento_contabil.aciona_sem_valor_de_retencoes?
					self.pagamento.valor_liquido_pago.to_d
				else
					self.pagamento.valor.to_d
				end				
			when "despesa_extra_orcamentaria_ddr"
				self.valor_total.to_d
			when "talao_de_receita_ddr"
				if evento_contabil.configuracao_do_evento_contabil.inclusivo_de_fontes?
					if self.complementos_por_fonte_do_talao_de_receita.map{ |a| a.orcamento_da_receita.fonte_de_recursos_id }.compact.size > 0
						#fontes_do_evento = evento_contabil.configuracao_do_evento_contabil.fontes_da_configuracao_contabil.pluck(:fonte_de_recursos_id)
						tipo_de_fonte = evento_contabil.configuracao_do_evento_contabil.fonte_vinculada?

						#valor_da_fonte = self.valor.to_d
						valor_da_fonte = 0
						self.complementos_por_fonte_do_talao_de_receita.each do |complemento|
							if complemento.orcamento_da_receita.fonte_de_recursos.fonte_vinculada == tipo_de_fonte
								valor_da_fonte = complemento.valor.to_d
							end
						end

						valor_da_fonte.to_d.abs
					else
						self.valor.to_d.abs
					end
				else
					self.valor.to_d.abs
				end
			when "anulacao_do_talao_de_receita_ddr"
				if evento_contabil.configuracao_do_evento_contabil.inclusivo_de_fontes?
					if self.complementos_por_fonte_da_anulacao_do_talao.map{ |a| a.orcamento_da_receita.fonte_de_recursos_id }.compact.size > 0
						fontes_do_evento = evento_contabil.configuracao_do_evento_contabil.fontes_da_configuracao_contabil.pluck(:fonte_de_recursos_id)

						valor_da_fonte = self.valor.to_d
						self.complementos_por_fonte_da_anulacao_do_talao.each do |complemento|
							if fontes_do_evento.include?(complemento.orcamento_da_receita.fonte_de_recursos_id)
								valor_da_fonte = complemento.valor
							end
						end

						valor_da_fonte.to_d.abs
					else
						self.valor.to_d.abs
					end
				else
					self.valor.to_d.abs
				end
			when "anulacao_do_empenho_ddr"
				self.valor.to_d
			when "estorno_de_despesa_extra_orcamentaria_ddr"
				self.valor.to_d
			when "transferencia_financeira_ddr"
				self.valor.to_d
			end
		end

		def retorna_valor_por_movimentacao_falha
			case self.class.name
			when "Contabilidade::Empenho"
				self.definir_valor_do_empenho
			when "Contabilidade::Liquidacao"
				self.valor.to_d
			when "Contabilidade::Pagamento"
				self.valor.to_d
			when "Contabilidade::DespesaExtraOrcamentaria"
				self.valor_total.to_d
			when "GestaoDeEstoque::RecebimentoDeMaterial"
				self.valor_total_do_recebimento.to_d
			when "Administrativo::RequisicaoDeMaterial"
				self.valor_total_da_requisicao.to_d
			when "Contabilidade::CancelamentoDeRestoAPagar"
				self.valor_total.to_d
			when "Loa::AlteracaoDeStatus"
				self.orcamento.subacoes.sum(&:valor_total_fixado_da_despesa)
			when "Ppa::Ppa"
				self.valor_total_da_despesa
			when "Ppa::ProjecaoDeDespesa"
				diferenca_a_ser_lancada(self.valor.to_d, self.valor_was.to_d)
			when "Projecao::CalculoPorExercicio"
				diferenca_a_ser_lancada(self.total.to_d, self.total_was.to_d)
			when "Loa::OrcamentoDaDespesa"
				diferenca_a_ser_lancada(self.valor.to_d, self.valor_was.to_d)
			when "Contabilidade::TalaoDeReceita"
				self.valor.to_d
			when "Contabilidade::MedicaoDaObra"
				self.valor.to_d
			when "Contabilidade::AnulacaoDoEmpenho"
				self.valor.to_d
			when "Contabilidade::BemDoBalancete"
				self.empenho.try(:definir_valor_do_empenho).to_d
			when "Contabilidade::Obra"
				self.valor.to_d
			when "Contabilidade::SituacaoDaObra"
				self.obra.valor.to_d
			when "Contabilidade::SolicitacaoDeAlteracaoOrcamentaria"
				self.soma_dotacoes_destino.to_d
			when "GestaoDeEstoque::ItemDoConsumo"
				self.total.to_d
			else
				self.valor.to_d
			end
		end

		def retornar_conta_bancaria(conta)
			conta_bancaria_a_utilizar = nil
			
			if conta.conta.codigo[0..4] == '11111' || conta.conta_par.codigo[0..4] == '11111'
				if self.class.name == "Contabilidade::TransferenciaFinanceira"
					if conta.debito? 
						conta_bancaria_a_utilizar = self.conta_bancaria_destino.try(:conta_bancaria_id) rescue nil
					else
						conta_bancaria_a_utilizar = self.conta_bancaria_origem.try(:conta_bancaria_id) rescue nil
					end
				elsif self.class.name == "Contabilidade::Pagamento"
					conta_bancaria_a_utilizar = self.contas_bancarias_por_pagamento&.first&.conta_bancaria_id
				elsif self.class.name == "Contabilidade::EstornoDePagamento"
					conta_bancaria_a_utilizar = self.pagamento&.contas_bancarias_por_pagamento&.first&.conta_bancaria_id
				elsif self.class.name == "Contabilidade::AnulacaoDoTalaoDeReceita"
					conta_bancaria_a_utilizar = talao_de_receita.conta_bancaria.try(:id)
				else
					conta_bancaria_a_utilizar = (conta_bancaria.try(:id) || conta_bancaria_por_classe.try(:id)) rescue nil
				end
			end

			return conta_bancaria_a_utilizar
		end

		alias_method :valor_movimentado, :retorna_valor_por_movimentacao_falha

		def valor_a_ser_lancado_do_loa(evento_contabil)
			if evento_contabil.configuracao_do_evento_contabil.projecao_de_despesa?
				self.orcamento.subacoes.sum(&:valor_total_fixado_da_despesa)
			elsif evento_contabil.configuracao_do_evento_contabil.projecao_de_receita?
				self.orcamento.unidades_orcamentarias_por_natureza_da_receita.sum(&:valor_total)
			elsif evento_contabil.configuracao_do_evento_contabil.inclusivo_de_receitas?
				valor_da_natureza_da_receita_inclusivo_de_receita(evento_contabil)
			elsif evento_contabil.configuracao_do_evento_contabil.exclusivo_de_receitas?
				valor_da_natureza_da_receita_exclusivo_de_receita(evento_contabil)
			else
				self.orcamento.subacoes.sum(&:valor_total_fixado_da_despesa) + self.orcamento.unidades_orcamentarias_por_natureza_da_receita.sum(&:valor_total)
			end
		end

		def valor_da_natureza_da_receita_inclusivo_de_receita(evento_contabil)
			pesquisa_sql = Array.new
			evento_contabil.naturezas_da_receita_da_configuracao_contabil.each do |natureza_da_receita|
				linha_sql = Array.new
				['categoria_economica', 'origem', 'especie', 'rubrica', 'alinea', 'subalinea', 'detalhamento_optativo',
					'nivel_opcional_1','nivel_opcional_2', 'nivel_opcional_3'].each do |atributo|
					if verifica_se_atributo_da_receita_esta_preenchido(atributo, natureza_da_receita)
						linha_sql.push("base_naturezas_da_receita.#{atributo} = '#{natureza_da_receita.send(atributo).to_s}'")
					end
				end
				pesquisa_sql.push(linha_sql.join(" AND "))
			end

			valores_previstos = self.orcamento.naturezas_da_receita.where(pesquisa_sql.join(" OR ")).uniq.sum(&:valor_previsto).to_d
			valores_previstos >= 0 ? valores_previstos : valores_previstos * -1
		end

		def valor_da_natureza_da_receita_exclusivo_de_receita(evento_contabil)
			pesquisa_sql = Array.new
			evento_contabil.naturezas_da_receita_da_configuracao_contabil.each do |natureza_da_receita|
				linha_sql = Array.new
				['categoria_economica', 'origem', 'especie', 'rubrica', 'alinea', 'subalinea', 'detalhamento_optativo',
					'nivel_opcional_1','nivel_opcional_2', 'nivel_opcional_3'].each do |atributo|
					if verifica_se_atributo_da_receita_esta_preenchido(atributo, natureza_da_receita)
						linha_sql.push("base_naturezas_da_receita.#{atributo} = '#{natureza_da_receita.send(atributo).to_s}'")
					end
				end
				pesquisa_sql.push(linha_sql.join(" AND "))
			end

			valores_previstos = self.orcamento.naturezas_da_receita.where.not(pesquisa_sql.join(" OR ")).uniq.sum(&:valor_previsto).to_d
			valores_previstos >= 0 ? valores_previstos : valores_previstos * -1
		end

		def diferenca_a_ser_lancada(valor_final, valor_inicial)
			diferenca = valor_final - valor_inicial
			diferenca >= 0 ? diferenca : diferenca * -1
		end

		def verifica_se_atributo_da_receita_esta_preenchido(atributo, natureza_da_receita)
			if atributo == "categoria_economica"
				natureza_da_receita.send(atributo) != "000"
			elsif atributo == "alinea" || atributo == "nivel_opcional_1" || atributo == "nivel_opcional_2" || atributo == "nivel_opcional_3"
				natureza_da_receita.send(atributo) != "00"
			else
				natureza_da_receita.send(atributo) != "0"
			end
		end

		def pesquisa_padrao_por_nome_e_classe_sem_dotacao(nome, classe)
			self.acao_do_sistema.eventos_contabeis.automatico.find_by(classe: classe, orcamento_id: self.orcamento_id, nome: nome)
		end

		def deve_ter_conta_debito_e_credito_nos_eventos_contabeis
			if @eventos_contabeis_por_objeto.present?
				@eventos_contabeis_por_objeto.each do |evento_contabil|
					if evento_contabil.present? && evento_contabil.semi_automatico? && evento_contabil.contas_por_eventos_contabeis.blank?
						mensagem = "O evento contábil associado com a ação #{self.acao_do_sistema.nome}, não possui contas de débito e crédito p/ realizar as movimentações, portanto não é possível concluir à ação."
						errors.add(:evento_contabil_id, mensagem)
					end
				end
			end
		end

		def acao_do_sistema
			case self.class.name
			when "Contabilidade::Liquidacao"
				define_atributo_data_e_codigo('data_da_liquidacao', 'numero')
			when "Administrativo::RequisicaoDeMaterial"
				define_atributo_data_e_codigo('data_da_requisicao', 'numero_da_requisicao')
			when "Contabilidade::DespesaExtraOrcamentaria"
				define_atributo_data_e_codigo('data_de_emissao', 'numero_de_caixa')
			when "Contabilidade::EstornoDeDespesaExtraOrcamentaria"
				define_atributo_data_e_codigo('data_do_estorno', 'numero_de_caixa')
			when "Contabilidade::Empenho"
				define_atributo_data_e_codigo('data_de_solicitacao', 'numero_do_empenho')
			when "Contabilidade::LancamentoManualDoEventoContabil"
				define_atributo_data_e_codigo('data_de_lancamento', 'codigo')
			when "Contabilidade::Pagamento"
				define_atributo_data_e_codigo('data_da_solicitacao', 'numero')
			when "Contabilidade::TalaoDeReceita"
				define_atributo_data_e_codigo('data_do_talao', 'numero_do_talao' )
			when "GestaoDeEstoque::RecebimentoDeMaterial"
				define_atributo_data_e_codigo('data_do_recebimento', 'codigo')
			when "GestaoDeEstoque::Transferencia"
				define_atributo_data_e_codigo('data_de_transferencia', 'codigo')
			when "Contabilidade::CancelamentoDeRestoAPagar"
				define_atributo_data_e_codigo('data', 'decreto')
			when "Loa::AlteracaoDeStatus"
				define_atributo_data_e_codigo('data_de_alteracao', nil)
			when "Ppa::Ppa"
				define_atributo_data_e_codigo('data_da_legislacao', nil)
			when 'Ppa::ProjecaoDeDespesa'
				define_atributo_data_e_codigo(nil, nil)
			when 'Projecao::CalculoPorExercicio'
				define_atributo_data_e_codigo(nil, nil)
			when 'Loa::OrcamentoDaDespesa'
				define_atributo_data_e_codigo(nil, nil)
			when "Contabilidade::MedicaoDaObras"
				define_atributo_data_e_codigo(nil, 'art')
			when "Contabilidade::AnulacaoDoEmpenho"
				define_atributo_data_e_codigo('data_da_anulacao', 'numero')
			when "Contabilidade::BemDoBalancete"
				define_atributo_data_e_codigo(nil, nil)
			when "Contabilidade::Obra"
				define_atributo_data_e_codigo(nil, 'codigo')
			when "Contabilidade::EstornoDePagamento"
				define_atributo_data_e_codigo('data_do_estorno', 'numero')
			when "Contabilidade::Retencao"
				define_atributo_data_e_codigo('atributo_data', 'atributo_codigo')
			when "Contabilidade::TransferenciaFinanceira"
				define_atributo_data_e_codigo('data', 'numero_da_transferencia')
			when "Contabilidade::EstornoDeLiquidacao"
				define_atributo_data_e_codigo('data_do_estorno', 'codigo_da_liquidacao')
			when "Contabilidade::SolicitacaoDeAlteracaoOrcamentaria"
				define_atributo_data_e_codigo('data_da_solicitacao', 'numero_da_alteracao_orcamentaria')
			when "Contabilidade::CancelamentoDeRestoAPagar"
				define_atributo_data_e_codigo('data', nil)
			when "Orcamento"
				define_atributo_data_e_codigo(nil, nil)
			when "Contabilidade::MesDoCronogramaDoEmpenho"
				define_atributo_data_e_codigo(nil, nil)
			when "Contabilidade::PagamentoDaRetencao"
				define_atributo_data_e_codigo(nil, nil)
			end
		end

		def define_atributo_data_e_codigo(data,codigo)
			@atributo_data = data
			@atributo_codigo_movimentacao = codigo
		end

		def lanca_tentativa_de_movimentacao(evento_contabil, saldo)
			self.tentativas_de_movimentacoes_do_plano_de_contas.new(
				evento_contabil_id: evento_contabil.try(:id),
				modulo_type: self.class.name,
				data_da_tentativa: @atributo_data.present? ? self.send(@atributo_data) : Date.today,
				saldo: saldo,
				falhou: evento_contabil.nil?
			)
		end


		def codigo_movimentado
			case self.class.name
			when "Contabilidade::Liquidacao", "Contabilidade::AnulacaoDoEmpenho", "Contabilidade::EstornoDePagamento", "Contabilidade::Pagamento", "Licitacao::Contrato", "Licitacao::Aditivo"
				numero
			when "Administrativo::RequisicaoDeMaterial"
				numero_da_requisicao
			when "Contabilidade::DespesaExtraOrcamentaria"
				numero_de_caixa
			when "Contabilidade::EstornoDeDespesaExtraOrcamentaria"
				numero_de_caixa
			when "Contabilidade::Empenho"
				numero_do_empenho
			when "Contabilidade::TalaoDeReceita", "Contabilidade::AnulacaoDoTalaoDeReceita"
				numero_do_talao
			when "GestaoDeEstoque::RecebimentoDeMaterial", "GestaoDeEstoque::Transferencia", "Contabilidade::Obra", "Contabilidade::LancamentoManualDoEventoContabil"
				codigo
			when "Contabilidade::CancelamentoDeRestoAPagar"
				decreto
			when "Contabilidade::MedicaoDaObras"
				art
			when "Contabilidade::Retencao"
				atributo_codigo
			else
				id
			end
		end

		def data_movimentada
			case self.class.name
			when "Contabilidade::Liquidacao"
				data_da_liquidacao
			when "Administrativo::RequisicaoDeMaterial"
				data_da_requisicao
			when "Contabilidade::DespesaExtraOrcamentaria"
				data_de_emissao
			when "Contabilidade::EstornoDeDespesaExtraOrcamentaria"
				data_do_estorno
			when "Contabilidade::Empenho"
				data_do_empenho
			when "Contabilidade::LancamentoManualDoEventoContabil"
				data_de_lancamento
			when "Contabilidade::Pagamento"
				data_da_solicitacao
			when "Contabilidade::TalaoDeReceita"
				data_do_talao
			when "GestaoDeEstoque::RecebimentoDeMaterial"
				data_do_recebimento
			when "GestaoDeEstoque::Transferencia"
				data_de_transferencia
			when "Contabilidade::CancelamentoDeRestoAPagar"
				data
			when "Loa::AlteracaoDeStatus"
				data_de_alteracao
			when "Ppa::Ppa"
				data_da_legislacao
			when "Contabilidade::AnulacaoDoEmpenho"
				data_da_anulacao
			when "Contabilidade::EstornoDePagamento"
				data_do_estorno
			when "Contabilidade::Retencao"
				atributo_data
			when "Licitacao::Contrato"
				data_do_contrato
			when "Licitacao::Aditivo"
				data_do_aditivo
			else
				Date.today
			end
		end

		def conta_bancaria_por_classe
			case self.class.name
			when 'Contabilidade::TalaoDeReceita', 'Contabilidade::DespesaExtraOrcamentaria', 'Contabilidade::EstornoDeDespesaExtraOrcamentaria'
				conta_bancaria
			when 'Contabilidade::AnulacaoDoTalaoDeReceita'
				talao_de_receita.conta_bancaria
			end
		end

		def cria_movimentacoes_por_fonte_de_recursos
			lancamentos_do_orcamento_da_receita.reload
			movimentacoes_do_plano_de_contas.reload
			movimentacoes_do_plano_de_contas.each do |movimentacao_do_plano_de_contas|
				if movimentacao_do_plano_de_contas.movimentacoes_por_fonte_de_recursos.empty?
					if movimentacao_do_plano_de_contas.gerador_type == 'Contabilidade::TalaoDeReceita' && movimentacao_do_plano_de_contas.conta.informacao_complementar_possui_fonte_de_recursos?
						lancamentos_do_orcamento_da_receita.each do |lancamento|
							Contabilidade::MovimentacaoPorFonteDeRecursos.create!(
								saldo: lancamento.valor,
								movimentacao_do_plano_de_contas_id: movimentacao_do_plano_de_contas.id,
								fonte_de_recursos_id: lancamento.orcamento_da_receita.fonte_de_recursos_id
							)
						end
					else
						if movimentacao_do_plano_de_contas.conta.informacao_complementar_possui_fonte_de_recursos?
							Contabilidade::MovimentacaoPorFonteDeRecursos.create!(
								saldo: movimentacao_do_plano_de_contas.valor,
								movimentacao_do_plano_de_contas_id: movimentacao_do_plano_de_contas.id,
								fonte_de_recursos_id: movimentacao_do_plano_de_contas.get_fonte_de_recursos.id
							)
						end
					end
				end
			end
		end

		def tipo_detalhamento_vpd_da_liquidacao(nome_conta)
			tipo_de_detalhamento = []
			case nome_conta
			when "APOSENTADORIAS POR INVALIDEZ"
				tipo_de_detalhamento = 'aposentadoria_por_invalidez'
			when "APOSENTADORIAS ESPECIAIS - ATIVIDADES DE RISCO"
				tipo_de_detalhamento = 'aposentadoria_especial_atividade_de_risco'
			when "APOSENTADORIAS ESPECIAIS - AGENTES NOCIVOS"
				tipo_de_detalhamento = 'aposentadoria_especial_agentes_nocivos'
			when "APOSENTADORIAS ESPECIAIS - DEFICIÊNCIA"
				tipo_de_detalhamento = 'aposentadoria_especial_deficiencia'
			when "APOSENTADORIAS PROFESSOR"
				tipo_de_detalhamento = 'aposentadoria_professor'
			when "APOSENTADORIAS POR TEMPO DE CONTRIBUIÇÃO"
				tipo_de_detalhamento = 'aposentadoria_por_tempo_de_contribuicao'
			when "APOSENTADORIAS COMPULSÓRIAS"
				tipo_de_detalhamento = 'aposentadoria_compulsoria'
			when "OUTRAS APOSENTADORIAS ESPECIAIS"
				tipo_de_detalhamento = 'outras_aposentadorias_especiais'
			when "OUTRAS APOSENTADORIAS"
				tipo_de_detalhamento = 'outras_aposentadorias'
			when "AUXILIO FUNERAL ATIVO CIVIL"
				tipo_de_detalhamento = 'auxilio_funeral_ativo_civil'
			when "AUXILIO FUNERAL INATIVO CIVIL"
				tipo_de_detalhamento = 'auxilio_funeral_inativo_civil'
			when "AUXILIO FUNERAL PENSIONISTA CIVIL"
				tipo_de_detalhamento = 'auxilio_funeral_pensionista_civil'
			when "AUXILIO NATALIDADE ATIVO CIVIL"
				tipo_de_detalhamento = 'auxilio_natalidade_ativo_civil'
			when "AUXILIO NATALIDADE INATIVO CIVIL"
				tipo_de_detalhamento = 'auxilio_natalidade_inativo_civil'
			when "AUXILIO NATALIDADE PENSIONISTA CIVIL"
				tipo_de_detalhamento = 'auxilio_natalidade_pensionista_civil'
			when "AUXILIO RECLUSAO ATIVO CIVIL"
				tipo_de_detalhamento = 'auxilio_reclusao_ativo_civil'
			when "AUXILIO RECLUSAO INATIVO CIVIL"
				tipo_de_detalhamento = 'auxilio_reclusao_inativo_civil'
			when "AUXILIO RECLUSAO PENSIONISTA CIVIL"
				tipo_de_detalhamento = 'auxilio_reclusao_pensionista_civil'
			when "SALARIO FAMILIA - ATIVO PESSOAL CIVIL"
				tipo_de_detalhamento = 'salario_familia_ativo_pessoal_civil'
			when "SALARIO FAMILIA-INATIVO PESSOAL CIVIL"
				tipo_de_detalhamento = 'salario_familia_inativo_pessoal_civil'
			when "SALARIO FAMILIA-PENSIONISTA PESSOAL CIVIL"
				tipo_de_detalhamento = 'salario_familia_pensionista_pessoal_civil'
			when "DEMAIS BENEFÍCIOS PREVIDENCIÁRIOS E  ASSISTENCIAIS - SERVIDOR CIVIL"
				tipo_de_detalhamento = 'demais_beneficios_previdenciarios_e_assistenciais_servidor_civil'
			when "SERVICOS EXTRAORDINARIOS CONTRATO TEMPORARIO"
				tipo_de_detalhamento = 'servicos_extraordinarios_contrato_temporario'
			when "SERVICOS EXTRAORDINARIOS NOTURNO CONT. TEMP."
				tipo_de_detalhamento = 'servicos_extraordinarios_noturno_cont_temp'
			when "VANTAGEM PECUNIÁRIA INDIVIDUAL"
				tipo_de_detalhamento = 'vantagem_pecuniaria_individual'
			when "ABONO PROVISÓRIO - PESSOAL CIVIL"
				tipo_de_detalhamento = 'abono_provisorio_pessoal_civil'
			when "GRATIFICAÇÕES ESPECIAIS"
				tipo_de_detalhamento = 'gratificacoes_especiais'
			when "GRATIFICAÇÃO POR ATIVIDADES EXPOSTAS"
				tipo_de_detalhamento = 'gratificacao_por_atividades_expostas'
			when "REPRESENTAÇÃO MENSAL"
				tipo_de_detalhamento = 'representacao_mensal'
			when "COMPLEMENTAÇÃO SALARIAL"
				tipo_de_detalhamento = 'complementacao_salarial'
			when "ADICIONAL - TETO PARLAMENTAR"
				tipo_de_detalhamento = 'adicional_teto_parlamentar'
			when "GRATIFICAÇÃO POR EXERCÍCIO DE CARGO EM COMISSÃO"
				tipo_de_detalhamento = 'gratificacao_por_exercicio_de_cargo_em_comissao'
			when "OUTROS VENCIMENTOS E VANTAGENS FIXAS - PESSOAL CIVIL RPPS"
				tipo_de_detalhamento = 'outros_vencimentos_e_vantagens_fixas_pessoal_civil_rpps'
			when "ADICIONAL VARIAVEL"
				tipo_de_detalhamento = 'adicional_variavel'
			when "LICENÇA SEM REMUNERAÇÃO INCENTIVADA"
				tipo_de_detalhamento = 'licenca_sem_remuneracao_incentivada'
			when "CONVOCAÇÃO EXTRAORDINARIA LEGISLATIVA"
				tipo_de_detalhamento = 'convocacao_extraordinaria_legislativa'
			when "INDENIZAÇÕES E RESTITUIÇÕES TRABALHISTAS"
				tipo_de_detalhamento = 'indenizacoes_e_restituicoes_trabalhistas'
			when "INDENIZ. E RESTIT. DECORR. DE PLANOS DE DEMISSÃO VOLUNTÁRIA"
				tipo_de_detalhamento = 'indeniz_e_restit_decorr_de_planos_de_demissao_voluntaria'
			when "OUTROS VENCIMENTOS E VANTAGENS FIXAS PESSOAL CIVIL RGPS"
				tipo_de_detalhamento = 'outros_vencimentos_e_vantagens_fixas_pessoal_civil_rgps'
			when "ADICIONAL DE TRANSFERÊNCIA - ART. 469/CLT"
				tipo_de_detalhamento = 'adicional_de_transferencia_art_469_clt'
			when "REMUNERAÇÃO DE DIRETORES"
				tipo_de_detalhamento = 'remuneracao_de_diretores'
			when "AVISO PREVIO"
				tipo_de_detalhamento = 'aviso_previo'
			end
		end

		def conta_do_detalhamento_vpd(enum_detalhamento_vpd)
			conta_detalhamento = []
			case enum_detalhamento_vpd
			when 'aposentadoria_por_invalidez'
				conta_detalhamento = Contabilidade::Conta.where(nome: "APOSENTADORIAS POR INVALIDEZ")
			when 'aposentadoria_especial_atividade_de_risco'
				conta_detalhamento = Contabilidade::Conta.where(nome: "APOSENTADORIAS ESPECIAIS - ATIVIDADES DE RISCO")
			when 'aposentadoria_especial_agentes_nocivos'
				conta_detalhamento = Contabilidade::Conta.where(nome: "APOSENTADORIAS ESPECIAIS - AGENTES NOCIVOS")
			when 'aposentadoria_especial_deficiencia'
				conta_detalhamento = Contabilidade::Conta.where(nome: "APOSENTADORIAS ESPECIAIS - DEFICIÊNCIA")
			when 'aposentadoria_professor'
				conta_detalhamento = Contabilidade::Conta.where(nome: "APOSENTADORIAS PROFESSOR")
			when 'aposentadoria_por_tempo_de_contribuicao'
				conta_detalhamento = Contabilidade::Conta.where(nome: "APOSENTADORIAS POR TEMPO DE CONTRIBUIÇÃO")
			when 'aposentadoria_compulsoria'
				conta_detalhamento = Contabilidade::Conta.where(nome: "APOSENTADORIAS COMPULSÓRIAS")
			when 'outras_aposentadorias_especiais'
				conta_detalhamento = Contabilidade::Conta.where(nome: "OUTRAS APOSENTADORIAS ESPECIAIS")
			when 'outras_aposentadorias'
				conta_detalhamento = Contabilidade::Conta.where(nome: "OUTRAS APOSENTADORIAS")
			when 'auxilio_funeral_ativo_civil'
				conta_detalhamento = Contabilidade::Conta.where(nome: "AUXILIO FUNERAL ATIVO CIVIL")
			when 'auxilio_funeral_inativo_civil'
				conta_detalhamento = Contabilidade::Conta.where(nome: "AUXILIO FUNERAL INATIVO CIVIL")
			when 'auxilio_funeral_pensionista_civil'
				conta_detalhamento = Contabilidade::Conta.where(nome: "AUXILIO FUNERAL PENSIONISTA CIVIL")
			when 'auxilio_natalidade_ativo_civil'
				conta_detalhamento = Contabilidade::Conta.where(nome: "AUXILIO NATALIDADE ATIVO CIVIL")
			when 'auxilio_natalidade_inativo_civil'
				conta_detalhamento = Contabilidade::Conta.where(nome: "AUXILIO NATALIDADE INATIVO CIVIL")
			when 'auxilio_natalidade_pensionista_civil'
				conta_detalhamento = Contabilidade::Conta.where(nome: "AUXILIO NATALIDADE PENSIONISTA CIVIL")
			when 'auxilio_reclusao_ativo_civil'
				conta_detalhamento = Contabilidade::Conta.where(nome: "AUXILIO RECLUSAO ATIVO CIVIL")
			when 'auxilio_reclusao_inativo_civil'
				conta_detalhamento = Contabilidade::Conta.where(nome: "AUXILIO RECLUSAO INATIVO CIVIL")
			when 'auxilio_reclusao_pensionista_civil'
				conta_detalhamento = Contabilidade::Conta.where(nome: "AUXILIO RECLUSAO PENSIONISTA CIVIL")
			when 'salario_familia_ativo_pessoal_civil'
				conta_detalhamento = Contabilidade::Conta.where(nome: "SALARIO FAMILIA - ATIVO PESSOAL CIVIL")
			when 'salario_familia_inativo_pessoal_civil'
				conta_detalhamento = Contabilidade::Conta.where(nome: "SALARIO FAMILIA-INATIVO PESSOAL CIVIL")
			when 'salario_familia_pensionista_pessoal_civil'
				conta_detalhamento = Contabilidade::Conta.where(nome: "SALARIO FAMILIA-PENSIONISTA PESSOAL CIVIL")
			when 'demais_beneficios_previdenciarios_e_assistenciais_servidor_civil'
				conta_detalhamento = Contabilidade::Conta.where(nome: "DEMAIS BENEFÍCIOS PREVIDENCIÁRIOS E  ASSISTENCIAIS - SERVIDOR CIVIL")
			when 'servicos_extraordinarios_contrato_temporario'
				conta_detalhamento = Contabilidade::Conta.where(nome: "SERVICOS EXTRAORDINARIOS CONTRATO TEMPORARIO")
			when 'servicos_extraordinarios_noturno_cont_temp'
				conta_detalhamento = Contabilidade::Conta.where(nome: "SERVICOS EXTRAORDINARIOS NOTURNO CONT. TEMP.")
			when 'vantagem_pecuniaria_individual'
				conta_detalhamento = Contabilidade::Conta.where(nome: "VANTAGEM PECUNIÁRIA INDIVIDUAL")
			when 'abono_provisorio_pessoal_civil'
				conta_detalhamento = Contabilidade::Conta.where(nome: "ABONO PROVISÓRIO - PESSOAL CIVIL")
			when 'gratificacoes_especiais'
				conta_detalhamento = Contabilidade::Conta.where(nome: "GRATIFICAÇÕES ESPECIAIS")
			when 'gratificacao_por_atividades_expostas'
				conta_detalhamento = Contabilidade::Conta.where(nome: "GRATIFICAÇÃO POR ATIVIDADES EXPOSTAS")
			when 'representacao_mensal'
				conta_detalhamento = Contabilidade::Conta.where(nome: "REPRESENTAÇÃO MENSAL")
			when 'complementacao_salarial'
				conta_detalhamento = Contabilidade::Conta.where(nome: "COMPLEMENTAÇÃO SALARIAL")
			when 'adicional_teto_parlamentar'
				conta_detalhamento = Contabilidade::Conta.where(nome: "ADICIONAL - TETO PARLAMENTAR")
			when 'gratificacao_por_exercicio_de_cargo_em_comissao'
				conta_detalhamento = Contabilidade::Conta.where(nome: "GRATIFICAÇÃO POR EXERCÍCIO DE CARGO EM COMISSÃO")
			when 'outros_vencimentos_e_vantagens_fixas_pessoal_civil_rpps'
				conta_detalhamento = Contabilidade::Conta.where(nome: "OUTROS VENCIMENTOS E VANTAGENS FIXAS - PESSOAL CIVIL RPPS")
			when 'adicional_variavel'
				conta_detalhamento = Contabilidade::Conta.where(nome: "ADICIONAL VARIAVEL")
			when 'licenca_sem_remuneracao_incentivada'
				conta_detalhamento = Contabilidade::Conta.where(nome: "LICENÇA SEM REMUNERAÇÃO INCENTIVADA")
			when 'convocacao_extraordinaria_legislativa'
				conta_detalhamento = Contabilidade::Conta.where(nome: "CONVOCAÇÃO EXTRAORDINARIA LEGISLATIVA")
			when 'indenizacoes_e_restituicoes_trabalhistas'
				conta_detalhamento = Contabilidade::Conta.where(nome: "INDENIZAÇÕES E RESTITUIÇÕES TRABALHISTAS")
			when 'indeniz_e_restit_decorr_de_planos_de_demissao_voluntaria'
				conta_detalhamento = Contabilidade::Conta.where(nome: "INDENIZ. E RESTIT. DECORR. DE PLANOS DE DEMISSÃO VOLUNTÁRIA")
			when 'outros_vencimentos_e_vantagens_fixas_pessoal_civil_rgps'
				conta_detalhamento = Contabilidade::Conta.where(nome: "OUTROS VENCIMENTOS E VANTAGENS FIXAS PESSOAL CIVIL RGPS")
			when 'adicional_de_transferencia_art_469_clt'
				conta_detalhamento = Contabilidade::Conta.where(nome: "ADICIONAL DE TRANSFERÊNCIA - ART. 469/CLT")
			when 'remuneracao_de_diretores'
				conta_detalhamento = Contabilidade::Conta.where(nome: "REMUNERAÇÃO DE DIRETORES")
			when 'aviso_previo'
				conta_detalhamento = Contabilidade::Conta.where(nome: "AVISO PREVIO")
			end
		end
		
		def tipos_de_pessoa_por_model
			tipos_de_pessoas_da_configuracao = Contabilidade::ConfiguracaoDoEventoContabil.tipo_de_pessoas
			tipos_de_pessoas = []
			case self.class.name
			when "Contabilidade::Empenho"
				tipos_de_pessoas.push ((tipos_de_pessoas_da_configuracao[pessoa.retorna_tipo_de_pessoa_formatada.to_sym] rescue nil))
			when "Contabilidade::AnulacaoDeEmpenho"
				tipos_de_pessoas.push((tipos_de_pessoas_da_configuracao[empenho.pessoa.retorna_tipo_de_pessoa_formatada.to_sym] rescue nil))
			when "Contabilidade::Pagamento"
				tipos_de_pessoas.push((tipos_de_pessoas_da_configuracao[empenho.pessoa.retorna_tipo_de_pessoa_formatada.to_sym] rescue nil))
			when "Contabilidade::EstornoDePagamento"
				tipos_de_pessoas.push((tipos_de_pessoas_da_configuracao[pagamento.liquidacao.empenho.pessoa.retorna_tipo_de_pessoa_formatada.to_sym] rescue nil))
			when "Contabilidade::MedicaoDaObra"
				tipos_de_pessoas.push(tipo_de_pessoas.pluck(:descricao).map{ |descricao| tipos_de_pessoas_da_configuracao[I18n.transliterate(descricao.downcase).tr(" ", "_")] })
			when "Contabilidade::Retencao"
				tipos_de_pessoas.push((tipos_de_pessoas_da_configuracao[liquidacao.empenho.pessoa.retorna_tipo_de_pessoa_formatada.to_sym] rescue nil))
			when "Contabilidade::TalaoDeReceita"
				tipos_de_pessoas.push((tipos_de_pessoas_da_configuracao[pessoa.retorna_tipo_de_pessoa_formatada.to_sym] rescue nil))
			when "Contabilidade::AnulacaoDoTalaoDeReceita"
				tipos_de_pessoas.push((tipos_de_pessoas_da_configuracao[talao_de_receita.pessoa.retorna_tipo_de_pessoa_formatada.to_sym] rescue nil))
			when "Contabilidade::Liquidacao"
				tipos_de_pessoas.push((tipos_de_pessoas_da_configuracao[empenho.pessoa.retorna_tipo_de_pessoa_formatada.to_sym] rescue nil))
			when "Contabilidade::EstornoDeLiquidacao"
				tipos_de_pessoas.push((tipos_de_pessoas_da_configuracao[liquidacao.empenho.pessoa.retorna_tipo_de_pessoa_formatada.to_sym] rescue nil))
			end

			tipos_de_pessoas = tipos_de_pessoas.flatten
			pessoa_fisica_ou_juridica = tipos_de_pessoas.include?(1) || tipos_de_pessoas.include?(2)
			demais_contribuintes = tipos_de_pessoas.include?(5)

			if pessoa_fisica_ou_juridica
				tipos_de_pessoas.push(tipos_de_pessoas_da_configuracao[:pessoa_fisica_ou_pessoa_juridica])
				tipos_de_pessoas.push(tipos_de_pessoas_da_configuracao[:pessoa_fisica_ou_pessoa_juridica_ou_demais_contribuintes])
			end

			tipos_de_pessoas.push(tipos_de_pessoas_da_configuracao[:pessoa_fisica_ou_pessoa_juridica_ou_demais_contribuintes]) if demais_contribuintes

			tipos_de_pessoas
		end

		def eh_receita_de_deducao_por_model
			case self.class.name
			when "Contabilidade::TalaoDeReceita"
				natureza_da_receita.categoria_economica == '009' if natureza_da_receita.present?
			end
		end

		def natureza_da_receita_por_model
			case self.class.name
			when "Contabilidade::TalaoDeReceita"
				natureza_da_receita
			when "Contabilidade::AnulacaoDoTalaoDeReceita"
				talao_de_receita.natureza_da_receita
			end
		end

		def recebimento_com_classificacao_por_model
			case self.class.name
			when "GestaoDeEstoque::RecebimentoDeMaterial"
				classificacao_doacao_ou_ajuste_de_inventario?
			end
		end

		def veio_de_uma_ordem_por_model
			case self.class.name
			when "GestaoDeEstoque::RecebimentoDeMaterial"
				ordem_de_compra.present?
			end
		end

		def originado_de_um_evento_manual_por_model
			case self.class.name
			when "Contabilidade::Pagamento"
				empenho.movimentacao_do_plano_de_contas.present?
			end
		end

		def conta_pcasp_do_lancamento_manual_por_model
			case self.class.name
			when "Contabilidade::Pagamento"
				empenho.movimentacao_do_plano_de_contas.conta_por_evento_contabil.conta_id rescue nil
			end
		end

		def resto_a_pagar_processado_por_model
			case self.class.name
			when "Contabilidade::Pagamento"
				processado?
			when "Contabilidade::EstornoDePagamento"
				pagamento.processado?
			end
		end

		def tipos_de_evento_por_model
			case self.class.name
			when "Contabilidade::TalaoDeReceita"
				["Inclusivo de Receitas", "Exclusivo de Receitas"]
			else
				["Inclusivo de Dotações", "Exclusivo de Dotações"]
			end
		end

		def eh_resto_a_pagar_por_model
			case self.class.name
			when "Contabilidade::Pagamento"
				resto_a_pagar?
			when "Contabilidade::Liquidacao"
				eh_resto_a_pagar?
			when "Contabilidade::EstornoDePagamento"
				pagamento.resto_a_pagar?
			when "GestaoDeEstoque::RecebimentoDeMaterial"
				ordem_de_compra.empenho.restos_a_pagar rescue nil
			end
		end

		def contas_pcasp_das_contas_bancarias_por_model
			case self.class.name
			when "Contabilidade::Pagamento"
				contas_bancarias_ids = contas_bancarias_por_pagamento.map{|t| t.conta_bancaria_id }
				Contabilidade::ContaPcaspDaContaBancariaPorOrcamento.where(conta_bancaria_id: contas_bancarias_ids, orcamento_id: orcamento_id)
			when "Contabilidade::EstornoDePagamento"
				contas_bancarias_ids = pagamento.contas_bancarias_por_pagamento.map{|t| t.conta_bancaria_id }
				Contabilidade::ContaPcaspDaContaBancariaPorOrcamento.where(conta_bancaria_id: contas_bancarias_ids, orcamento_id: pagamento.orcamento_id)
			when "Contabilidade::TalaoDeReceita"
				conta_bancaria.contas_pcasp_da_conta_bancaria_por_orcamento.where(orcamento_id: orcamento_id) if conta_bancaria.present?
			end
		end

		def modalidade_do_empenho_por_model
			modalidades_do_empenho = []
			modalidades_do_empenho_da_configuracao = Contabilidade::ConfiguracaoDoEventoContabil.modalidades_do_empenho
			empenho_da_ativacao = nil

			case self.class.name
			when "Contabilidade::Empenho"
				empenho_da_ativacao = self
			when "Contabilidade::Liquidacao", "Contabilidade::Pagamento", "Contabilidade::AnulacaoDoEmpenho"
				empenho_da_ativacao = empenho
			when "GestaoDeEstoque::RecebimentoDeMaterial"
				empenho_da_ativacao = ordem_de_compra.empenho rescue nil
			when "Contabilidade::MedicaoDaObra"
				modalidades_do_empenho = empenhos.pluck(:modalidade).uniq
				modalidades_do_empenho.push(modalidades_do_empenho_da_configuracao["global_ou_estimativo"]) if empenhos.global.any? || empenhos.estimativo.any?
			end

			if empenho_da_ativacao.present?
				modalidades_do_empenho.push(modalidades_do_empenho_da_configuracao[empenho_da_ativacao.modalidade])
				modalidades_do_empenho.push(modalidades_do_empenho_da_configuracao["global_ou_estimativo"]) if empenho_da_ativacao.global? || empenho_da_ativacao.estimativo?
			end

			modalidades_do_empenho
		end

		def empenho_complementar_por_model
			case self.class.name
			when "Contabilidade::Empenho"
				empenho_complementar?
			end
		end

		def fluxo_completo_do_empenho_por_model
			case self.class.name
			when "Contabilidade::Empenho"
				Configuracao.last.envia_empenho_para_contabilidade? && status_was == 'enviado_para_contabilidade'
			end
		end

		def tipo_de_resto_a_pagar_por_model
			tipos_de_resto_a_pagar_da_configuracao = Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_resto_a_pagar
			case self.class.name
			when "Contabilidade::Empenho"
				if restos_a_pagar
					if contexto_atual.present?
						orcamento_atual = contexto_atual
					else
						orcamento_atual = @orcamento_atual
					end

					valor_processado(orcamento_atual)  > 0 ? tipos_de_resto_a_pagar_da_configuracao['rp_processado'] : tipos_de_resto_a_pagar_da_configuracao['rp_nao_processado']
				end
			when "Contabilidade::Liquidacao"
				if restos_a_pagar
					if contexto_atual.present?
						orcamento_atual = contexto_atual
					else
						orcamento_atual = @orcamento_atual
					end

					empenho.valor_processado(orcamento_atual)  > 0 ? tipos_de_resto_a_pagar_da_configuracao['rp_processado'] : tipos_de_resto_a_pagar_da_configuracao['rp_nao_processado']
				end	
			when "Contabilidade::Pagamento"
				if self.liquidacao.restos_a_pagar
					if contexto_atual.present?
						orcamento_atual = contexto_atual
					else
						orcamento_atual = @orcamento_atual
					end

					self.liquidacao.empenho.valor_processado(orcamento_atual)  > 0 ? tipos_de_resto_a_pagar_da_configuracao['rp_processado'] : tipos_de_resto_a_pagar_da_configuracao['rp_nao_processado']
				end
			end 
		end

		def sub_elementos_de_despesa_por_model
			sub_elementos_de_despesa_da_configuracao = []
			case self.class.name
			when "Contabilidade::Empenho", "Contabilidade::Liquidacao", "Contabilidade::Pagamento", "Contabilidade::EstornoDePagamento", "GestaoDeEstoque::RecebimentoDeMaterial"
				sub_elementos_de_despesa_da_configuracao.push(sub_elemento_de_despesa)
			end

			sub_elementos_de_despesa_da_configuracao
		end

		def uso_do_bem_por_model
			case self.class.name
			when "Contabilidade::BemDoBalancete"
				Contabilidade::ConfiguracaoDoEventoContabil.uso_do_bens[self.empenho.try(:uso_do_bem_do_empenho)] rescue nil
			when "Contabilidade::SituacaoDaObra"
				obra.read_attribute_before_type_cast(:uso_do_bem) rescue nil
			end
		end

		def tipo_de_obra_por_model
			case self.class.name
			when "Contabilidade::MedicaoDaObra"
				Contabilidade::ConfiguracaoDoEventoContabil.tipos_de_obra[self.obra.try(:tipo_de_obra)] rescue nil
			end
		end

		def origem_da_retencao_por_model
			case self.class.name
			when "Contabilidade::Retencao"
				Contabilidade::ConfiguracaoDoEventoContabil.origens_da_retencao[origem_da_retencao]
			end
		end

		def tipo_de_credito_por_model
			case self.class.name
			when "Contabilidade::SolicitacaoDeAlteracaoOrcamentaria"
				Contabilidade::ConfiguracaoDoEventoContabil.tipo_de_creditos[tipo_de_credito.to_sym] rescue nil
			# when "Contabilidade::CancelamentoDeRestoAPagar"
			# 	tipo_de_credito
			end
		end

		def origem_do_recurso_por_model
			case self.class.name
			when "Contabilidade::SolicitacaoDeAlteracaoOrcamentaria"
				Contabilidade::ConfiguracaoDoEventoContabil.origens_dos_recursos[origem_do_recurso.to_sym] rescue nil
			# when "Contabilidade::CancelamentoDeRestoAPagar"
			# 	origem_do_recurso
			end
		end

		def cancelamento_por_falta_de_disponibilidade_de_caixa_por_model
			case self.class.name
			when "Contabilidade::AnulacaoDoEmpenho"
				#cancelamento_por_falta_de_disponibilidade_de_caixa?
				false
			end
		end

		def empenho_complementar_por_model
			case self.class.name
			when "Contabilidade::Empenho"
				empenho_complementar?
			end
		end

		def bem_lancado_por_model
			case self.class.name
			when "Contabilidade::BemDoBalancete"
				lancado?
			end
		end

		def obra_tombada_por_model
			case self.class.name
			when "Contabilidade::SituacaoDaObra"
				obra.tombada? || tombada?
			end
		end

		def extraorcamentario_por_model
			case self.class.name
			when "Contabilidade::TalaoDeReceita"
				self.extra_orcamentario?
			when "Contabilidade::AnulacaoDoTalaoDeReceita"
				talao_de_receita.extra_orcamentario?
			when "Contabilidade::DespesaExtraOrcamentaria", "Contabilidade::EstornoDeDespesaExtraOrcamentaria"
				true
			end
		end

		def conta_pcasp_de_deposito(conta_pcasp)
			if ['2.1.8.8.1.03.01', '2.1.8.8.1.03.02', '2.1.8.8.1.04.01', '2.1.8.8.1.04.02', '2.1.8.8.1.04.03', '2.1.8.8.1.04.04', '2.1.8.8.1.04.05', '2.1.8.8.1.04.99', '2.1.8.8.1.02.00'].include? conta_pcasp&.codigo_formatado
				conta_pcasp_deposito = true
			else
				conta_pcasp_deposito = false
			end
		end

		def conta_pcasp_de_retencoes_e_consignacoes(conta_pcasp)
			if ['2.1.8.8.1.01.03', '2.1.8.8.1.01.05', '2.1.8.8.1.01.10', '2.1.8.8.1.01.11', '2.1.8.8.1.01.13', '2.1.8.8.1.01.14', '2.1.8.8.1.01.15', '2.1.8.8.1.01.15', '2.1.8.8.1.01.16', '2.1.8.8.1.01.17', '2.1.8.8.1.01.99', '2.1.8.8.2.01.01', '2.1.8.8.2.01.04', '2.1.8.8.2.01.08', '2.1.8.8.3.01.02', '2.1.8.8.3.01.04'].include? conta_pcasp&.codigo_formatado 
				conta_pcasp_retencoes_e_consignacoes = true
			else
				conta_pcasp_retencoes_e_consignacoes = false
			end
		end

		def com_fonte_de_recursos_por_model
			case self.class.name
			when "Contabilidade::TalaoDeReceita"
				lancamentos_do_orcamento_da_receita.any?
			end
		end

		#private

		def mes_bloqueado?
			if retornar_data_referencia_por_objeto.present? && Configuracao.last.utiliza_evento_contabil?
				orcamento = orcamento.present? ? orcamento : Orcamento.find_by(exercicio: retornar_data_referencia_por_objeto.year)
				mes = Contabilidade::BloqueioMensalDoPcasp.find_by(mes_referencia: retornar_data_referencia_por_objeto.month, orcamento_id: orcamento.id, bloqueado: true)
				return mes.present?
			else
				return false
			end
		end

		def movimentacoes_sao_validas?
			return self.movimentacoes_do_plano_de_contas.select{|movimentacao| movimentacao.errors.present?}.blank?
		end

		def pode_deletar_movimentacoes?
			persisted? && (self.class.name == "Contabilidade::TalaoDeReceita" || self.class.name == "Contabilidade::Empenho" || self.class.name == "Contabilidade::Liquidacao" || self.class.name == "Contabilidade::EstornoDeLiquidacao" || self.class.name == "Contabilidade::TransferenciaFinanceira" || self.class.name == "Contabilidade::Pagamento" || self.class.name == "Contabilidade::EstornoDePagamento"  || self.class.name == "Contabilidade::PagamentoDaRetencao" || self.class.name == "Contabilidade::DespesaExtraOrcamentaria" || self.class.name == "Contabilidade::Obra" || self.class.name == "Contabilidade::MedicaoDaObra") 
		end

		def eh_solicitacao_orcamentaria?
			self.class.name == "Contabilidade::SolicitacaoDeAlteracaoOrcamentaria"
		end

		def deleta_movimentacoes_antigas(orcamento_atual = nil)
			if contexto_atual.present?
				@orcamento_atual = contexto_atual
			else
				@orcamento_atual = orcamento_atual
			end
			# if self.class.name == "Contabilidade::Empenho"
			# 	self.movimentacoes_do_plano_de_contas.select{ |m| m.regras_do_evento_de_acordo_com_o_gerador? == false }.each { |m| m.destroy }
			# end

			if @orcamento_atual.present?
				self.movimentacoes_do_plano_de_contas.joins(:evento_contabil).where('contabilidade_eventos_contabeis.orcamento_id = ?', @orcamento_atual.id).order(id: :desc).each do |movimentacao_do_plano_de_conta|
					movimentacoes_do_plano_de_contas.reload
					if self.class.name == "Contabilidade::CancelamentoDeRestoAPagar"
						self.restos_a_pagar_cancelados.each do |restos_a_pagar|
							evento_duplicado = self.movimentacoes_do_plano_de_contas.joins(:evento_contabil).where(
								contabilidade_eventos_contabeis: {
									id: movimentacao_do_plano_de_conta.evento_contabil.id,
									orcamento_id: @orcamento_atual
									}, 
								contabilidade_movimentacoes_do_plano_de_contas: {
									gerador_id: movimentacao_do_plano_de_conta.gerador_id,
									gerador_type: movimentacao_do_plano_de_conta.gerador_type,
									conta_por_evento_contabil_id: movimentacao_do_plano_de_conta.conta_por_evento_contabil_id,
									valor: restos_a_pagar.valor_cancelado.to_d
									}
								)

							# esta apagando os cancelamentos de mesmo valor
							#movimentacao_do_plano_de_conta.destroy if evento_duplicado.size >= 2
						end
					else
						evento_duplicado = self.movimentacoes_do_plano_de_contas.joins(:evento_contabil).where(
							contabilidade_eventos_contabeis: {
								id: movimentacao_do_plano_de_conta.evento_contabil.id,
								orcamento_id: @orcamento_atual
								}, 
							contabilidade_movimentacoes_do_plano_de_contas: {
								gerador_id: movimentacao_do_plano_de_conta.gerador_id,
								gerador_type: movimentacao_do_plano_de_conta.gerador_type,
								conta_por_evento_contabil_id: movimentacao_do_plano_de_conta.conta_por_evento_contabil_id
								}
							)

						eh_talao_orcamentario = self.class.name == 'Contabilidade::TalaoDeReceita' && self.orcamentario? && movimentacao_do_plano_de_conta&.conta_por_evento_contabil&.conta&.informacao_complementar_possui_fonte_de_recursos?
						eh_anulacao_de_talao_orcamentario = self.class.name == 'Contabilidade::AnulacaoDoTalaoDeReceita' && self.talao_de_receita.orcamentario? && movimentacao_do_plano_de_conta&.conta_por_evento_contabil&.conta&.informacao_complementar_possui_fonte_de_recursos?

						unless eh_talao_orcamentario == true || eh_anulacao_de_talao_orcamentario == true
							movimentacao_do_plano_de_conta.destroy if evento_duplicado.size >= 2
						end
					end
				end
			end
		end

		def deleta_movimentacoes_antigas_solicitacao_orcamentaria(orcamento_atual = nil)
			if contexto_atual.present?
				@orcamento_atual = contexto_atual
			else
				@orcamento_atual = orcamento_atual
			end

			unless @orcamento_atual.nil?
				self.movimentacoes_do_plano_de_contas.joins(:evento_contabil).where('contabilidade_eventos_contabeis.orcamento_id = ?', @orcamento_atual.id).order(id: :desc).each do |movimentacao_do_plano_de_conta|
					evento_duplicado = self.movimentacoes_do_plano_de_contas.joins(:evento_contabil).where(
						contabilidade_eventos_contabeis: {
							id: movimentacao_do_plano_de_conta.evento_contabil.id,
							orcamento_id: @orcamento_atual
							}, 
						contabilidade_movimentacoes_do_plano_de_contas: {
							gerador_id: movimentacao_do_plano_de_conta.gerador_id,
							gerador_type: movimentacao_do_plano_de_conta.gerador_type,
							valor: movimentacao_do_plano_de_conta.valor,
							conta_por_evento_contabil_id: movimentacao_do_plano_de_conta.conta_por_evento_contabil_id
							}
						)
						
						#movimentacao_do_plano_de_conta.destroy if evento_duplicado.size >= 2
				end
			end
		end

		def atribui_codigo_para_movimentacoes
			codigo = codigo_movimentado rescue id
			movimentacoes_do_plano_de_contas.update_all(codigo_movimentacao: codigo)
		end

		def verifica_se_ja_existe_balancete_de_verificacao_gerado_pro_mes(data=self.retornar_data_do_lancamento_por_objeto)
			#if (balancete_pcasp_gerado?(data) || self.mes_bloqueado?) && !ignora_validacao_do_balancete_de_validacao?
			#	errors.add(:mes_de_referencia, 'Já existe balancete de verificação gerado para o mês e não é possivel criar, editar ou apagar dados.')
			#	raise ActiveRecord::Rollback.new(self)
			#end
		end

		def retornar_data_referencia_por_objeto
			data_referencia = nil

			case self.class.name
			when "Contabilidade::Empenho"
				data_referencia = self.data_ref || self.data_do_empenho
			when "Contabilidade::Liquidacao"
				data_referencia = self.data_da_liquidacao
			when "Contabilidade::ItemDaNotaFiscal"
				data_referencia = self.liquidacao.data_da_liquidacao
			when "Contabilidade::Pagamento"
				data_referencia = self.data
			when "Contabilidade::EstornoDePagamento"
				data_referencia = self.data_do_estorno
			when "Contabilidade::NotaFiscal"
				data_referencia = self.data_de_emissao
			# when "GestaoDeEstoque::RecebimentoDeMaterial"
			# 	data_referencia = self.data_do_recebimento
			# when "Loa::OrcamentoDaDespesa"
			# 	data_referencia = primeiro_dia_util_do_ano
			when "Contabilidade::TalaoDeReceita"
				data_referencia = self.data_do_talao
			when 'Contabilidade::AnulacaoDoTalaoDeReceita'
				data_referencia = self.data_da_anulacao
			# when "Contabilidade::MedicaoDaObra"
			# 	data_referencia = self.data_inicial
			when "Contabilidade::AnulacaoDoEmpenho"
				data_referencia = self.data_da_anulacao
			# when "Contabilidade::Obra"
			# 	data_referencia = self.data_de_inicio
			# when "Administrativo::RequisicaoDeMaterial"
			# 	data_referencia = self.data_da_requisicao
			# when 'Contabilidade::DespesaExtraOrcamentaria'
			# 	data_referencia = self.data_de_emissao
			# when 'Contabilidade::EstornoDeDespesaExtraOrcamentaria'
			# 	data_referencia = self.data_do_estorno
			when "Contabilidade::EstornoDeLiquidacao"
				data_referencia = self.data_do_estorno
			# when 'Contabilidade::BloqueioDeDotacao'
			# 	if evento_contabil.configuracao_do_evento_contabil.status == "desbloqueado"
			# 		data_referencia = self.data_do_desbloqueio
			# 	else
			# 		data_referencia = self.data_do_bloqueio
			# 	end
			# when 'Contabilidade::SolicitacaoDeAlteracaoOrcamentaria'
			# 	data_referencia = self.data_da_solicitacao || self.data_da_legislacao
			# when 'Loa::OrcamentoDaReceita'
			# 	data_referencia = primeiro_dia_util_do_ano
			when "Licitacao::Contrato"
				data_referencia = self.data_de_envio_pro_sim
			when "Licitacao::Aditivo"
				data_referencia = self.data_de_envio_pro_sim
			# when 'Contabilidade::TransferenciaFinanceira'
			# 	data_referencia = self.data
			when "Contabilidade::TransferenciaDeSaldoPcasp"
				data_referencia = self.data_transferencia
			when "Contabilidade::Decreto"
				data_referencia = self.data_da_legislacao
			when "Contabilidade::SolicitacaoDeAlteracaoOrcamentaria"	
				data_referencia = self.data_da_solicitacao || self.decreto&.data_da_legislacao || self.empenho&.data_do_empenho || self.projeto&.data_do_projeto
			when "GestaoDeEstoque::Transferencia"
				data_referencia = self.data_de_transferencia
			when "Patrimonio::Transferencia"
				data_referencia = self.data_da_transferencia	
			end
			return data_referencia
		end

		def ignora_validacao_do_balancete_de_validacao?
			self.class.name == "GestaoDeEstoque::RecebimentoDeMaterial" || self.class.name == "GestaoDeEstoque::Transferencia" || self.class.name == "Loa::OrcamentoDaDespesa" || self.class.name == "Loa::OrcamentoDaReceita" || self.class.name == "Contabilidade::MedicaoDaObra" || self.class.name == "GestaoDeEstoque::RecebimentoDeMaterial"
		end

		def gerar_todos_os_movimentos(campo_de_data, orcamento)
			@contexto_atual = orcamento

			if campo_de_data.nil?
				case self.class.name
				when "Contabilidade::Liquidacao"
					campo_de_data = :data_da_liquidacao
				when "Contabilidade::EstornoDeLiquidacao"
					campo_de_data = :data_do_estorno
				when "Contabilidade::Pagamento"
					campo_de_data = :data
				when "Contabilidade::EstornoDePagamento"
					campo_de_data = :data_do_estorno
				when "Contabilidade::Empenho"
					campo_de_data = :data_do_empenho
				when "Contabilidade::AnulacaoDoEmpenho"
					campo_de_data = :data_da_anulacao
				when "Contabilidade::AnulacaoDoTalaoDeReceita"
					campo_de_data = :data_da_anulacao
				when "Contabilidade::TalaoDeReceita"
					campo_de_data = :data_do_talao
				when "Contabilidade::TransferenciaFinanceira"
					campo_de_data = :data
				when "Contabilidade::SolicitacaoDeAlteracaoOrcamentaria"
					campo_de_data = :data_da_solicitacao
				when "Contabilidade::DespesaExtraOrcamentaria"
					campo_de_data = :data_de_emissao
				when "Contabilidade::EstornoDeDespesaExtraOrcamentaria"
					campo_de_data = :data_de_emissao
				when "Contabilidade::BloqueioDeDotacao"
					campo_de_data = :data_do_bloqueio
				when "Contabilidade::CancelamentoDeRestoAPagar"
					campo_de_data = :data
				end
			end

			self.preencher_data(campo_de_data)
			self.nova_atribuicao_de_eventos_contabeis(orcamento)
			self.cria_eventos_contabeis_por_gerador
			self.apagar_movimentos(orcamento)
			self.define_tipo_de_movimentacao(orcamento)
			
			self.atribui_codigo_para_movimentacoes

			if eh_solicitacao_orcamentaria?
				self.deleta_movimentacoes_antigas_solicitacao_orcamentaria(orcamento)
			else
				self.deleta_movimentacoes_antigas(orcamento)
			end
		end
	end
end