
require 'rails_helper'

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

	it { is_expected.to belong_to(:fonte_de_recursos).class_name( 'Base::FonteDeRecursos').required(true)}
	it { is_expected.to belong_to(:unidade_orcamentaria_por_natureza_da_receita).required(true)}
	it{ is_expected.to have_many(:lancamentos_do_orcamento_da_receita).class_name( 'Contabilidade::LancamentoDoOrcamentoDaReceita').dependent(:destroy) }

	[:fonte_de_recursos_id, :unidade_orcamentaria_por_natureza_da_receita, :valor].each do |atributo|
		it{ is_expected.to validate_presence_of atributo }
	end

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

	describe '#update' do
		it 'validate_uniqueness_of fonte_de_recursos_id no escopo unidade_orcamentaria_por_natureza_da_receita_id' do
			natureza_da_receita = FactoryBot.create(:natureza_receita_corrente_pai)

			atributos_de_natureza_da_receita = {
				valor_previsto: 50000.00,
				unidades_orcamentarias_por_natureza_da_receita_attributes: {
					"0" => {
						unidade_orcamentaria_id: Loa::UnidadeOrcamentaria.find_or_create_by(FactoryBot.attributes_for :loa_hgf, :orcamento_2016).id,
						orcamentos_da_receita_attributes: {
							"0" => {
								valor: 40000.0,
								fonte_de_recursos_id: Base::FonteDeRecursos.find_or_create_by!(FactoryBot.attributes_for(:taxas_vinculadas)).id
							},
							"1" => {
								valor: 10000.0,
								fonte_de_recursos_id: Base::FonteDeRecursos.find_or_create_by!(FactoryBot.attributes_for(:taxas_vinculadas)).id
							}
						}
					}
				}
			}

			natureza_da_receita.update(atributos_de_natureza_da_receita)

			expect(
				natureza_da_receita.errors[:"unidades_orcamentarias_por_natureza_da_receita.orcamentos_da_receita"][0]
			).to include( 'fonte de recursos deve ser único dentro de uma unidade orcamentária' )
		end
	end

	describe '#valor_negativo_para_deducoes_de_receita' do
		context 'quando o valor é negativo para uma dedução da receita' do
			it "atributo valor não inclui mensagem de erro" do
				orcamento_da_receita = Loa::OrcamentoDaReceita.create( FactoryBot.attributes_for( :orcamento_da_deducao_da_receita ) )

				expect( orcamento_da_receita.errors[:valor] ).not_to include( 'valores negativos só são permitidos para classificações: 9.5.X.X.XX.XX.XX (deduções da receita)' )
			end
		end

		context 'quando o valor é negativo para uma receita que não é uma dedução' do
			it "atributo valor não inclui mensagem de erro" do
				orcamento_da_receita = Loa::OrcamentoDaReceita.create( FactoryBot.attributes_for( :orcamento_da_receita_educacao, valor: -4000.00 ) )

				expect( orcamento_da_receita.errors[:valor] ).to include( 'valores negativos só são permitidos para classificações: 9.5.X.X.XX.XX.XX (deduções da receita)' )
			end
		end
	end

	describe "saldo" do
		it "positivo" do
			orcamento_da_receita = FactoryBot.build( :orcamento_da_receita_educacao, valor: 187.67, valor_arrecadado: 20 )

			expect( orcamento_da_receita.saldo).to eq 167.67
		end

		it "negativo" do
			orcamento_da_receita = FactoryBot.build( :orcamento_da_receita_educacao, valor: 187.67, valor_arrecadado: 200 )

			expect( orcamento_da_receita.saldo.round(2) ).to eq (-12.33)
		end

		it "sem valor arrecadado" do
			orcamento_da_receita = FactoryBot.build( :orcamento_da_receita_educacao, valor: 187.67, valor_arrecadado: 0)

			expect( orcamento_da_receita.saldo).to eq 187.67
		end
	end

	describe "atualiza_saldo_dos_lancamentos" do
		before(:each) do
			allow_any_instance_of( Contabilidade::LancamentoDoOrcamentoDaReceita ).to receive( :valor_nao_passar_do_talao ).and_return(true)
		end

		it "nao_possui_lancamentos" do
			orcamento_da_receita = Loa::OrcamentoDaReceita.create( FactoryBot.attributes_for( :orcamento_da_deducao_da_receita, valor: 100.00 ) )

			orcamento_da_receita.atualiza_saldo_dos_lancamentos

			expect( orcamento_da_receita.lancamentos_do_orcamento_da_receita.count ).to eq 0
		end

		it "possui_lancamentos" do

			orcamento_da_receita = Loa::OrcamentoDaReceita.create( FactoryBot.attributes_for( :orcamento_da_deducao_da_receita, valor: 100.00 ) )

			talao_de_receita = Contabilidade::TalaoDeReceita.new
			talao_de_receita.save(validate: false)

			lancamento_do_orcamento_da_receita = FactoryBot.build(:contabilidade_lancamento_do_orcamento_da_receita, valor: 12.73, orcamento_da_receita: orcamento_da_receita, modulo: talao_de_receita)
			lancamento_do_orcamento_da_receita.save(validate: false)

			orcamento_da_receita.atualiza_saldo_dos_lancamentos

			expect( lancamento_do_orcamento_da_receita.reload.saldo.to_f ).to eq 87.27
		end
	end

	describe "escopo" do
		before(:each) do
		  @receita = Loa::OrcamentoDaReceita.create( FactoryBot.attributes_for( :orcamento_da_deducao_da_receita, valor: 100.00 ) )
		end

		context "fiscal" do
			it "deve incluir orçamentos cuja natureza da receita é fiscal" do
				expect( Loa::OrcamentoDaReceita.fiscal ).to include(@receita)
			end
		end

		context "social" do
			it "deve excluir orçamentos cuja natureza da receita é fiscal" do
				expect( Loa::OrcamentoDaReceita.social ).to_not include(@receita)
			end
		end
	end

	describe 'to_sim' do
		before(:each) do
			FactoryBot.create(:configuracao)
		end
		# testar sempre validando se o ultimo campo foi preenchido
		it 'retorna string formatada para envio ao SIM' do
			orcamento_da_receita = FactoryBot.build(:orcamento_da_receita_saude)
			expect( orcamento_da_receita.to_sim ).to eq '"201","099","201600","04","00","1235109900","1","32","Receita Corrente",10.00'
		end
	end
end
