require 'rails_helper'

RSpec.describe Loa::OrcamentoDaDespesa, type: :model do

	it { is_expected.to belong_to(:elemento_de_despesa_por_subacao).inverse_of(:orcamentos_da_despesa).required }
	it { is_expected.to belong_to(:fonte_de_recursos).class_name("Base::FonteDeRecursos").required }

	it{ is_expected.to have_many(:empenhos).class_name('Contabilidade::Empenho').dependent(:restrict_with_exception) }
	it{ is_expected.to have_many(:lancamentos_do_orcamento_da_despesa).class_name('Contabilidade::LancamentoDoOrcamentoDaDespesa').dependent(:destroy) }


	it { is_expected.to delegate_method(:elemento_de_despesa).to(:elemento_de_despesa_por_subacao) }
	it { is_expected.to delegate_method(:codigo_e_descricao).to(:elemento_de_despesa).with_prefix(:elemento_de_despesa) }
	it { is_expected.to delegate_method(:subacao).to(:elemento_de_despesa_por_subacao) }
	it { is_expected.to delegate_method(:acao).to(:subacao) }
	it { is_expected.to delegate_method(:codigo_e_nome).to(:acao).with_prefix(:acao) }
	it { is_expected.to delegate_method(:codigo_e_descricao).to(:fonte_de_recursos).with_prefix(:fonte_de_recursos) }


	context "validando presenca" do
		subject {
			Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_educacao ) )
		}

		it { is_expected.to validate_presence_of :fonte_de_recursos_id }
		it { is_expected.to validate_presence_of :valor }

		it { is_expected.to validate_numericality_of(:valor).is_greater_than(0) }

	end

	describe 'validates_uniqueness_of' do
		it 'validate_uniqueness_of fonte_de_recursos_id no escopo elemento_de_despesa_por_subacao_id' do

			subacao = FactoryBot.create :subacao_1005_0002, :orcamento_2016
			elemento_de_despesa = FactoryBot.create :elemento_de_despesa_material_de_consumo
			fonte_de_recursos = FactoryBot.create :alienacao_de_bens

			atributos_de_elementos_de_despesa_por_subacao =  {
				fixacao_da_despesa: 100.00,
				elementos_de_despesa_por_subacao_attributes: {
					"0" => {
						elemento_de_despesa_id: elemento_de_despesa.id,
						orcamentos_da_despesa_attributes: {
							"0" => {
								valor: 50.00,
								fonte_de_recursos_id: fonte_de_recursos.id
							},
							"1" => {
								valor: 50.00,
								fonte_de_recursos_id: fonte_de_recursos.id
							}
						}
					}
				}
			}

			subacao.update(atributos_de_elementos_de_despesa_por_subacao)

			expect(
				subacao.errors[:"elementos_de_despesa_por_subacao.orcamentos_da_despesa"][0]
			).to include( 'fonte de recursos deve ser único dentro de elemento de despesa' )
		end
	end

	describe '#codigo_e_descricao_fonte' do
		it 'retorna o código e a descrição da fonte relacionada ao orçamento da despesa' do
		  orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_educacao ) )

			expect( orcamento_da_despesa.codigo_e_descricao_fonte ).to eq '129 - Taxas Vinculadas'
		end
	end

	describe '#unidade_orcamentaria' do
		it 'retorna a unidade orçamentaria relacionada indiretamente com o orçamento da despesa' do
		  orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_educacao ) )

			expect( orcamento_da_despesa.unidade_orcamentaria ).not_to be_nil
		end
	end

	describe '#orgao' do
		it 'retorna o orgao relacionado indiretamente com o orçamento da despesa' do
			orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_educacao ) )
			expect( orcamento_da_despesa.orgao ).not_to be_nil
		end
	end

	describe '#subacao' do
		it 'retorna a subacao relacionada diretamente com o orçamento da despesa' do
		  orcamento_da_despesa = Loa::OrcamentoDaDespesa.create( FactoryBot.attributes_for( :orcamento_da_despesa_educacao ) )

			expect( orcamento_da_despesa.subacao ).not_to be_nil
		end
	end

	describe '#classificacao_completa' do
		it 'retorna a classificação completa (Dotação) do orçamento de despesa' do
			orcamento_da_despesa = FactoryBot.create( :orcamento_da_despesa_educacao )
			expect( orcamento_da_despesa.classificacao_completa ).to eq "04 0002 80 126 1010 3.005 0001 3.3.90.30.00 129"
		end
	end

	describe '#funcional_programatica' do
		it 'retorna a funcional programática do orçamento de despesa' do
			orcamento_da_despesa = FactoryBot.create( :orcamento_da_despesa_educacao )
			expect( orcamento_da_despesa.funcional_programatica ).to eq "04 0002 80 126 1010 3.005"
		end
	end

	describe 'to_sim_orcamento_da_despesa' do
		before(:each) do
			FactoryBot.create(:configuracao)
		end

		it 'retorna string formatada para envio ao SIM' do
			orcamento_da_despesa = FactoryBot.build(:orcamento_da_despesa_saude)
			expect( orcamento_da_despesa.to_sim_orcamento_da_despesa ).to eq '"202","099","201600","04","00","33903000","Material de Consumo",12345.67'
		end
	end

	describe 'to_sim_elementos' do
		before(:each) do
			FactoryBot.create(:configuracao)
		end

		it 'retorna string formatada para envio ao SIM' do
			orcamento_da_despesa = FactoryBot.build(:orcamento_da_despesa_saude)
			expect( orcamento_da_despesa.to_sim_elementos ).to eq '"204","099","201600","04","00","80","126","1010","3","005","0001","33903000","1","32",12345.67'
		end
	end
end
