require 'rails_helper'

RSpec.describe Base::CategoriaEconomica, type: :model do
	it { is_expected.to belong_to(:modulo).required }

	it{ is_expected.to have_many :grupos_de_natureza_da_despesa }
	it{ is_expected.to have_many(:modalidades_de_aplicacao).through(:grupos_de_natureza_da_despesa) }
	it{ is_expected.to have_many(:elementos_de_despesa).through(:modalidades_de_aplicacao) }

	it{ is_expected.to validate_presence_of :descricao }
	it{ is_expected.to validate_presence_of :codigo }

	it{ is_expected.to validate_uniqueness_of(:descricao).scoped_to(:modulo_id, :modulo_type) }
	it{ is_expected.to validate_uniqueness_of(:codigo).scoped_to(:modulo_id, :modulo_type) }

	describe '#valor_total_fixado_dos_elementos' do
		it "retorna a soma de todos os orçamentos aliados a todos os elementos de despesa filhos" do
			categoria_economica = Base::CategoriaEconomica.new( FactoryBot.attributes_for(:despesas_correntes, :orcamento_2016) )
			categoria_economica.save
			elemento_de_despesa = Base::ElementoDeDespesa.find_or_create_by!( FactoryBot.attributes_for(:elemento_de_despesa_material_de_consumo, :com_modalidade_de_aplicacao) )
			elemento_de_despesa_por_subacao = FactoryBot.create(:elemento_de_despesa_por_subacao, elemento_de_despesa_id: elemento_de_despesa.id)
			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_educacao, valor: 150.0 , elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao.id ) )
			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_saude, valor: 50.0, elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao.id ) )

			expect(categoria_economica.valor_total_fixado_dos_elementos).to eq 200.0
		end
	end

	describe '#valor_total_fixado_dos_elementos_intra_orcamentarios' do
		it "retorna a soma de todos os orçamentos aliados a todos os elementos de despesa cuja modalidade de aplicação é 91" do
			categoria_economica = Base::CategoriaEconomica.new( FactoryBot.attributes_for(:despesas_correntes, :orcamento_2016) )
			categoria_economica.save

			elemento_de_despesa_intra_orcamentario = Base::ElementoDeDespesa.find_or_create_by!( FactoryBot.attributes_for(:elemento_de_despesa_material_de_consumo, :com_modalidade_de_aplicacao_intra_orcamentaria) )
			elemento_de_despesa_por_subacao_intra_orcamentario = FactoryBot.create(:elemento_de_despesa_por_subacao, elemento_de_despesa_id: elemento_de_despesa_intra_orcamentario.id)
			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_educacao, valor: 150.0 , elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao_intra_orcamentario.id ) )
			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_saude, valor: 50.0, elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao_intra_orcamentario.id ) )

			elemento_de_despesa = Base::ElementoDeDespesa.find_or_create_by!( FactoryBot.attributes_for(:elemento_de_despesa_material_de_consumo, :com_modalidade_de_aplicacao) )
			elemento_de_despesa_por_subacao = FactoryBot.create(:elemento_de_despesa_por_subacao, elemento_de_despesa_id: elemento_de_despesa.id)
			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_saude, valor: 50.0, elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao.id ) )
			expect(categoria_economica.valor_total_fixado_dos_elementos_intra_orcamentarios).to eq 200.0
		end
	end

	describe '#valor_total_realizado_dos_elementos' do
		it "retorna a soma dos valores empenhados de todos os orçamentos aliados aos elementos de despesa filhos" do
			categoria_economica = Base::CategoriaEconomica.new( FactoryBot.attributes_for(:despesas_correntes, :orcamento_2016) )
			categoria_economica.save

			elemento_de_despesa = Base::ElementoDeDespesa.find_or_create_by!( FactoryBot.attributes_for(:elemento_de_despesa_material_de_consumo, :com_modalidade_de_aplicacao_intra_orcamentaria) )
			elemento_de_despesa_por_subacao = FactoryBot.create(:elemento_de_despesa_por_subacao, elemento_de_despesa_id: elemento_de_despesa.id)
			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_educacao, valor: 150.0 , elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao.id ) )
			empenho = FactoryBot.build( :empenho_22090001, orcamento_da_despesa: orcamento_da_despesa, valor: 130.0, status: :confirmado, descriminacao_obrigatoria_de_itens: false )
			empenho.save(validate: false)
			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_saude, valor: 50.0, elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao.id ) )
			empenho = FactoryBot.build( :empenho_22090001, orcamento_da_despesa: orcamento_da_despesa, valor: 30.0, status: :confirmado, descriminacao_obrigatoria_de_itens: false )
			empenho.save(validate: false)

			expect(categoria_economica.valor_total_realizado_dos_elementos).to eq 160.0
		end
	end

	describe '#valor_total_fixado_dos_elementos_exceto_intra_orcamentarios' do
		it "retorna a soma de todos os orçamentos aliados a todos os elementos de despesa cuja modalidade de aplicação é 91" do
			categoria_economica = Base::CategoriaEconomica.new( FactoryBot.attributes_for(:despesas_correntes, :orcamento_2016) )
			categoria_economica.save

			elemento_de_despesa = Base::ElementoDeDespesa.find_or_create_by!( FactoryBot.attributes_for(:elemento_de_despesa_material_de_consumo, :com_modalidade_de_aplicacao) )
			elemento_de_despesa_intra_orcamentario = Base::ElementoDeDespesa.find_or_create_by!( FactoryBot.attributes_for(:elemento_de_despesa_material_de_consumo, :com_modalidade_de_aplicacao_intra_orcamentaria) )

			elemento_de_despesa_por_subacao = FactoryBot.create(:elemento_de_despesa_por_subacao, elemento_de_despesa_id: elemento_de_despesa.id)
			elemento_de_despesa_por_subacao_intra_orcamentario = FactoryBot.create(:elemento_de_despesa_por_subacao, elemento_de_despesa_id: elemento_de_despesa_intra_orcamentario.id)

			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_saude, valor: 50.0, elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao.id ) )
			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_educacao, valor: 150.0 , elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao_intra_orcamentario.id ) )
			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_saude, valor: 50.0, elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao_intra_orcamentario.id ) )

			expect(categoria_economica.valor_total_fixado_dos_elementos_exceto_intra_orcamentarios).to eq 50.0
		end
	end

	describe '#valor_total_realizado_dos_elementos_intra_orcamentarios' do
		it "retorna a soma de todos os orçamentos aliados a todos os elementos de despesa cuja modalidade de aplicação é 91" do
			categoria_economica = Base::CategoriaEconomica.new( FactoryBot.attributes_for(:despesas_correntes, :orcamento_2016) )
			categoria_economica.save

			elemento_de_despesa = Base::ElementoDeDespesa.find_or_create_by!( FactoryBot.attributes_for(:elemento_de_despesa_material_de_consumo, :com_modalidade_de_aplicacao) )
			elemento_de_despesa_intra_orcamentario = Base::ElementoDeDespesa.find_or_create_by!( FactoryBot.attributes_for(:elemento_de_despesa_material_de_consumo, :com_modalidade_de_aplicacao_intra_orcamentaria) )

			elemento_de_despesa_por_subacao = FactoryBot.create(:elemento_de_despesa_por_subacao, elemento_de_despesa_id: elemento_de_despesa.id)
			elemento_de_despesa_por_subacao_intra_orcamentario = FactoryBot.create(:elemento_de_despesa_por_subacao, elemento_de_despesa_id: elemento_de_despesa_intra_orcamentario.id)

			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_saude, valor: 50.0, elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao.id ) )
			empenho = FactoryBot.build( :empenho_22090001, orcamento_da_despesa: orcamento_da_despesa, valor: 130.0, status: :confirmado, descriminacao_obrigatoria_de_itens: false )
			empenho.save(validate: false)

			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_educacao, valor: 150.0 , elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao_intra_orcamentario.id ) )
			empenho = FactoryBot.build( :empenho_22090001, orcamento_da_despesa: orcamento_da_despesa, valor: 30.0, status: :confirmado, descriminacao_obrigatoria_de_itens: false )
			empenho.save(validate: false)

			expect(categoria_economica.valor_total_realizado_dos_elementos_intra_orcamentarios).to eq 30.0
		end
	end

	describe '#valor_total_realizado_dos_elementos_exceto_intra_orcamentarios' do
		it "retorna a soma de todos os orçamentos aliados a todos os elementos de despesa cuja modalidade de aplicação não é 91" do

			categoria_economica = Base::CategoriaEconomica.new( FactoryBot.attributes_for(:despesas_correntes, :orcamento_2016) )
			categoria_economica.save

			elemento_de_despesa = Base::ElementoDeDespesa.find_or_create_by!( FactoryBot.attributes_for(:elemento_de_despesa_material_de_consumo, :com_modalidade_de_aplicacao) )
			elemento_de_despesa_intra_orcamentario = Base::ElementoDeDespesa.find_or_create_by!( FactoryBot.attributes_for(:elemento_de_despesa_material_de_consumo, :com_modalidade_de_aplicacao_intra_orcamentaria) )

			elemento_de_despesa_por_subacao = FactoryBot.create(:elemento_de_despesa_por_subacao, elemento_de_despesa_id: elemento_de_despesa.id)
			elemento_de_despesa_por_subacao_intra_orcamentario = FactoryBot.create(:elemento_de_despesa_por_subacao, elemento_de_despesa_id: elemento_de_despesa_intra_orcamentario.id)

			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_saude, valor: 50.0, elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao.id ) )
			empenho = FactoryBot.build( :empenho_22090001, orcamento_da_despesa: orcamento_da_despesa, valor: 130.0, status: :confirmado, descriminacao_obrigatoria_de_itens: false )
			empenho.save(validate: false)

			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_educacao, valor: 150.0 , elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao_intra_orcamentario.id ) )
			empenho = FactoryBot.build( :empenho_22090001, orcamento_da_despesa: orcamento_da_despesa, valor: 30.0, status: :confirmado, descriminacao_obrigatoria_de_itens: false )
			empenho.save(validate: false)

			expect(categoria_economica.valor_total_realizado_dos_elementos_exceto_intra_orcamentarios).to eq 130.0
		end
	end

	describe 'codigo_formatado' do
		it 'retorna codigo com os pontos' do
			categoria = Base::CategoriaEconomica.new
			categoria.codigo = '30000000'
			expect(categoria.codigo_formatado).to eq("3.0.00.00.00")
		end
	end

	describe 'valor_previsto_por_mes(mes)' do
		it 'sem porcentagem cadastrada retorna valor total/12' do
			categoria_economica = Base::CategoriaEconomica.new( FactoryBot.attributes_for(:despesas_correntes, :orcamento_2016) )
			categoria_economica.save

			elemento_de_despesa = Base::ElementoDeDespesa.find_or_create_by!( FactoryBot.attributes_for(:elemento_de_despesa_material_de_consumo, :com_modalidade_de_aplicacao_intra_orcamentaria) )
			elemento_de_despesa_por_subacao = FactoryBot.create(:elemento_de_despesa_por_subacao, elemento_de_despesa_id: elemento_de_despesa.id)
			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_educacao, valor: 120.0 , elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao.id ) )
			empenho = FactoryBot.build( :empenho_22090001, orcamento_da_despesa: orcamento_da_despesa, valor: 120.0, status: :confirmado, descriminacao_obrigatoria_de_itens: false )
			empenho.save(validate: false)
			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_saude, valor: 120.0, elemento_de_despesa_por_subacao_id: elemento_de_despesa_por_subacao.id ) )
			empenho = FactoryBot.build( :empenho_22090001, orcamento_da_despesa: orcamento_da_despesa, valor: 120.0, status: :confirmado, descriminacao_obrigatoria_de_itens: false )
			empenho.save(validate: false)

			expect(categoria_economica.valor_previsto_por_mes(1)).to eq (240/12)
		end
	end

	it 'valor_total' do
		skip
	end
end
