class Orcamento < ApplicationRecord
	include SeedServicosConcern
	include SeedFuncoesESubFuncoes
	include SeedNaturezasDaReceita
	include SeedTiposDeOrcamento
	include SeedNaturezasDaAcao
	include SeedGruposDasFontesDeRecursos
	include SeedClassificacoesDaDespesa
	include SeedTiposDeAdministracao
	include SeedTiposDeUnidadesAdministrativas
	include SeedTiposDeEsfera
	include SeedClassificacoesDasFontesDeRecursos
	include SeedGrupoDeContasConcern
	include SeedContasConcern
	include SeedTiposDeDeducao
	include SeedReceitasStn
	include SeedNaturezasDaReceitaIniciais
	include SeedUnidadesDasContasBancarias
	include SeedContasExtraorcamentarias
	include SeedImpostosAliquotas
	include ValidaOrcamentoConcern
	include TradutorConcern
	include StatusLoaConcern

	has_paper_trail

	attr_accessor :criar_classificacoes_da_despesa, :importar_orgaos, :importar_acoes, :importar_despesas, :gerar_dependencias, :importar_do_orcamento_anterior
	attr_default :origem_da_importacao, 0
	attr_default :percentual_do_duodecimo, 0
	attr_default :status, :gerando_dependencias
	attr_default :obrigatorio_meta_fisica, :meta_fisica_obrigatoria_para_0_1_2
	attr_default :gerar_dependencias, true
	attr_default :importar_do_orcamento_anterior, true

	belongs_to :ppa, class_name: 'Ppa::Ppa'

	#Licitacao
	has_many :pedidos, class_name: 'Licitacao::Pedido'
	has_many :projetos, class_name: 'Licitacao::Projeto'
	has_many :pessoas_do_projeto, through: :projetos, class_name: 'Licitacao::PessoaDoProjeto'
	has_many :atas_de_registro_de_precos, through: :projetos, class_name: 'Licitacao::AtaDeRegistroDePrecos'
	has_many :processos, class_name: 'Licitacao::Processo'
	has_many :publicacoes, through: :projetos, class_name: 'Licitacao::Publicacao'
	has_many :comissoes, through: :projetos, class_name: 'Licitacao::Comissao'
	has_many :membros_das_comissoes, through: :projetos, source: :membros_da_comissao, class_name: 'Licitacao::MembroDaComissao'
	has_many :pessoas_dos_projetos, through: :projetos, source: :pessoas_do_projeto, class_name: 'Licitacao::PessoaDoProjeto'
	has_many :orcamentos_da_despesa_por_projetos, through: :projetos, source: :orcamentos_da_despesa_por_projetos, class_name: 'Licitacao::OrcamentoDaDespesaPorProjeto'
	has_many :itens_dos_lotes_dos_projetos, through: :projetos, source: :itens_do_lote, class_name: 'Licitacao::ItemDoLote'

	has_many :lotes, through: :projetos, source: :lotes, class_name: 'Licitacao::Lote'
	has_many :lances, through: :rodadas, source: :lances, class_name: 'Licitacao::Lance'
	has_many :rodadas, through: :lotes, source: :rodadas, class_name: 'Licitacao::Rodada'
	has_many :contratos, class_name: 'Licitacao::Contrato'
	has_many :aditivos, class_name: 'Licitacao::Aditivo'
	has_many :contratados, through: :contratos, class_name: 'Licitacao::Contratado'
	has_many :ordens_de_compra, class_name: 'Licitacao::OrdemDeCompra'
	has_many :solicitacao_de_alteracao_orcamentarias, class_name: 'Contabilidade::SolicitacaoDeAlteracaoOrcamentaria'

	# PROJEÇÃO DE RECEITA
	has_one :projecao_de_receita, class_name: 'Projecao::ProjecaoDeReceita', dependent: :destroy, as: :planejamento

	# BASE
	has_many :receitas_stn, class_name: 'Base::ReceitaStn', dependent: :destroy
	has_many :funcoes, class_name: 'Base::Funcao', as: :modulo, dependent: :destroy
	has_many :subfuncoes, through: :funcoes, class_name: 'Base::Subfuncao'
	has_many :naturezas_da_receita, class_name: 'Base::NaturezaDaReceita', as: :modulo
	has_many :tipos_de_administracao, class_name: 'Base::TipoDeAdministracao', as: :modulo, dependent: :destroy
	has_many :tipos_de_orcamento, class_name: 'Base::TipoDeOrcamento', as: :modulo, dependent: :destroy
	has_many :tipos_de_unidades_administrativas, class_name: 'Base::TipoDeUnidadeAdministrativa', as: :modulo, dependent: :destroy
	has_many :naturezas_da_acao, class_name: 'Base::NaturezaDaAcao', as: :modulo, dependent: :destroy
	has_many :grupos_das_fontes_de_recursos, class_name: 'Base::GrupoDaFonteDeRecursos', as: :modulo, dependent: :destroy
	has_many :fontes_tce, class_name: 'Base::FontesDeRecursos::FonteTCE', as: :modulo, dependent: :destroy
	has_many :fontes2018, class_name: 'Base::FontesDeRecursos::Fonte2018', as: :modulo, dependent: :destroy
	has_many :fontes_stn, class_name: 'Base::FontesDeRecursos::FonteStn', dependent: :destroy, inverse_of: :orcamento
	has_many :categorias_economicas, class_name: 'Base::CategoriaEconomica', as: :modulo, dependent: :destroy
	has_many :grupos_de_natureza_da_despesa, through: :categorias_economicas, class_name: 'Base::GrupoDeNaturezaDaDespesa'
	has_many :modalidades_de_aplicacao, through: :grupos_de_natureza_da_despesa, class_name: 'Base::ModalidadeDeAplicacao'
	has_many :elementos_de_despesa, through: :modalidades_de_aplicacao, class_name: 'Base::ElementoDeDespesa'
	has_many :sub_elementos_de_despesa, through: :elementos_de_despesa, class_name: "Contabilidade::SubElementoDeDespesa", dependent: :destroy
	has_many :tipos_de_esfera, class_name: 'Base::TipoDeEsfera', as: :modulo, dependent: :destroy
	has_many :tecnicos,class_name: 'Base::Tecnico', as: :modulo, dependent: :destroy

	# LOA
	has_many :orgaos, class_name: 'Loa::Orgao', dependent: :restrict_with_exception
	has_many :unidades_orcamentarias, through: :orgaos, class_name: 'Loa::UnidadeOrcamentaria'
	has_many :agente_publico, through: :unidades_orcamentarias, class_name: 'Base::AgentePublicoMunicipal'
	has_many :unidades_orcamentarias_por_usuario, through: :unidades_orcamentarias, class_name: 'Loa::UnidadeOrcamentariaPorUsuario'
	has_many :unidades_orcamentarias_por_natureza_da_receita, through: :unidades_orcamentarias, class_name: 'Loa::UnidadeOrcamentariaPorNaturezaDaReceita'
	has_many :orcamentos_da_receita, through: :unidades_orcamentarias_por_natureza_da_receita, class_name: 'Loa::OrcamentoDaReceita'
	has_many :programas_de_governo, class_name: 'Loa::ProgramaDeGoverno', dependent: :restrict_with_exception
	has_many :acoes, through: :programas_de_governo, class_name: 'Loa::Acao'
	has_many :subacoes, through: :acoes, class_name: 'Loa::Subacao'
	has_many :elementos_de_despesa_por_subacao, through: :subacoes, class_name: 'Loa::ElementoDeDespesaPorSubacao'
	has_many :orcamentos_da_despesa, through: :elementos_de_despesa_por_subacao, class_name: 'Loa::OrcamentoDaDespesa'
	has_many :dotacoes_destino, through: :orcamentos_da_despesa, class_name: 'Contabilidade::DotacaoDestino'
	has_many :dotacoes_origem, through: :orcamentos_da_despesa, class_name: 'Contabilidade::DotacaoOrigem'
	has_many :transferencias_de_recursos, class_name: 'Loa::TransferenciaDeRecurso', dependent: :restrict_with_exception
	has_many :tipos_de_deducao, class_name: 'Loa::TipoDeDeducao', dependent: :destroy
	has_many :alteracoes_de_status, class_name: 'Loa::AlteracaoDeStatus'
	has_many :cotas_orcamentarias, class_name: 'Loa::CotaOrcamentaria', dependent: :destroy

	has_many :temas_do_orcamento, class_name: 'Loa::TemaDoOrcamento', inverse_of: :orcamento, dependent: :destroy
	accepts_nested_attributes_for :temas_do_orcamento, allow_destroy: true

	# CONTABILIDADE
	has_many :investimentos_do_rpps, class_name: 'Contabilidade::InvestimentoDoRpps', dependent: :restrict_with_exception
	has_many :demonstrativos_de_informacoes_previdenciarias, class_name: 'Contabilidade::DemonstrativoDeInformacaoPrevidenciaria', dependent: :restrict_with_exception
	has_many :alocacoes_de_recurso_de_rpps, class_name: 'Contabilidade::AlocacaoDeRecursoDeRpps', dependent: :destroy
	has_many :percentuais_da_alocacao_de_recurso, through: :alocacoes_de_recurso_de_rpps, class_name: "Contabilidade::PercentualDaAlocacaoDeRecurso"
	has_many :conselhos_de_rpps, class_name: 'Contabilidade::ConselhoDeRpps', dependent: :restrict_with_exception
	has_many :aportes_despesas, class_name: 'Contabilidade::AporteDespesa', dependent: :restrict_with_exception
	has_many :empenhos, class_name: 'Contabilidade::Empenho', dependent: :restrict_with_exception
	has_many :anulacoes_do_empenho, through: :empenhos, class_name: "Contabilidade::AnulacaoDoEmpenho", dependent: :destroy
	has_many :liquidacoes, class_name: 'Contabilidade::Liquidacao'
	has_many :estornos_de_liquidacao, through: :liquidacoes, class_name: "Contabilidade::EstornoDeLiquidacao", dependent: :destroy
	has_many :pagamentos, class_name: 'Contabilidade::Pagamento'
	has_many :estornos_de_pagamento, through: :pagamentos, class_name: "Contabilidade::EstornoDePagamento", dependent: :destroy
	has_many :taloes_de_receita, class_name: 'Contabilidade::TalaoDeReceita', dependent: :restrict_with_exception
	has_many :anulacoes_dos_taloes_de_receita, through: :taloes_de_receita, class_name: "Contabilidade::AnulacaoDoTalaoDeReceita", dependent: :destroy
	has_many :convenios, class_name: 'Contabilidade::Convenio', dependent: :restrict_with_exception
	has_many :obras, class_name: 'Contabilidade::Obra', dependent: :restrict_with_exception
	has_many :operacoes_de_credito, through: :obras, class_name: "Obra::OperacaoDeCredito", dependent: :destroy
	has_many :diarias, class_name: 'Contabilidade::Diaria', dependent: :restrict_with_exception
	has_many :passagens, class_name: 'Contabilidade::Passagem', dependent: :restrict_with_exception
	has_many :agencias, class_name: 'Base::Agencia', dependent: :restrict_with_exception # É DO MÓDULO BASE, MAS SÓ É USADA NA CONTABILIDADE
	has_many :contas_bancarias, through: :agencias, class_name: "Base::ContaBancaria"
	has_many :classificacoes_das_fontes_de_recursos, class_name: "Base::ClassificacaoDaFonteDeRecursos", as: :modulo, dependent: :destroy
	has_many :contas_extra_orcamentarias, class_name: 'Contabilidade::ContaExtraOrcamentaria', dependent: :destroy
	has_many :contas_extra_por_unidades_orcamentarias, through: :contas_extra_orcamentarias, class_name: 'Contabilidade::ContaExtraPorUnidadeOrcamentaria'
	has_many :anulacoes_da_conta_extra, class_name: 'Contabilidade::AnulacaoDaContaExtra'
	has_many :despesas_extra_orcamentarias, class_name: "Contabilidade::DespesaExtraOrcamentaria", dependent: :destroy
	has_many :imposto_sobre_servicos, class_name: "Contabilidade::ImpostoSobreServico", dependent: :destroy
	has_many :irrfs_pessoas_juridicas, class_name: "Contabilidade::IrrfPessoaJuridica", dependent: :destroy
	has_many :inss_pessoas_juridicas, class_name: "Contabilidade::InssPessoaJuridica", dependent: :destroy
	has_many :decretos, class_name: "Contabilidade::Decreto", dependent: :destroy
	has_many :transferencias_financeiras, class_name: "Contabilidade::TransferenciaFinanceira", dependent: :destroy
	has_many :transferencias_nao_financeiras, class_name: "Contabilidade::TransferenciaNaoFinanceira", dependent: :destroy
	has_many :cancelamentos_de_restos_a_pagar, class_name: "Contabilidade::CancelamentoDeRestoAPagar", dependent: :destroy
	has_many :controle_de_pagamentos, class_name: "Contabilidade::ControleDePagamento", dependent: :destroy
	has_many :comites_de_investimento, class_name: "Contabilidade::ComiteDeInvestimento", dependent: :destroy
	has_many :parcelamentos_do_rpps, class_name: 'Contabilidade::ParcelamentoDoRpps', dependent: :destroy

	# CONTABILIDADE > PLANO DE CONTAS
	has_many :grupo_de_contas, class_name: 'Contabilidade::GrupoDeConta', dependent: :destroy
	has_many :contas, class_name: 'Contabilidade::Conta', dependent: :destroy
	has_many :eventos_contabeis, class_name: "Contabilidade::EventoContabil", dependent: :restrict_with_exception
	has_many :contas_por_eventos_contabeis, through: :eventos_contabeis, class_name: "Contabilidade::ContaPorEventoContabil", dependent: :restrict_with_exception
	has_many :movimentacoes_do_plano_de_contas, through: :contas_por_eventos_contabeis, class_name: "Contabilidade::MovimentacaoDoPlanoDeContas", dependent: :restrict_with_exception
	has_many :balancetes_de_verificacoes, class_name: "Contabilidade::BalanceteDeVerificacao"
	has_many :sub_contas_pcasp, class_name: "Contabilidade::SubContaPcasp", dependent: :destroy
	has_many :bloqueios_mensais_do_pcasp, class_name: "Contabilidade::BloqueioMensalDoPcasp", dependent: :destroy

	# TCM
	has_many :lotes_do_tcm, class_name: "Tcm::Lote", dependent: :destroy
	has_many :erros_dos_lotes, class_name: "Tcm::ErrosDoLote", dependent: :destroy

	# GESTÃO DE ESTOQUE
	has_many :almoxarifados, class_name: 'GestaoDeEstoque::Almoxarifado', dependent: :destroy
	has_many :recebimento_de_materiais, class_name: 'GestaoDeEstoque::RecebimentoDeMaterial'
	has_many :movimentacoes_do_estoque, class_name: 'GestaoDeEstoque::MovimentacaoDoEstoque'
	has_many :encerramentos, class_name: 'GestaoDeEstoque::ControleDoAlmoxarifado'
	has_many :estoques, class_name: 'GestaoDeEstoque::Estoque'

	# PATRIMÔNIO
	has_many :transferencias_patrimoniais, class_name: 'Patrimonio::Transferencia'
	has_many :requisicoes_patrimoniais, class_name: 'Patrimonio::RequisicaoPatrimonial'

	# ADMINISTRATIVO
	has_many :requisicoes_de_materiais, class_name: 'Administrativo::RequisicaoDeMaterial'

	#PCA
	has_many :acoes_pca, class_name: 'Pca::Acao', dependent: :destroy
	has_many :orcamentos_da_despesa_por_acao, through: :acoes_pca, class_name: 'Pca::OrcamentoDaDespesaPorAcao'

	after_create :cria_receitas_stn_por_funcao, if: Proc.new { self.exercicio.to_i > 2017 } #precisa do excel de ementario da receita

	after_update :copia_valores_para_campos_orcados, if: Proc.new{ fechado? && status_was == "aberto" }

	validate :verificar_exercicio_do_ppa, if: Proc.new{|orcamento| orcamento.ppa_id.present? && orcamento.exercicio.present?}

	validates_presence_of :exercicio, :prefeito, :vice_prefeito
	validates_presence_of :percentual_despesa_com_pessoal
	validates_presence_of :numero_da_lei, :numero_ldo
	validates_presence_of :status
	validates_uniqueness_of :exercicio

	validates_length_of :exercicio, is: 4

	validates_numericality_of :percentual_da_reserva_de_contingencia, greater_than_or_equal_to: 0, less_than: 100, allow_nil: true
	validates_numericality_of :percentual_normativo_da_ldo, greater_than_or_equal_to: 0, less_than: 100, allow_nil: true
	validates_numericality_of :percentual_despesa_com_pessoal, greater_than_or_equal_to: 0, less_than: 100

	validates :exercicio, immutable: true

	validate :valor_percentual_da_reserva_de_contingencia, if: Proc.new{|orcamento| orcamento.percentual_da_reserva_de_contingencia.present?}
	validates :trabalha_com_subacao, immutable: true, if: Proc.new { acoes.any? }

	validates :ppa_id, immutable: { message: "não pode ser alterado após ser utilizado na importação dos programas" } , if: :ppa_esta_sendo_utilizado?, on: :update
	validate :utilizar_projecao_do_ppa_se_ppa_selecionado, if: Proc.new{|orcamento| orcamento.utilizar_projecao_do_ppa.present?}

	validate :valida_data_final_da_proposta_setorial, if: proc { self.prazo_final_proposta_setorial.present? }

	has_attached_file :arquivo_de_contexto
	validates_attachment_content_type :arquivo_de_contexto, content_type: "application/pdf"
	validates_attachment_size :arquivo_de_contexto, in: 0..10.megabytes

	before_destroy :deleta_receitas_do_orcamento

	enum status: STATUS_DO_ORCAMENTO
	enum origem_da_importacao: {
		nao_importado: 0,
		api_do_tcm: 1,
		outros_sistemas: 2
	}

	enum obrigatorio_meta_fisica: {
		meta_fisica_obrigatoria_para_0_1_2: 1,
		meta_fisica_obrigatoria_para_1: 2,
		meta_fisica_nao_obrigatoria: 3
	}

	scope :ativos, -> { where(status: [:aberto, :enviado_para_votacao, :em_alteracao, :aprovado, :encerrado]) }
	scope :aprovados, -> { where(status: [:aprovado, :encerrado]) }

	def pode_modificar_o_orcamento?
		self.aberto? || self.enviado_para_votacao? || self.em_alteracao?
	end

	def cria_receitas_stn_por_funcao
		cria_receitas_stn(true)
	end

	def importar_despesa_orcamento_anterior
		ActiveRecord::Base.transaction do
			::DuplicarOrcamento.new(self, orcamento_anterior).perform if orcamento_anterior.present?
		end
	end

	def orcamento_anterior
		@orcamento_anterior ||= Orcamento.find_by_exercicio(exercicio.to_i - 1)
	end

	def fontes_de_recursos
		(self.exercicio.to_i > 2018) ? fontes_tce : fontes2018
	end

	def deleta_receitas_do_orcamento
		ActiveRecord::Base.transaction do
			begin
				receitas = self.naturezas_da_receita.where(analitica: true, valor_previsto: nil)
				receitas.each do |receita|
					receita.destroy
				end
				if self.naturezas_da_receita.count > 0
					raise ActiveRecord::Rollback, 'Não foi possivel excluir o Orçamento pois existem receitas com valor'
				end
			end
		end
	end

	def importado?
		!(origem_da_importacao.nil? || nao_importado?)
	end

	def orcamento_confirmado_ou_encerrado?
		self.aprovado? || self.encerrado?
	end

	def cabecalho_do_loa_por_status_do_orcamento
		if self.orcamento_confirmado_ou_encerrado?
			"Lei Orçamentária Anual"
		else
			"Projeto de Lei Orçamentária Anual"
		end
	end

	def saldo_superavit
		self.superavit_financeiro.to_f - self.solicitacao_de_alteracao_orcamentarias.superavit_financeiro.sum(&:valor_a_suplementar).to_f
	end

	def valor_de_anulacoes
		self.solicitacao_de_alteracao_orcamentarias.anulacao_de_dotacao.sum(&:valor_a_suplementar)
	end

	def valor_de_operacao_de_credito
		self.solicitacao_de_alteracao_orcamentarias.operacao_de_credito.sum(&:valor_a_suplementar)
	end

	def utilizar_projecao_do_ppa_se_ppa_selecionado
		if utilizar_projecao_do_ppa? && ppa_id.nil?
			errors.add(:utilizar_projecao_do_ppa, "Só deve ser marcado se um PPA for selecionado.")
		end
	end

	def verificar_exercicio_do_ppa
		ppa = Ppa::Ppa.find_by_id(self.ppa_id)
		unless (ppa.exercicio_inicial..ppa.exercicio_final).include? self.exercicio.to_i
			errors[:ppa_id] << "O exercicio do orçamento deve estar no intervalo do PPA"
			return false
		end
	end

	def quantidade_de_receitas_a_preencher
		self.orcamentos_da_receita.where(forma_de_adicao: :original).where("valor = 0 or valor is null").count
	end

	def possui_orcamento_da_receita_vazio?
		self.quantidade_de_receitas_a_preencher > 0
	end

	def quantidade_de_despesas_a_preencher
		self.orcamentos_da_despesa.where(de_credito_adicional: false).where("valor = 0 or valor is null").count
	end

	def possui_orcamento_da_despesa_vazio?
		self.quantidade_de_despesas_a_preencher > 0
	end

	def ppa_do_orcamento
		Ppa::Ppa.where("exercicio_inicial <= ? and exercicio_final >= ?", self.exercicio, self.exercicio).last
	end

	def valor_duodecimo_camara
	self.subacoes.joins(unidade_orcamentaria: :tipo_de_unidade_administrativa).where(base_tipos_de_unidades_administrativas: {descricao:'Câmara Municipal'}).inject(0) { |total, despesa|
			total + despesa.valor_total_fixado_da_despesa.to_f }
	end

	def valor_percentual_da_reserva_de_contingencia
		if self.percentual_da_reserva_de_contingencia.to_f > percentual_normativo_da_ldo.to_f
			errors[:percentual_da_reserva_de_contingencia ] << "deve ser menor ou igual ao percentual normativo da LDO para reserva de contingência"
		end
	end

	def valida_data_final_da_proposta_setorial
		errors.add(:prazo_final_proposta_setorial, 'deve ser maior que o prazo inicial') unless self.prazo_final_proposta_setorial >= self.prazo_inicial_proposta_setorial
	end

	def esta_no_prazo_para_envio_setorial?
		if self.prazo_inicial_proposta_setorial.present? && self.prazo_final_proposta_setorial.present?
			Date.today >= self.prazo_inicial_proposta_setorial && Date.today <= self.prazo_final_proposta_setorial
		else
			false
		end
	end

	def prazo_para_envio_setorial_expirado?
		if prazo_final_proposta_setorial.present?
			!esta_no_prazo_para_envio_setorial? && Date.today > self.prazo_final_proposta_setorial
		else
			true
		end
	end

	def valor_da_reserva_de_contigencia_projetado
		self.valor_total_da_receita_corrente_liquida.to_f * (self.percentual_normativo_da_ldo.to_f / 100)
	end

	def valor_total_das_deducoes_da_rcl
		receitas_de_deducao = ['0012100420000000', 'falta essa', '0017580111100000']
		return self.naturezas_da_receita.where(codigo: receitas_de_deducao).to_a.sum(&:total_previsto_agregado)
	end

	def valor_total_da_receita_corrente_liquida
		total_receitas_correntes = self.naturezas_da_receita.where("origem = '0' and categoria_economica = '001'").to_a.sum(&:total_previsto_agregado)
		return total_receitas_correntes - valor_total_das_deducoes_da_rcl
	end

	def to_sim
		begin
			texto = ""
			texto << "200".to_s.sim_preenche(3) + ","
			texto << Configuracao.first.codigo_do_municipio_no_tcm.to_s.sim_preenche(3) + "," # criar campo na tabela de configuração
			texto << exercicio.to_s.sim_limite_sem_aspas(4, "00") + ","
			texto << numero_da_lei.to_s.sim_limite(10) + "," #Número da Lei do Orçamento
			texto << valor_total_fixado_da_despesa.to_f.to_s.sim_valor + "," #Valor Total Fixado no Orçamento
			texto << (data_de_envio.nil? ? "".sim_limite(1) : data_de_envio.sim_data) + "," #Data de envio do projeto de LOA
			texto << (data_de_aprovacao.nil? ? "".sim_limite(1) : data_de_aprovacao.sim_data) + "," #Data de aprovação do projeto
			texto << (data_de_publicacao.nil? ? "".sim_limite(1) : data_de_publicacao.sim_data) #Data de Publicação da LOA
			return texto
		rescue => e
			if e.class.to_s == "NoMethodError"
				atributo_falho = e.message.split(" ")[2]
				coluna = CSV.parse(texto, :headers => false).last.count
				raise e.mensagem_traduzida(self, self.exercicio, atributo_falho, coluna)
			else
				raise e
			end
		end
	end

	def to_param
		exercicio.to_s
	end

	def convenios_ppa_que_possui_codigo?
		self.ppa.convenios.any?{|convenio| convenio.numero_do_convenio.present?}
	end

	def tem_convenio_ppa_nao_importado?
		self.convenios.count < self.ppa.convenios.count if self.convenios
	end

	def valor_do_superafit


	end

	def foi_constituida_a_reserva_de_contingencia?
		return reservas_de_contingencia.present?
	end

	def unidade_arrecadadora
		self.unidades_orcamentarias.find_by(is_unidade_arrecadadora: true)
	end

	def valor_total_fixado_da_despesa(tipo_de_orcamento = nil)
		if tipo_de_orcamento.present?
			self.subacoes.where(tipo_de_orcamento: tipo_de_orcamento).inject(0) { |total, despesa|
				total + despesa.valor_total_fixado_da_despesa.to_f
			}
		else
			self.subacoes.inject(0) { |total, despesa|
				total + despesa.valor_total_fixado_da_despesa.to_f
			}
		end
	end

	def valor_total_realizado_da_despesa
		self.elementos_de_despesa.inject(0) { |total, despesa|
			total + despesa.valor_total_realizado_da_despesa.to_f
		}
	end

	def valor_total_fixado_da_despesa_por_funcao_e_codigos_dos_elementos (funcao, codigos)
		if funcao.present? && codigos.present?
			total_a_retornar = self.subacoes.where(funcao: funcao).inject(0) { |total, subacao|
				total + subacao.orcamentos_da_despesa.joins(elemento_de_despesa_por_subacao: :elemento_de_despesa).where(base_elementos_de_despesa: {codigo: codigos}).sum(:valor).to_f
			}
		else
			0
		end
	end

	def valor_total_previsto_da_receita(tipo_de_orcamento = nil)
		if tipo_de_orcamento.present?
			self.naturezas_da_receita.where(tipo_de_orcamento: tipo_de_orcamento).inject(0) { |total, receita|
				total + receita[:valor_previsto].to_f
			}
		else
			self.naturezas_da_receita.inject(0) { |total, receita|
				total + receita[:valor_previsto].to_f
			}
		end
	end

	def valor_total_realizado_da_receita
		self.naturezas_da_receita.inject(0) { |total, receita|
			total + receita.valor_total_realizado_da_receita.to_f
		}
	end

	def valor_total_gasto_com_magisterio
		funcao_educacao = self.funcoes.find_by(codigo: 12)
		self.subacoes.where(funcao: funcao_educacao, despesa_da_educacao: 2).inject(0) { |total, subacao|
			total + subacao.valor_total_fixado_da_despesa.to_f
		}
	end

	def valor_total_gasto_com_fundeb_quarenta
		self.fontes_de_recursos.where(codigo:14).inject(0) { |total, fonte|
			total + fonte.total_da_despesa.to_f
		}
	end

	def valor_encargos_sociais_masgisterio
		resultado = 0
		codigos = ['31911300', '31901300']
		funcao_educacao = self.funcoes.find_by(codigo: 12)
			self.subacoes.where(funcao: funcao_educacao, despesa_da_educacao: 2).each { |subacao|
						resultado += subacao.orcamentos_da_despesa.joins(elemento_de_despesa_por_subacao: :elemento_de_despesa).where(base_elementos_de_despesa: {codigo: codigos}).sum(:valor).to_f
			}
			return resultado
	end

	def valor_remuneracao_professores_magisterio
		resultado = 0
		funcao_educacao = self.funcoes.find_by(codigo: 12)
			self.subacoes.where(funcao: funcao_educacao, despesa_da_educacao: 2).each { |subacao|
						resultado += subacao.orcamentos_da_despesa.joins(elemento_de_despesa_por_subacao: [elemento_de_despesa: [modalidade_de_aplicacao: :grupo_de_natureza_da_despesa]]).where("base_grupos_de_natureza_da_despesa.codigo = '31000000'").sum(:valor).to_f
			}
			return resultado - valor_encargos_sociais_masgisterio
	end


	def valor_total_das_receitas_do_fundeb
		if utiliza_novo_tipo_para_receita?
			receitas = ["0017580110000000", "0017580120000000"]
		else
			receitas = ["1325010200", "1724010000", "1724020000"]
		end
		self.naturezas_da_receita.where("codigo in (?)", receitas).inject(0) { |total, receita|
			total + receita.total_previsto_agregado.to_f
		}
	end

	def percentual_ideal_para_gasto_com_magisterio
		valor_total_das_receitas_do_fundeb.to_f > 0 ?	(valor_total_das_receitas_do_fundeb.to_f * 0.6).round(2) : 0
	end

	def percentual_gasto_com_magisterio
		valor_total_das_receitas_do_fundeb.to_f > 0 ? ((100 * valor_total_gasto_com_magisterio.to_f) / valor_total_das_receitas_do_fundeb.to_f).round(2) : 0
	end

	def valor_total_das_receitas_por_fonte_de_recurso codigo_da_fonte
		fonte_de_recursos = self.fontes_de_recursos.find_by(codigo: codigo_da_fonte.to_s)
		if fonte_de_recursos != nil
			Loa::OrcamentoDaReceita.joins(:fonte_de_recursos).where(base_fontes_de_recursos: {id: fonte_de_recursos.id}).sum(:valor)
		end
	end

	def valor_total_das_receitas_que_contem_a_fonte_de_recurso codigo_da_fonte
		fonte_de_recurso_educacao = self.fontes_de_recursos.find_by(codigo: codigo_da_fonte.to_s)
		Base::NaturezaDaReceita.joins(orcamentos_da_receita: :fonte_de_recursos).where(base_fontes_de_recursos: {id: fonte_de_recurso_educacao.id}).sum(:valor_previsto)
	end

	def percentual_ideal_das_receitas_que_contem_a_fonte_de_recurso codigo_da_fonte, percentual
		valor_total_das_receitas_que_contem_a_fonte_de_recurso(codigo_da_fonte).to_f > 0 ?	(valor_total_das_receitas_que_contem_a_fonte_de_recurso(codigo_da_fonte).to_f * (percentual.to_f / 100)).round(2) : 0
	end

	def valor_total_da_despesa_por_subfuncao (subfuncao)
		if subfuncao.present?
			total_a_retornar = self.subacoes.where(subfuncao: subfuncao).inject(0) { |total, subacao|
				total + subacao.valor_total_fixado_da_despesa.to_f
			}
		else
			0
		end
	end

	def valor_total_da_despesa_por_funcao (funcao)
		if funcao.present?
			total_a_retornar = self.subacoes.where(funcao: funcao).inject(0) { |total, subacao|
				total + subacao.valor_total_fixado_da_despesa.to_f
			}
		else
			0
		end
	end

	def valor_total_da_despesa_por_funcao_e_fonte (funcao, fonte_de_recursos, excecoes = [])
		if funcao.present? && fonte_de_recursos.present?
			total_a_retornar = self.subacoes.where(funcao: funcao).where.not(subfuncao: excecoes).inject(0) { |total, subacao|
				total + subacao.orcamentos_da_despesa.where(fonte_de_recursos: fonte_de_recursos).sum(:valor).to_f
			}
		else
			0
		end
	end

	def valor_total_das_despesas_voluntarias_da_educacao
		total = 0
		excecoes_de_subfuncoes = self.subfuncoes.where(codigo: [362, 363, 364])
		['08', '10', '15', '19'].each do |codigo_da_fonte|
			total += self.valor_total_da_despesa_por_funcao_e_fonte(self.funcoes.find_by(codigo: '12'), self.fontes_de_recursos.find_by(codigo: codigo_da_fonte), excecoes_de_subfuncoes)
		end
		return total
	end

	def valor_total_do_ganho_e_complementacao_do_fundeb
		return self.valor_total_da_complementacao_do_fundeb + (self.valor_total_das_transferencias_do_fundeb - self.valor_total_do_ganho_do_fundeb)
	end

	def valor_total_da_complementacao_do_fundeb
		self.naturezas_da_receita.where("codigo = ?", "0017580121000000").to_a.sum(&:total_previsto_agregado)
	end

	def valor_percentual_do_duodecimo total
			if self.percentual_do_duodecimo.to_f > 0
				total_com_percentual =	total * (self.percentual_do_duodecimo / 100)
			else
				total_com_percentual =  total * 0.07.to_f
			end
				return total_com_percentual
	end

	def valor_percentual_do_duodecimo_mensal total
			percentual_do_duodecimo = (total.to_f / 12).to_f
			return percentual_do_duodecimo
	end

	def valor_total_do_ganho_do_fundeb
		if utiliza_novo_tipo_para_receita?
			receitas = ["0017180121000000", "0017180151000000", "0017180611000000", "0017280111000000", "0017280121000000", "0017280131000000"]
		else
			receitas = ["1721010200", "1721010500", "1721360000", "1722010100", "1722010200", "1722010400"]
		end
		ganho_do_fundeb = self.naturezas_da_receita.where("codigo in (?)", receitas).inject(0) { |total, receita|
			total + (receita.total_previsto_agregado.to_f * 0.2)
		}
		return ganho_do_fundeb
	end

	def valor_total_das_transferencias_do_fundeb
		self.naturezas_da_receita.where("codigo = ?", "0017580111000000").to_a.sum(&:total_previsto_agregado)
	end

	def total_impostos_e_transferencias_das_receitas_por_fonte_de_recurso (fonte_de_recursos)
		total = 0
		if fonte_de_recursos != nil
			receitas_base_ids = ::Base::NaturezaDaReceita.joins(orcamentos_da_receita: :fonte_de_recursos).where(base_fontes_de_recursos: {id: fonte_de_recursos.id}, origem: '1', detalhamento_optativo: '1').ids
			total += self.naturezas_da_receita.where(id: receitas_base_ids, origem: '1', detalhamento_optativo: '1').to_a.sum(&:valor_total)

			receitas_da_divida_ids = ::Base::NaturezaDaReceita.joins(orcamentos_da_receita: :fonte_de_recursos).where(base_fontes_de_recursos: {id: fonte_de_recursos.id}, origem: '1', detalhamento_optativo: '3').ids
			total += self.naturezas_da_receita.where("id in (?) and origem = '1' and detalhamento_optativo = '3'", receitas_da_divida_ids).to_a.sum(&:valor_total)

			receitas_de_juros_e_multas_ids = ::Base::NaturezaDaReceita.joins(orcamentos_da_receita: :fonte_de_recursos).where(base_fontes_de_recursos: {id: fonte_de_recursos.id}, origem: '1', detalhamento_optativo: ['2','4']).ids
			total += self.naturezas_da_receita.where("id in (?) and origem = '1' and detalhamento_optativo in ('2','4')", receitas_de_juros_e_multas_ids).to_a.sum(&:valor_total)
		end

		if utiliza_novo_tipo_para_receita?
			receitas = ["0017180121000000", "0017180151000000", "0017180611000000", "0017280111000000", "0017280121000000", "0017280131000000"]
		else
			receitas = ["1721010200", "1721010500", "1721360000", "1722010100", "1722010200", "1722010400"]
		end
		total += self.naturezas_da_receita.where("codigo in (?)", receitas).to_a.sum(&:valor_total)

		return total
	end

	def valor_a_aplicar_em_educacao
		fonte_de_recurso_educacao = self.fontes_de_recursos.find_by(codigo: "02")
		self.total_impostos_e_transferencias_das_receitas_por_fonte_de_recurso(fonte_de_recurso_educacao).to_f * 0.25
	end

	def valor_a_aplicar_em_saude
		fonte_de_recurso_saude = self.fontes_de_recursos.find_by(codigo: "03")
		self.total_impostos_e_transferencias_das_receitas_por_fonte_de_recurso(fonte_de_recurso_saude).to_f * 0.15
	end

	def valor_total_das_despesas_com_inativos_e_pensionistas
		funcao_saude = self.funcoes.find_by(codigo: '10')
		valor_total_fixado_da_despesa_por_funcao_e_codigos_dos_elementos(funcao_saude, ["31900100", "31900300"])
	end

	def valor_total_das_despesas_voluntarias_da_saude
		total = 0
		['07', '09', '16', '20'].each do |codigo_da_fonte|
			total += self.valor_total_da_despesa_por_funcao_e_fonte(self.funcoes.find_by(codigo: '10'), self.fontes_de_recursos.find_by(codigo: codigo_da_fonte))
		end
		return total
	end

	def valor_total_aplicado_em_educacao
		funcao_educacao = self.funcoes.find_by(codigo: '12')
		self.valor_total_da_despesa_por_funcao(funcao_educacao).to_f - self.valor_total_da_despesa_por_subfuncao(self.subfuncoes.find_by(codigo: '362')).to_f - self.valor_total_da_despesa_por_subfuncao(self.subfuncoes.find_by(codigo: '363')).to_f - self.valor_total_da_despesa_por_subfuncao(self.subfuncoes.find_by(codigo: '364')).to_f - self.valor_total_das_despesas_voluntarias_da_educacao.to_f - self.valor_total_do_ganho_e_complementacao_do_fundeb.to_f
	end

	def valor_total_aplicado_em_saude
		funcao_saude = self.funcoes.find_by(codigo: '10')
		self.valor_total_da_despesa_por_funcao(funcao_saude).to_f - valor_total_das_despesas_com_inativos_e_pensionistas.to_f - self.valor_total_das_despesas_voluntarias_da_saude.to_f
	end

	def valor_total_pessoal_e_encargos_sociais_orcamento_fiscal
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "F" && orc.elemento_de_despesa.codigo[0..1] == "31"}.sum(&:valor_fixado)
	end

	def valor_total_pessoal_e_encargos_sociais_orcamento_fiscal_por_unidade(unidade_orcamentaria_id)
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "F" && orc.elemento_de_despesa.codigo[0..1] == "31" && orc.subacao.unidade_orcamentaria_id == unidade_orcamentaria_id}.sum(&:valor_fixado)
	end

	def valor_total_juros_e_encargos_da_divida_orcamento_fiscal
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "F" && orc.elemento_de_despesa.codigo[0..1] == "32"}.sum(&:valor_fixado)
	end

	def valor_total_juros_e_encargos_da_divida_orcamento_fiscal_por_unidade(unidade_orcamentaria_id)
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "F" && orc.elemento_de_despesa.codigo[0..1] == "32" && orc.subacao.unidade_orcamentaria_id == unidade_orcamentaria_id}.sum(&:valor_fixado)
	end

	def valor_total_outras_despesas_correntes_orcamento_fiscal
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "F" && orc.elemento_de_despesa.codigo[0..1] == "33"}.sum(&:valor_fixado)
	end

	def valor_total_outras_despesas_correntes_orcamento_fiscal_por_unidade(unidade_orcamentaria_id)
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "F" && orc.elemento_de_despesa.codigo[0..1] == "33" && orc.subacao.unidade_orcamentaria_id == unidade_orcamentaria_id}.sum(&:valor_fixado)
	end

	def valor_total_investimentos_orcamento_fiscal
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "F" && orc.elemento_de_despesa.codigo[0..1] == "44"}.sum(&:valor_fixado)
	end

	def valor_total_investimentos_orcamento_fiscal_por_unidade(unidade_orcamentaria_id)
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "F" && orc.elemento_de_despesa.codigo[0..1] == "44" && orc.subacao.unidade_orcamentaria_id == unidade_orcamentaria_id}.sum(&:valor_fixado)
	end

	def valor_total_inversoes_financeiras_orcamento_fiscal
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "F" && orc.elemento_de_despesa.codigo[0..1] == "45"}.sum(&:valor_fixado)
	end

	def valor_total_inversoes_financeiras_orcamento_fiscal_por_unidade(unidade_orcamentaria_id)
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "F" && orc.elemento_de_despesa.codigo[0..1] == "45" && orc.subacao.unidade_orcamentaria_id == unidade_orcamentaria_id}.sum(&:valor_fixado)
	end

	def valor_total_amortizacao_da_divida_orcamento_fiscal
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "F" && orc.elemento_de_despesa.codigo[0..1] == "46"}.sum(&:valor_fixado)
	end

	def valor_total_amortizacao_da_divida_orcamento_fiscal_por_unidade(unidade_orcamentaria_id)
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "F" && orc.elemento_de_despesa.codigo[0..1] == "46"  && orc.subacao.unidade_orcamentaria_id == unidade_orcamentaria_id}.sum(&:valor_fixado)
	end

	def valor_total_reserva_de_contingencia_orcamento_fiscal
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "F" && orc.elemento_de_despesa.codigo[0..1] == "99"}.sum(&:valor_fixado)
	end

	def valor_total_reserva_de_contingencia_orcamento_fiscal_por_unidade(unidade_orcamentaria_id)
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "F" && orc.elemento_de_despesa.codigo[0..1] == "99" && orc.subacao.unidade_orcamentaria_id == unidade_orcamentaria_id}.sum(&:valor_fixado)
	end

	def valor_total_orcamento_fiscal
		(valor_total_pessoal_e_encargos_sociais_orcamento_fiscal.to_d + valor_total_juros_e_encargos_da_divida_orcamento_fiscal.to_d + valor_total_outras_despesas_correntes_orcamento_fiscal.to_d + valor_total_investimentos_orcamento_fiscal.to_d + valor_total_inversoes_financeiras_orcamento_fiscal.to_d + valor_total_amortizacao_da_divida_orcamento_fiscal.to_d + valor_total_reserva_de_contingencia_orcamento_fiscal.to_d)
	end

	def valor_total_orcamento_fiscal_por_unidade(unidade_orcamentaria_id)
		(valor_total_pessoal_e_encargos_sociais_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_juros_e_encargos_da_divida_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_outras_despesas_correntes_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_investimentos_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_inversoes_financeiras_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_amortizacao_da_divida_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_reserva_de_contingencia_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d)
	end

	def valor_total_pessoal_e_encargos_sociais_seguridade_social
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "S" && orc.elemento_de_despesa.codigo[0..1] == "31"}.sum(&:valor_fixado)
	end

	def valor_total_pessoal_e_encargos_sociais_seguridade_social_por_unidade(unidade_orcamentaria_id)
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "S" && orc.elemento_de_despesa.codigo[0..1] == "31" && orc.subacao.unidade_orcamentaria_id == unidade_orcamentaria_id}.sum(&:valor_fixado)
	end

	def valor_total_juros_e_encargos_da_divida_seguridade_social
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "S" && orc.elemento_de_despesa.codigo[0..1] == "32"}.sum(&:valor_fixado)
	end

	def valor_total_juros_e_encargos_da_divida_seguridade_social_por_unidade(unidade_orcamentaria_id)
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "S" && orc.elemento_de_despesa.codigo[0..1] == "32" && orc.subacao.unidade_orcamentaria_id == unidade_orcamentaria_id}.sum(&:valor_fixado)
	end

	def valor_total_outras_despesas_correntes_seguridade_social
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "S" && orc.elemento_de_despesa.codigo[0..1] == "33" }.sum(&:valor_fixado)
	end

	def valor_total_outras_despesas_correntes_seguridade_social_por_unidade(unidade_orcamentaria_id)
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "S" && orc.elemento_de_despesa.codigo[0..1] == "33" && orc.subacao.unidade_orcamentaria_id == unidade_orcamentaria_id}.sum(&:valor_fixado)
	end

	def valor_total_investimentos_seguridade_social
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "S" && orc.elemento_de_despesa.codigo[0..1] == "44"}.sum(&:valor_fixado)
	end

	def valor_total_investimentos_seguridade_social_por_unidade(unidade_orcamentaria_id)
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "S" && orc.elemento_de_despesa.codigo[0..1] == "44" && orc.subacao.unidade_orcamentaria_id == unidade_orcamentaria_id}.sum(&:valor_fixado)
	end

	def valor_total_inversoes_financeiras_seguridade_social
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "S" && orc.elemento_de_despesa.codigo[0..1] == "45"}.sum(&:valor_fixado)
	end

	def valor_total_inversoes_financeiras_seguridade_social_por_unidade(unidade_orcamentaria_id)
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "S" && orc.elemento_de_despesa.codigo[0..1] == "45" && orc.subacao.unidade_orcamentaria_id == unidade_orcamentaria_id}.sum(&:valor_fixado)
	end

	def valor_total_amortizacao_da_divida_seguridade_social
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "S" && orc.elemento_de_despesa.codigo[0..1] == "46"}.sum(&:valor_fixado)
	end

	def valor_total_amortizacao_da_divida_seguridade_social_por_unidade(unidade_orcamentaria_id)
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "S" && orc.elemento_de_despesa.codigo[0..1] == "46" && orc.subacao.unidade_orcamentaria_id == unidade_orcamentaria_id}.sum(&:valor_fixado)
	end

	def valor_total_reserva_de_contingencia_seguridade_social
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "S" && orc.elemento_de_despesa.codigo[0..1] == "99"}.sum(&:valor_fixado)
	end

	def valor_total_reserva_de_contingencia_seguridade_social_por_unidade(unidade_orcamentaria_id)
		self.orcamentos_da_despesa.select{|orc| orc.tipo_de_orcamento == "S" && orc.elemento_de_despesa.codigo[0..1] == "99" && orc.subacao.unidade_orcamentaria_id == unidade_orcamentaria_id}.sum(&:valor_fixado)
	end

	def valor_total_seguridade_social
		(valor_total_pessoal_e_encargos_sociais_seguridade_social.to_d + valor_total_juros_e_encargos_da_divida_seguridade_social.to_d + valor_total_outras_despesas_correntes_seguridade_social.to_d + valor_total_investimentos_seguridade_social.to_d + valor_total_inversoes_financeiras_seguridade_social.to_d + valor_total_amortizacao_da_divida_seguridade_social.to_d + valor_total_reserva_de_contingencia_seguridade_social.to_d)
	end

	def valor_total_seguridade_social_por_unidade(unidade_orcamentaria_id)
		(valor_total_pessoal_e_encargos_sociais_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d + valor_total_juros_e_encargos_da_divida_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d + valor_total_outras_despesas_correntes_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d + valor_total_investimentos_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d + valor_total_inversoes_financeiras_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d + valor_total_amortizacao_da_divida_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d + valor_total_reserva_de_contingencia_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d)
	end

	def valor_total_despesas_correntes
		(valor_total_pessoal_e_encargos_sociais_seguridade_social.to_d + valor_total_juros_e_encargos_da_divida_seguridade_social.to_d + valor_total_outras_despesas_correntes_seguridade_social.to_d) + (valor_total_pessoal_e_encargos_sociais_orcamento_fiscal.to_d + valor_total_juros_e_encargos_da_divida_orcamento_fiscal.to_d + valor_total_outras_despesas_correntes_orcamento_fiscal.to_d)
	end

	def valor_total_despesas_correntes_por_unidade(unidade_orcamentaria_id)
		(valor_total_pessoal_e_encargos_sociais_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d + valor_total_juros_e_encargos_da_divida_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d + valor_total_outras_despesas_correntes_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d) + (valor_total_pessoal_e_encargos_sociais_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_juros_e_encargos_da_divida_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_outras_despesas_correntes_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d)
	end

	def valor_total_pessoal_e_encargos_sociais
		valor_total_pessoal_e_encargos_sociais_orcamento_fiscal.to_d + valor_total_pessoal_e_encargos_sociais_seguridade_social.to_d
	end

	def valor_total_pessoal_e_encargos_sociais_por_unidade(unidade_orcamentaria_id)
		valor_total_pessoal_e_encargos_sociais_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_pessoal_e_encargos_sociais_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d
	end

	def valor_total_juros_e_encargos_da_divida
		valor_total_juros_e_encargos_da_divida_orcamento_fiscal.to_d + valor_total_juros_e_encargos_da_divida_seguridade_social.to_d
	end

	def valor_total_juros_e_encargos_da_divida_por_unidade(unidade_orcamentaria_id)
		valor_total_juros_e_encargos_da_divida_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_juros_e_encargos_da_divida_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d
	end

	def valor_total_outras_despesas_correntes
		valor_total_outras_despesas_correntes_orcamento_fiscal.to_d + valor_total_outras_despesas_correntes_seguridade_social.to_d
	end

	def valor_total_outras_despesas_correntes_por_unidade(unidade_orcamentaria_id)
		valor_total_outras_despesas_correntes_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_outras_despesas_correntes_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d
	end

	def valor_total_despesas_de_capital
		(valor_total_investimentos_seguridade_social.to_d + valor_total_inversoes_financeiras_seguridade_social.to_d + valor_total_amortizacao_da_divida_seguridade_social.to_d) + (valor_total_investimentos_orcamento_fiscal.to_d + valor_total_inversoes_financeiras_orcamento_fiscal.to_d + valor_total_amortizacao_da_divida_orcamento_fiscal.to_d)
	end

	def valor_total_despesas_de_capital_por_unidade(unidade_orcamentaria_id)
		(valor_total_investimentos_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d + valor_total_inversoes_financeiras_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d + valor_total_amortizacao_da_divida_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d) + (valor_total_investimentos_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_inversoes_financeiras_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_amortizacao_da_divida_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d)
	end

	def valor_total_investimentos
		valor_total_investimentos_orcamento_fiscal.to_d + valor_total_investimentos_seguridade_social.to_d
	end

	def valor_total_investimentos_por_unidade(unidade_orcamentaria_id)
		valor_total_investimentos_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_investimentos_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d
	end

	def valor_total_inversoes_financeiras
		valor_total_inversoes_financeiras_orcamento_fiscal.to_d + valor_total_inversoes_financeiras_seguridade_social.to_d
	end

	def valor_total_inversoes_financeiras_por_unidade(unidade_orcamentaria_id)
		valor_total_inversoes_financeiras_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_inversoes_financeiras_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d
	end

	def valor_total_amortizacao_da_divida
		valor_total_amortizacao_da_divida_orcamento_fiscal.to_d + valor_total_amortizacao_da_divida_seguridade_social.to_d
	end

	def valor_total_amortizacao_da_divida_por_unidade(unidade_orcamentaria_id)
		valor_total_amortizacao_da_divida_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_amortizacao_da_divida_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d
	end

	def valor_total_reserva_de_contingencia
		valor_total_reserva_de_contingencia_orcamento_fiscal.to_d + valor_total_reserva_de_contingencia_seguridade_social.to_d
	end

	def valor_total_reserva_de_contingencia_por_unidade(unidade_orcamentaria_id)
		valor_total_reserva_de_contingencia_orcamento_fiscal_por_unidade(unidade_orcamentaria_id).to_d + valor_total_reserva_de_contingencia_seguridade_social_por_unidade(unidade_orcamentaria_id).to_d
	end

	def valor_das_acoes_pca
		self.orcamentos_da_despesa_por_acao.sum(:valor)
	end

	def percentual_aplicado (total, aplicado)
		total.to_f > 0 ? ((aplicado * 100) / total).round(2) : 0
	end

	def percentual_aplicado_em_educacao
		fonte_de_recurso_educacao = self.fontes_de_recursos.find_by(codigo: "02")
		percentual_aplicado(total_impostos_e_transferencias_das_receitas_por_fonte_de_recurso(fonte_de_recurso_educacao), valor_total_aplicado_em_educacao.to_f)
	end

	def percentual_aplicado_em_saude
		fonte_de_recurso_saude = self.fontes_de_recursos.find_by(codigo: "03")
		percentual_aplicado(total_impostos_e_transferencias_das_receitas_por_fonte_de_recurso(fonte_de_recurso_saude), valor_total_aplicado_em_saude.to_f)
	end

	def percentual_das_receitas_por_fonte_de_recurso codigo_da_fonte
		valor = valor_total_das_receitas_por_fonte_de_recurso(codigo_da_fonte)
		valor.to_f > 0 ?	((100 * valor.to_f) / valor_total_das_receitas_que_contem_a_fonte_de_recurso(codigo_da_fonte).to_f).round(2) : 0
	end

	def refazer_movimentacoes data_inicio, data_fim = Date.today
		movimentacoes = Contabilidade::MovimentacaoDoPlanoDeContas.where("data_de_lancamento >= ? and data_de_lancamento <= ?", data_inicio, data_fim)
		movimentacoes.group_by {|m| m.gerador_id }.each { |gerador_id, array_movimentacoes|
			array_movimentacoes.first.gerador.gera_movimentacao
			array_movimentacoes.each(&:destroy)
		}
		movimentacoes.reload
	end

	def inss_vigente
		Contabilidade::Inss.order(:ano_de_referencia, :competencia).last
	end

	def irpf_vigente
		Contabilidade::ImpostoDeRenda.order(:ano_de_referencia, :mes_de_competencia).last
	end

	def cria_calculo_de_projecao projecao_a_ser_copiada
		calculos_de_projecoes_a_serem_copiados = projecao_a_ser_copiada.calculo_de_projecoes

		calculos_de_projecoes_a_serem_copiados.each do |calculo_de_projecao_a_ser_copiado|

			novo_calculo_de_projecao = calculo_de_projecao_a_ser_copiado.dup
			novo_calculo_de_projecao.projecao_de_receita_id = projecao_de_receita.id
			novo_calculo_de_projecao.save!

			cria_indices_do_calculo_de_projecao(calculo_de_projecao_a_ser_copiado, novo_calculo_de_projecao.id)

			# cria_receitas_dos_calculos_de_projecao_para_projecao(calculo_de_projecao_a_ser_copiado, novo_calculo_de_projecao)
		end

		return true
	end

	def cria_indices_do_calculo_de_projecao calculo_de_projecao_a_ser_copiado, novo_calculo_de_projecao_id
		calculo_de_projecao_a_ser_copiado.indices_do_calculo_de_projecao.each do |indice_de_calculo_projecao_a_ser_copiado|
			novo_indice_de_calculo_de_projecao = indice_de_calculo_projecao_a_ser_copiado.dup
			novo_indice_de_calculo_de_projecao.calculo_de_projecao_id = novo_calculo_de_projecao_id
			unless novo_indice_de_calculo_de_projecao.save!
				raise ActiveRecord::Rollback
			end
		end
	end

	def cria_receitas_dos_calculos_de_projecao_para_projecao calculo_de_projecao_a_ser_copiado, novo_calculo_de_projecao
		calculo_de_projecao_a_ser_copiado.receitas_dos_calculos_de_projecao.each do |receita_do_calculo_de_projecao_a_ser_copiada|
			if receita_do_calculo_de_projecao_a_ser_copiada.receita.codigo.present?
				if receita_do_calculo_de_projecao_a_ser_copiada.calculo_de_projecao.projecao_de_receita.planejamento.utiliza_novo_tipo_para_receita?
					nova_receita_codigo = receita_do_calculo_de_projecao_a_ser_copiada.receita.codigo
				else
					nova_receita_codigo = receita_do_calculo_de_projecao_a_ser_copiada.receita.codigo_referencia
				end

				# unless nova_receita.present?
				# 	nova_receita = projecao_de_receita.receitas.find_by(codigo: nova_receita_codigo)
				# 	nova_receita = nova_receita.mais_proximo_que_pode_ser_orcado
				# end

				# if nova_receita.present?
				# 	unless nova_receita.pode_ser_orcada?
				# 		nova_receita = nova_receita.mais_proximo_que_pode_ser_orcado
				# 	end
				# end

				if nova_receita_codigo.present?
					nova_receita = projecao_de_receita.receitas.find_by(codigo: nova_receita_codigo)

					if nova_receita.present? && nova_receita.pode_ser_orcada?
						unless novo_calculo_de_projecao.receitas_dos_calculos_de_projecao.find_by(receita_id: nova_receita.id)
							nova_receita_calculo_de_projecao = receita_do_calculo_de_projecao_a_ser_copiada.dup
							nova_receita_calculo_de_projecao.calculo_de_projecao_id = novo_calculo_de_projecao.id

							nova_receita_calculo_de_projecao.receita_id = nova_receita.id

							unless nova_receita_calculo_de_projecao.save!
								raise ActiveRecord::Rollback
							end
						end
					end
				end
			end
		end
	end

	def criar_projecao_de_receita
		projecao_de_receita_id_a_ser_copiada = nil
		ppa = Ppa::Ppa.find_by_id(self.ppa_id.to_i)
		if utilizar_projecao_do_ppa.present? && ppa.projecao_de_receita.present?
			projecao_de_receita_id_a_ser_copiada = ppa.id
		end

		ActiveRecord::Base.transaction do
			exercicio_final = self.exercicio.to_i + 3

			params = {
				descricao: "Projeção de Receita #{self.exercicio} - #{exercicio_final}",
				exercicio_base_inicial: (self.exercicio.to_i - 4), exercicio_base_final: (exercicio.to_i - 2),
				exercicio_corrente: (self.exercicio.to_i - 1),
				exercicio_projecao_inicial: self.exercicio, exercicio_projecao_final: exercicio_final,
				planejamento_type: "Orcamento",
				planejamento_id: self.id,
				receitas_importadas: true
			}

			unless self.create_projecao_de_receita(params)
				errors.add(:projecao_de_receita_id, "Falha ao criar a nova projeção.")
				raise ActiveRecord::Rollback
			end

			# unless criar_dados_padroes_para_projecao
			# 	errors.add(:projecao_de_receita_id, "Falha ao criar os dados iniciais para a nova projeção.")
			# 	raise ActiveRecord::Rollback
			# end

			if projecao_de_receita_id_a_ser_copiada.present?
				replicar_projecao_de_receita(projecao_de_receita_id_a_ser_copiada)
			end
		end
	end

	def utiliza_novo_tipo_para_receita?
		exercicio.present? && exercicio > 2017
	end

	def lista_de_temas
		temas_do_orcamento = self.temas_do_orcamento
		if temas_do_orcamento.size > 0
			temas = Loa::OrcamentoTematico.where("id not in (?)", self.temas_do_orcamento.map(&:orcamento_tematico_id)).all
		else
			temas = Loa::OrcamentoTematico.all
		end

		temas.each do |tema|
			temas_do_orcamento.build(orcamento_tematico_id: tema.id, ativo: false)
		end
		temas_do_orcamento
	end

	def exercicios_para_convenios
		total = self.exercicio + 2
		self.exercicio..total
	end

	def renumerar_acoes
		naturezas_da_acao = Array.new
		self.naturezas_da_acao.each do |natureza_da_acao|
			naturezas_da_acao << {id: natureza_da_acao.id, codigo: 1}
		end
		acoes.joins(:subacoes).order("unidade_orcamentaria_id ASC").each do |acao|
			natureza_da_acao = naturezas_da_acao.find{|e| e[:id] == acao.natureza_da_acao.id}
			acao.codigo = natureza_da_acao[:codigo].to_s.rjust(3, '0')
			acao.save(validate: false)
			natureza_da_acao[:codigo] += 1
		end
	end

	def corrigir_tipo_de_orcamento
		self.subacoes.each do |subacao|
			subacao.preenche_tipo_de_orcamento
			subacao.save(validate: false)
		end
	end

	def orgaos_do_usuario(usuario)
		if usuario.desenvolvedor?
			self.orgaos
		elsif usuario.present? && (usuario.administrador? || usuario.todas_as_unidades?)
			if usuario.tipo_de_poder == 'ambos'				
				self.orgaos
			elsif usuario.tipo_de_poder == 'legislativo'
				self.orgaos.joins(:tipo_de_unidade_administrativa).where("base_tipos_de_unidades_administrativas.poder_associado = ?", 0)
			else
				self.orgaos.por_tipo_de_sistema
			end
		elsif usuario.present? && usuario.unidades_selecionadas?
			if usuario.tipo_de_poder == 'ambos'
				self.orgaos.joins(unidades_orcamentarias: :unidades_orcamentarias_por_usuario).where("loa_unidades_orcamentarias_por_usuario.usuario_id = ?", usuario.id).distinct
			elsif usuario.tipo_de_poder == 'legislativo'
				self.orgaos.joins(:tipo_de_unidade_administrativa).where("base_tipos_de_unidades_administrativas.poder_associado = ?", 0).joins(unidades_orcamentarias: :unidades_orcamentarias_por_usuario).where("loa_unidades_orcamentarias_por_usuario.usuario_id = ?", usuario.id).distinct
			else
				self.orgaos.por_tipo_de_sistema.joins(unidades_orcamentarias: :unidades_orcamentarias_por_usuario).where("loa_unidades_orcamentarias_por_usuario.usuario_id = ?", usuario.id).distinct
			end
		else
			Loa::Orgao.none
		end
	end

	def unidades_orcamentarias_do_usuario(usuario)
		if usuario.present? && (usuario.administrador? || usuario.todas_as_unidades?)
			self.unidades_orcamentarias
		elsif usuario.present? && usuario.unidades_selecionadas?
			self.unidades_orcamentarias.joins(:unidades_orcamentarias_por_usuario).where("loa_unidades_orcamentarias_por_usuario.usuario_id = ?", usuario.id)
		else
			Loa::UnidadeOrcamentaria.none
		end
	end

	def unidades_orcamentarias_com_itens_no_almoxarifado(usuario)
		itens_do_estoque = GestaoDeEstoque::Estoque.select("DISTINCT ON (item_id, unidade_de_medida_id) *").pluck(:unidade_orcamentaria_id)
		unidades = []
		itens_do_estoque.each do |item|
			unidades += Loa::UnidadeOrcamentaria.where(id: item)
		end
		return unidades.uniq
	end

	[:importar_acoes, :importar_orgaos, :importar_despesas].each do |atributo_importacao|
		define_method :"#{atributo_importacao}=" do |valor_string|
			instance_variable_set "@#{atributo_importacao}".to_sym, valor_string == '1'
		end
	end

	def resgata_ordenador_antigo_das_unidades
		self.unidades_orcamentarias.each do |unidade_orcamentaria|
			unidade_orcamentaria.resgata_ordenador_antigo
		end
	end

	def cria_almoxarifado_do_patrimonio
		unless GestaoDeEstoque::Almoxarifado.any? {|almoxarifado| almoxarifado.orcamento_id == self.id and almoxarifado.tipo_de_almoxarifado == "patrimonio"}
			almoxarifado_patrimonio = GestaoDeEstoque::Almoxarifado.new(
				orcamento_id: self.id,
				nome: "Almoxarifado Central do Patrimônio de #{self.exercicio}",
				tipo_de_almoxarifado: "patrimonio"
			)
			almoxarifado_patrimonio.save(validate: false)
			if almoxarifado_patrimonio.present?
				self.unidades_orcamentarias.each do |unidade_orcamentaria|
					almoxarifado_patrimonio.unidades_orcamentarias_do_almoxarifado.create(unidade_orcamentaria: unidade_orcamentaria)
				end
			end
		end
	end

	def cria_informacoes_rpps
		duplica_legislacoes
		duplica_comites_rpps
		duplica_conselhos_rpps
	end

	def cria_feriados_exercicio_atual
		duplica_feriados_ano_anterior
	end

	def unidades_gestoras
		data_periodo = Date.new(self.exercicio, 1, 1)
		
		Loa::UnidadeGestora.where("data_encerramento >= ? or data_encerramento is null", data_periodo).all
	end

	def quantidade_de_acoes_sem_metas_fisicas
		if self.meta_fisica_obrigatoria_para_0_1_2?
			self.subacoes.select { |i| i.metas_fisicas.size == 0 }.size
		elsif self.meta_fisica_obrigatoria_para_1?
			self.subacoes.select { |i| i.acao.programa_de_governo.codigo[0] == '1' && i.metas_fisicas.size == 0 }.size
		elsif self.meta_fisica_nao_obrigatoria?
			0
		end
	end

	def todos_os_programas_possuem_meta_fisica?
		self.quantidade_de_acoes_sem_metas_fisicas == 0 ? true : false
	end

	private

	# ao criar um orçamento via task, passar o atributo gerar_dependencias como false para evitar rodar em thread separada
	def criar_dependencias_do_orcamento
		if self.gerando_dependencias?
			if self.gerar_dependencias == true
				Thread.new do
					system("rake db:criacao_de_novo_orcamento[#{self.exercicio}]")
				end
			end
		end
	end

	def gerar_receitas
		unless utiliza_novo_tipo_para_receita?
			cria_naturezas_da_receita
		end
	end

	def criar_dados_padroes_para_projecao
		receitas_orcamentos = self.naturezas_da_receita
		if utiliza_novo_tipo_para_receita?
			receitas_orcamentos.order(:codigo).each do |receita|
				nova_receita = Projecao::Receita.criar_receita_da_projecao(self.projecao_de_receita, receita)
				if nova_receita.pode_ser_orcada?
					nova_receita.criar_calculos_por_exercicios(:orcamento)
					nova_receita.atualizar_calculos_por_exercicios_para_nova_receita_em_exercicios_base_e_corrente
				end
			end
		else
			receitas_orcamentos.each do |receita|
				Projecao::Receita.criar_receita_da_projecao(self.projecao_de_receita, receita)
			end
			Projecao::Receita.criar_calculos_base_e_corrente(self.projecao_de_receita)
		end
	end

	def replicar_projecao_de_receita(projecao_de_receita_id_a_ser_copiada)
		projecao_a_ser_copiada = Projecao::ProjecaoDeReceita.find(projecao_de_receita_id_a_ser_copiada)
		criar_indices_da_projecao(projecao_a_ser_copiada.indices_de_projecao)

		unless projecao_a_ser_copiada.try(:calculo_de_projecoes).present?
			errors.add(:ppa_id, "Essa projeção não possui cálculos de projeção criados.")
			raise ActiveRecord::Rollback
		end

		unless cria_calculo_de_projecao(projecao_a_ser_copiada)
			errors.add(:ppa_id, "Falha ao criar os cálculos de projeção.")
			raise ActiveRecord::Rollback
		end
	end

	def criar_indices_da_projecao(indices_a_serem_copiados)
		projecao_de_receita.indices_de_projecao.delete_all

		indices_a_serem_copiados.each do |indice_a_ser_copiado|
			novo_indice = indice_a_ser_copiado
			novo_indice.projecao_de_receita_id = projecao_de_receita.id

			unless novo_indice.save!
				raise ActiveRecord::Rollback
			end
		end
	end

	# TODO: IMPLEMENTAR TESTE
	def atualiza_tipo_da_receita
		self.utiliza_novo_tipo_para_receita = (exercicio.present? && exercicio > 2017)
	end

	def ppa_esta_sendo_utilizado?
		programas_de_governo.where("programa_id is not null").count > 0 || acoes.where("iniciativa_id is not null").count > 0
	end

	def copia_valores_para_campos_orcados
		subacoes.each do |subacao|
			subacao.update_attribute(:fixacao_orcada, subacao.fixacao_da_despesa)
		end

		orcamentos_da_despesa.each do |orcamento_da_despesa|
			orcamento_da_despesa.update_attribute(:valor_orcado, orcamento_da_despesa.valor)
		end
	end


	def duplica_legislacoes
		if orcamento_anterior.present?
			legislacoes_antigas = orcamento_anterior.decretos.rpps

			legislacoes_antigas.each do |legislacao|
				legislacao_exercicio_vigente = legislacao.dup
				legislacao_exercicio_vigente.orcamento_id = id

				legislacao_exercicio_vigente.save(validate: false)
			end
		end
	end

	def duplica_comites_rpps
		comites_de_investimento_antigos = orcamento_anterior&.comites_de_investimento

		unless comites_de_investimento_antigos.nil?
			comites_de_investimento_antigos.each do |comite_de_investimento|
				comite_de_investimento_atual = comite_de_investimento.dup
				comite_de_investimento_atual.orcamento_id = id
				comite_de_investimento_atual.save(validate: false)

				comite_de_investimento.membros_dos_comites_de_investimento.each do |membro_do_comite_de_investimento|
					membro_do_comite_de_investimento_atual = membro_do_comite_de_investimento.dup
					membro_do_comite_de_investimento_atual.comite_de_investimento_id = comite_de_investimento_atual.id

					membro_do_comite_de_investimento_atual.save(validate: false)
				end
			end
		end
	end

	def duplica_conselhos_rpps
		conselhos_de_rpps_antigos = orcamento_anterior&.conselhos_de_rpps

		unless conselhos_de_rpps_antigos.nil?
			conselhos_de_rpps_antigos.each do |conselho_de_rpps|
				conselho_de_rpps_atual = conselho_de_rpps.dup
				conselho_de_rpps_atual.orcamento_id = id
				conselho_de_rpps_atual.save(validate: false)

				conselho_de_rpps.membros_do_conselho_do_rpps.each do |membro_do_conselho|
					membro_do_conselho_atual = membro_do_conselho.dup
					membro_do_conselho_atual.conselho_de_rpps_id = conselho_de_rpps_atual.id

					membro_do_conselho_atual.save(validate: false)
				end
			end
		end
	end

	def duplica_feriados_ano_anterior
		if self.orcamento_anterior.present?
			feriados_ano_anterior = ::Base::ConfiguracaoDeFeriado.where(ano_de_referencia: self.orcamento_anterior.exercicio).where.not(tipo_de_feriado: 'facultativo')

			feriados_ano_anterior.each do |feriado|
				feriado_atual = feriado.dup
				feriado_atual.orcamento_id = id
				feriado_atual.ano_de_referencia = feriado.ano_de_referencia + 1
				feriado_atual.data_do_feriado = feriado.data_do_feriado + 1.year
				feriado_atual.save(validate: false)
			end
		end
	end
end
