require 'rails_helper'

RSpec.describe Orcamento, type: :model do
	cria_configuracao_default

	it{ is_expected.to belong_to(:ppa).class_name('Ppa::Ppa')}
	it{ is_expected.to have_one(:projecao_de_receita).class_name('Projecao::ProjecaoDeReceita').dependent(:destroy)}

	it{ is_expected.to have_many(:imposto_sobre_servicos).class_name('Contabilidade::ImpostoSobreServico').dependent(:destroy) }
	it{ is_expected.to have_many(:orgaos).class_name('Loa::Orgao').dependent(:restrict_with_exception)}
	it{ is_expected.to have_many(:unidades_orcamentarias).class_name('Loa::UnidadeOrcamentaria').through(:orgaos) }
	it{ is_expected.to have_many(:unidades_orcamentarias_por_usuario).class_name('Loa::UnidadeOrcamentariaPorUsuario').through(:unidades_orcamentarias) }
	it{ is_expected.to have_many(:programas_de_governo).dependent(:restrict_with_exception)}
	it{ is_expected.to have_many(:acoes).class_name('Loa::Acao').through(:programas_de_governo) }
	it{ is_expected.to have_many(:transferencias_de_recursos).class_name('Loa::TransferenciaDeRecurso').dependent(:restrict_with_exception) }
	it{ is_expected.to have_many(:tipos_de_deducao).class_name('Loa::TipoDeDeducao').dependent(:destroy) }
	it{ is_expected.to have_many(:funcoes).class_name('Base::Funcao').dependent(:destroy) }
	it{ is_expected.to have_many(:subfuncoes).class_name('Base::Subfuncao').through(:funcoes) }
	it{ is_expected.to have_many(:naturezas_da_receita).class_name('Base::NaturezaDaReceita')}
	it{ is_expected.to have_many(:tipos_de_orcamento).class_name('Base::TipoDeOrcamento').dependent(:destroy) }
	it{ is_expected.to have_many(:tipos_de_administracao).class_name('Base::TipoDeAdministracao').dependent(:destroy) }
	it{ is_expected.to have_many(:tipos_de_unidades_administrativas).class_name('Base::TipoDeUnidadeAdministrativa').dependent(:destroy) }
	it{ is_expected.to have_many(:naturezas_da_acao).class_name('Base::NaturezaDaAcao').dependent(:destroy)}
	it{ is_expected.to have_many(:grupos_das_fontes_de_recursos).class_name('Base::GrupoDaFonteDeRecursos').dependent(:destroy) }
	it{ is_expected.to have_many(:fontes_tce).class_name('Base::FontesDeRecursos::FonteTCE').dependent(:destroy) }
	it{ is_expected.to have_many(:fontes2018).class_name('Base::FontesDeRecursos::Fonte2018').dependent(:destroy) }
	it{ is_expected.to have_many(:fontes_stn).class_name('Base::FontesDeRecursos::FonteStn').dependent(:destroy) }
	it{ is_expected.to have_many(:categorias_economicas).class_name('Base::CategoriaEconomica').dependent(:destroy)}
	it{ is_expected.to have_many(:grupos_de_natureza_da_despesa).class_name('Base::GrupoDeNaturezaDaDespesa').through(:categorias_economicas) }
	it{ is_expected.to have_many(:modalidades_de_aplicacao).class_name('Base::ModalidadeDeAplicacao').through(:grupos_de_natureza_da_despesa) }
	it{ is_expected.to have_many(:elementos_de_despesa).class_name('Base::ElementoDeDespesa').through(:modalidades_de_aplicacao) }
	it{ is_expected.to have_many(:agencias).class_name('Base::Agencia').dependent(:restrict_with_exception) }
	it{ is_expected.to have_many(:tipos_de_esfera).class_name('Base::TipoDeEsfera').dependent(:destroy) }
	it{ is_expected.to have_many(:convenios).class_name('Contabilidade::Convenio').dependent(:restrict_with_exception) }
	it{ is_expected.to have_many(:taloes_de_receita).class_name('Contabilidade::TalaoDeReceita').dependent(:restrict_with_exception) }
	it{ is_expected.to have_many(:obras).class_name('Contabilidade::Obra').dependent(:restrict_with_exception) }
	it{ is_expected.to have_many(:diarias).class_name('Contabilidade::Diaria').dependent(:restrict_with_exception) }
	it{ is_expected.to have_many(:empenhos).class_name('Contabilidade::Empenho').dependent(:restrict_with_exception) }
	it{ is_expected.to have_many(:classificacoes_das_fontes_de_recursos).class_name('Base::ClassificacaoDaFonteDeRecursos').dependent(:destroy) }
	it{ is_expected.to have_many(:grupo_de_contas).class_name('Contabilidade::GrupoDeConta').dependent(:destroy) }
	it{ is_expected.to have_many(:contas).class_name('Contabilidade::Conta').dependent(:destroy) }
	it{ is_expected.to have_many(:eventos_contabeis).class_name('Contabilidade::EventoContabil').dependent(:restrict_with_exception) }
	it{ is_expected.to have_many(:contas_extra_orcamentarias).class_name('Contabilidade::ContaExtraOrcamentaria').dependent(:destroy) }
	it{ is_expected.to have_many(:irrfs_pessoas_juridicas).class_name('Contabilidade::IrrfPessoaJuridica').dependent(:destroy) }
	it{ is_expected.to have_many(:inss_pessoas_juridicas).class_name('Contabilidade::InssPessoaJuridica').dependent(:destroy) }
	it{ is_expected.to have_many(:temas_do_orcamento).class_name('Loa::TemaDoOrcamento').dependent(:destroy) }
	it{ is_expected.to have_many(:lotes_do_tcm).class_name('Tcm::Lote').dependent(:destroy) }
	it{ is_expected.to have_many(:pedidos).class_name('Licitacao::Pedido') }
	it{ is_expected.to have_many(:projetos).class_name('Licitacao::Projeto') }
	it{ is_expected.to have_many(:processos).class_name('Licitacao::Processo') }
	it{ is_expected.to have_many(:ordens_de_compra).class_name('Licitacao::OrdemDeCompra') }
	it{ is_expected.to have_many(:receitas_stn).class_name('Base::ReceitaStn').dependent(:destroy) }
	it{ is_expected.to have_many(:publicacoes).class_name('Licitacao::Publicacao').through(:projetos) }
	it{ is_expected.to have_many(:comissoes).class_name('Licitacao::Comissao').through(:projetos) }
	it{ is_expected.to have_many(:membros_das_comissoes).class_name('Licitacao::MembroDaComissao').through(:projetos) }
	it{ is_expected.to have_many(:pessoas_dos_projetos).class_name('Licitacao::PessoaDoProjeto').through(:projetos) }
	it{ is_expected.to have_many(:orcamentos_da_despesa_por_projetos).class_name('Licitacao::OrcamentoDaDespesaPorProjeto').through(:projetos) }
	it{ is_expected.to have_many(:itens_dos_lotes_dos_projetos).class_name('Licitacao::ItemDoLote').through(:projetos) }
	it{ is_expected.to have_many(:contratos).class_name('Licitacao::Contrato') }
	it{ is_expected.to have_many(:aditivos).class_name('Licitacao::Aditivo') }
	it{ is_expected.to have_many(:contratados).class_name('Licitacao::Contratado').through(:contratos) }
	it{ is_expected.to have_many(:lances).class_name('Licitacao::Lance').through(:rodadas) }
	it{ is_expected.to have_many(:comites_de_investimento).class_name('Contabilidade::ComiteDeInvestimento')}
	it{ is_expected.to have_many(:parcelamentos_do_rpps).class_name('Contabilidade::ParcelamentoDoRpps')}


	it{ is_expected.to validate_presence_of :exercicio }
	it{ is_expected.to validate_presence_of :status }
	it{ is_expected.to validate_presence_of :percentual_despesa_com_pessoal }

	it { is_expected.to validate_uniqueness_of :exercicio }

	it { is_expected.to validate_numericality_of(:percentual_da_reserva_de_contingencia).is_greater_than_or_equal_to(0).allow_nil }
	it { is_expected.to validate_numericality_of(:percentual_da_reserva_de_contingencia).is_less_than(100).allow_nil }

	it { is_expected.to validate_numericality_of(:percentual_normativo_da_ldo).is_greater_than_or_equal_to(0).allow_nil }
	it { is_expected.to validate_numericality_of(:percentual_normativo_da_ldo).is_less_than(100).allow_nil }

	it { is_expected.to validate_numericality_of(:percentual_despesa_com_pessoal).is_greater_than_or_equal_to(0) }
	it { is_expected.to validate_numericality_of(:percentual_despesa_com_pessoal).is_less_than(100) }

	it { is_expected.to validate_attachment_content_type(:arquivo_de_contexto).allowing('application/pdf').rejecting('image/png', 'image/gif') }
	it { is_expected.to validate_attachment_size(:arquivo_de_contexto).less_than(10.megabytes) }

	let(:orcamento) {
		FactoryBot.build(:orcamento_2016)
	}

	describe '#fontes_de_recursos' do
		context 'quando o orçamento é 2018' do
			it 'retorna Base::FontesDeRecursos::Fonte2018'
		end
		context 'quando o orçamento é 2019' do
			it 'retorna Base::FontesDeRecursos::FonteTCE'
		end
	end

	it "não permite alterações no atributo exercicio" do
		orcamento = FactoryBot.create( :orcamento_2016 )
		orcamento.exercicio = orcamento.exercicio + 1
		orcamento.validate
		expect( orcamento.errors[:exercicio] ).to include "não pode ser alterado"
	end

	describe "#verificar_exercicio_do_ppa" do
		context "quando exercicio do orçamento não contem no intervalo do ppa" do
			it "retorna erro" do
				ppa = FactoryBot.create( :ppa_fortaleza_2014 )
				orcamento = FactoryBot.build( :orcamento_2016, exercicio: 2019, ppa_id: ppa.id)
				orcamento.save
				expect(orcamento.errors[:ppa_id] ).to include "O exercicio do orçamento deve estar no intervalo do PPA"
			end
		end
		context "quando exercicio do orçamento contem no intervalo do ppa" do
			it "salva o orçamento" do
				ppa = FactoryBot.create( :ppa_fortaleza_2014 )
				orcamento = FactoryBot.build( :orcamento_2016, exercicio: 2014, ppa_id: ppa.id)
				orcamento.save
				expect(orcamento).to be_persisted
			end
		end
	end

	describe "#utiliza_novo_tipo_para_receita?" do
		context "quando exercicio do ppa é maior que 2018" do
			it "retorna true" do
				orcamento = FactoryBot.build(:orcamento_2016, exercicio: 2019)
				expect(orcamento.utiliza_novo_tipo_para_receita?).to eq true
			end
		end

		context "quando exercicio ppa é menor ou igual a 2018" do
			it "retorna false" do
				orcamento = FactoryBot.build(:orcamento_2016)
				expect(orcamento.utiliza_novo_tipo_para_receita?).to eq false
			end
		end
	end

	describe 'imutabilidade do campo trabalha_com_subacao' do
		context 'quando o orçamento possui ações' do
			it 'é verificada' do
				acao = FactoryBot.create :acao_9005, :orcamento_2016
				orcamento = acao.programa_de_governo.orcamento
				orcamento.update(trabalha_com_subacao: false)
				expect(orcamento.errors[:trabalha_com_subacao]).to include "não pode ser alterado"
			end
		end
		context 'quando o orçamento não possui ações' do
			it 'não é verificada' do
				orcamento = FactoryBot.create :orcamento_2016
				orcamento.update(trabalha_com_subacao: false)
				expect(orcamento).to be_persisted
			end
		end
	end

	describe "#to_param" do
		it "retorna exercicio como string" do
			orcamento = Orcamento.new(exercicio: "2016")
			expect( orcamento.to_param ).to eq('2016')
		end
	end

	describe "valor_percentual_da_reserva_de_contingencia" do
		it "percentual_normativo_da_ldo menor que percentual_da_reserva_de_contingencia" do
			orcamento = Orcamento.new(percentual_normativo_da_ldo: 10, percentual_da_reserva_de_contingencia: 20)
			orcamento.validate

			expect(orcamento.errors[:percentual_da_reserva_de_contingencia]).to include "deve ser menor ou igual ao percentual normativo da LDO para reserva de contingência"
		end

		it "percentual_normativo_da_ldo igual a percentual_da_reserva_de_contingencia" do
			orcamento = Orcamento.new(percentual_normativo_da_ldo: 10, percentual_da_reserva_de_contingencia: 10)
			orcamento.validate

			expect(orcamento.errors[:percentual_da_reserva_de_contingencia]).to_not include "deve ser menor ou igual ao percentual normativo da LDO para reserva de contingência"
		end

		it "percentual_normativo_da_ldo maior que percentual_da_reserva_de_contingencia" do
			orcamento = Orcamento.new(percentual_normativo_da_ldo: 20, percentual_da_reserva_de_contingencia: 10)
			orcamento.validate

			expect(orcamento.errors[:percentual_da_reserva_de_contingencia]).to_not include "deve ser menor ou igual ao percentual normativo da LDO para reserva de contingência"
		end
	end

	describe 'to_sim' do
		it 'retorna string formatada para envio ao SIM' do
			orcamento = FactoryBot.build(:orcamento_2016)
			expect( orcamento.to_sim ).to eq "\"200\",\"099\",201600,\"02456/15\",0.00,20170101,20170101,20170101" 
		end
	end

	describe 'ppa_esta_sendo_utilizado?' do
		context 'um novo orcamento está sendo criado' do
			it 'e nenhum ppa foi selecionado' do
				skip
			end

			it 'e um ppa foi selecionado' do
				skip
			end
		end

		context 'um orçamento está sendo editado' do
			it 'e não havia ppa selecionado quando o orçamento foi criado' do
				skip
			end

			it 'e não contém programas importados' do
				skip
			end

			it 'e contém programas importados' do
				skip
			end
		end
	end


	# context 'orgaos por usuario' do
	# 	before :each do
	# 		@orgao1 = FactoryBot.create(:loa_secretaria_de_saude, :orcamento_2016)
	# 		@orgao2 = FactoryBot.create(:loa_desenvolvimento_economico, :orcamento_2016)
	# 		@perfil_administrador = FactoryBot.create(:perfil_administrador)
	# 		@perfil_comum = FactoryBot.create(:perfil_comum)
	# 	end

	# 	it 'é admin' do
	# 		orcamento_2016 = Orcamento.find_by(exercicio: 2016)
	# 		usuario = FactoryBot.create(:admin)

	# 		expect(orcamento_2016.orgaos_do_usuario(usuario)).to eq orcamento_2016.orgaos
	# 	end

	# 	it 'não pode acessar nenhum órgão' do
	# 		orcamento_2016 = Orcamento.find_by(exercicio: 2016)
	# 		usuario = FactoryBot.create(:usuario_comum, nivel_de_permissao_a_unidades: :nenhuma_unidade)

	# 		expect(orcamento_2016.orgaos_do_usuario(usuario)).to eq Loa::Orgao.none
	# 	end

	# 	it 'pode acessar todos os órgãos' do
	# 		orcamento_2016 = Orcamento.find_by(exercicio: 2016)
	# 		usuario = FactoryBot.create(:usuario_comum, nivel_de_permissao_a_unidades: :todas_as_unidades)

	# 		expect(orcamento_2016.orgaos_do_usuario(usuario)).to eq orcamento_2016.orgaos
	# 	end

	# 	it 'só pode acessar órgãos selecionados' do
	# 		orcamento_2016 = Orcamento.find_by(exercicio: 2016)
	# 		usuario = FactoryBot.create(:usuario_comum, nivel_de_permissao_a_unidades: :unidades_selecionadas)
	# 		unidade_orcamentaria_por_usuario = FactoryBot.create(:unidade_orcamentaria_por_usuario, usuario: usuario)

	# 		expect(orcamento_2016.orgaos_do_usuario(usuario)).to include(unidade_orcamentaria_por_usuario.unidade_orcamentaria.orgao)
	# 	end
	# end

	# context 'unidades orcamentárias por usuário' do
	# 	before :each do
	# 		@unidade_orcamentaria_1 = FactoryBot.create(:loa_hgf, :orcamento_2016)
	# 		@unidade_orcamentaria_2 = FactoryBot.create(:loa_fes, :orcamento_2016)
	# 		@perfil_administrador = FactoryBot.create(:perfil_administrador)
	# 		@perfil_comum = FactoryBot.create(:perfil_comum)
	# 	end

	# 	it 'é admin' do
	# 		orcamento_2016 = Orcamento.find_by(exercicio: 2016)
	# 		usuario = FactoryBot.create(:admin)

	# 		expect(orcamento_2016.unidades_orcamentarias_do_usuario(usuario)).to eq orcamento_2016.unidades_orcamentarias
	# 	end

	# 	it 'não pode acessar nenhum órgão' do
	# 		orcamento_2016 = Orcamento.find_by(exercicio: 2016)
	# 		usuario = FactoryBot.create(:usuario_comum, nivel_de_permissao_a_unidades: :nenhuma_unidade)

	# 		expect(orcamento_2016.unidades_orcamentarias_do_usuario(usuario)).to eq Loa::UnidadeOrcamentaria.none
	# 	end

	# 	it 'pode acessar todos os órgãos' do
	# 		orcamento_2016 = Orcamento.find_by(exercicio: 2016)
	# 		usuario = FactoryBot.create(:usuario_comum, nivel_de_permissao_a_unidades: :todas_as_unidades)

	# 		expect(orcamento_2016.unidades_orcamentarias_do_usuario(usuario)).to eq orcamento_2016.unidades_orcamentarias
	# 	end

	# 	it 'só pode acessar órgãos selecionados' do
	# 		orcamento_2016 = Orcamento.find_by(exercicio: 2016)
	# 		usuario = FactoryBot.create(:usuario_comum, nivel_de_permissao_a_unidades: :unidades_selecionadas)
	# 		unidade_orcamentaria_por_usuario = FactoryBot.create(:unidade_orcamentaria_por_usuario, usuario: usuario)

	# 		expect(orcamento_2016.unidades_orcamentarias_do_usuario(usuario)).to include(unidade_orcamentaria_por_usuario.unidade_orcamentaria)
	# 	end
	# end

end
