module Base
	class CategoriaEconomica < ApplicationRecord
		include CalculaValoresDeElementos
		include ClassificacaoDaDespesaConcern

		has_paper_trail

		belongs_to :modulo, polymorphic: true, required: true

		has_many :grupos_de_natureza_da_despesa
		has_many :modalidades_de_aplicacao, through: :grupos_de_natureza_da_despesa
		has_many :elementos_de_despesa, through: :modalidades_de_aplicacao
		has_many :sub_elementos_de_despesa, through: :elementos_de_despesa, class_name: 'Contabilidade::SubElementoDeDespesa'
		has_many :elementos_de_despesa_por_subacao, through: :elementos_de_despesa
		has_many :orcamentos_da_despesa, through: :elementos_de_despesa_por_subacao
		has_many :lancamentos_do_orcamento_da_despesa, through: :orcamentos_da_despesa

		validates_presence_of :codigo, :descricao, :modulo_id, :modulo_type
		validates_uniqueness_of :codigo, scope: [:modulo_id, :modulo_type]
		validates_uniqueness_of :descricao, scope: [:modulo_id, :modulo_type]

		validate :codigo_deve_estar_contido_nos_dados_base, unless: Proc.new { Rails.env.test? }
		#validate :descricao_deve_estar_contida_nos_dados_base, unless: Proc.new { Rails.env.test? }

		scope :despesa_corrente, -> { find_by(codigo: '30000000') }
		scope :despesa_de_capital, -> { find_by(codigo: '40000000') }

		scope :selecionados, -> {self.joins(grupos_de_natureza_da_despesa: [modalidades_de_aplicacao: :elementos_de_despesa]).where(base_elementos_de_despesa: {exibir_elemento_de_despesa: 'true'}).distinct}

		def codigo_e_descricao
			"#{codigo} - #{descricao}"
		end

		def codigo_formatado_e_descricao
			"#{codigo_formatado} - #{descricao}"
		end

		def valor_previsto_por_mes mes, unidade_orcamentaria_id=0
			self.elementos_de_despesa.inject(0){ |total, elemento_de_despesa| total + elemento_de_despesa.valor_previsto_por_mes(mes, unidade_orcamentaria_id)}
		end

		def reserva_de_contingencia?
			descricao == 'Reserva de Contingência' && codigo == '90000000'
		end

		

		private
		def codigo_deve_estar_contido_nos_dados_base
			if codigo.present?
				unless NaturezaDaDespesa::CategoriaEconomica.find_by( codigo: codigo[0] )
					errors.add(:codigo, 'não existe categoria econômica com esse código')
				end
			end
		end

		def descricao_deve_estar_contida_nos_dados_base
			if descricao.present?
				unless NaturezaDaDespesa::CategoriaEconomica.find_by( descricao: descricao )
					errors.add(:descricao, 'não existe categoria econômica com essa descrição')
				end
			end
		end
	end
end
