require 'rails_helper'

RSpec.describe Contabilidade::Convenio, type: :model do

	it{ is_expected.to belong_to( :orcamento ).required }
	it{ is_expected.to belong_to( :funcao ).class_name('Base::Funcao') }
	it{ is_expected.to belong_to( :tipo_de_transferencia ).class_name('Base::TipoDeTransferencia') }
	it{ is_expected.to belong_to( :tipo_de_esfera ).class_name('Base::TipoDeEsfera') }
	it{ is_expected.to belong_to( :unidade_orcamentaria ).class_name('Loa::UnidadeOrcamentaria') }
	it{ is_expected.to belong_to( :receita_corrente ).class_name('Base::NaturezaDaReceita').inverse_of(:convenios) }
	it{ is_expected.to belong_to( :receita_de_capital ).class_name('Base::NaturezaDaReceita').inverse_of(:convenios) }
	it{ is_expected.to belong_to( :convenio ).class_name('Ppa::Convenio') }

	it{ is_expected.to have_many( :valores_do_convenio ).dependent(:destroy).inverse_of(:convenio) }
	it{ is_expected.to have_many( :convenios_contas_bancarias ) }
	it{ is_expected.to have_many( :contas_bancarias ).class_name('Base::ContaBancaria').through( :convenios_contas_bancarias ) }



	describe "Quando contexto for Contabilidade" do
		subject{
			FactoryBot.build(:convenio0001, contexto_atual_convenio: 'Contabilidade')
		}

		[:data_da_celebracao, :inicio_da_vigencia, :fim_da_vigencia,
			:funcao_id, :tipo_de_esfera_id, :modalidade,
			:valor_da_contrapartida, :tipo_de_transferencia_id].each do |atributo|

			it{ is_expected.to validate_presence_of atributo }
		end

		it { is_expected.to allow_value('01/01/2016').for(:data_da_celebracao) }
		it { is_expected.to_not allow_value('').for(:data_da_celebracao) }
		it { is_expected.to_not allow_value('00/').for(:data_da_celebracao) }

		it { is_expected.to allow_value('01/01/2016').for(:inicio_da_vigencia) }
		it { is_expected.to_not allow_value('').for(:inicio_da_vigencia) }
		it { is_expected.to_not allow_value('00/').for(:inicio_da_vigencia) }

		it { is_expected.to allow_value('01/01/2016').for(:fim_da_vigencia) }
		it { is_expected.to_not allow_value('').for(:fim_da_vigencia) }
		it { is_expected.to_not allow_value('00/').for(:fim_da_vigencia) }
	end

	[:numero].each do |atributo|
		it{ is_expected.to validate_uniqueness_of( atributo ).scoped_to(:orcamento_id)}
	end

	describe "#ano_orcamento_e_numero" do
		it "retorna numero e ano do orçamento" do
			convenio = FactoryBot.build(:convenio0001)

			expect(convenio.ano_orcamento_e_numero).to eq "0001/2016"
		end
	end

	describe "#valor_total" do
		it "soma o valor do repasse com o valor da contrapartida" do
			convenio = Contabilidade::Convenio.new
			convenio.valor_do_repasse = 1200000
			convenio.valor_da_contrapartida = 12000

			expect(convenio.valor_total).to eq 1212000
		end
	end

	describe "#periodo" do
		it "informa o periodo do convenio" do
			convenio = Contabilidade::Convenio.new
			convenio.inicio_da_vigencia = Time.local(2016, 8, 1)
			convenio.fim_da_vigencia = Time.local(2016, 9, 20)

			expect(convenio.periodo).to eq "01/08/2016 - 20/09/2016"
		end
	end

	describe "importacao de convenio ppa para contabilidade" do
		before(:each) do
			FactoryBot.create(:despesa_corrente)
			FactoryBot.create(:despesa_de_capital)
			@convenios = []
			@orcamento = FactoryBot.create(:orcamento_2016)
			@convenio = FactoryBot.create(:convenio0001, orcamento_id: @orcamento.id)
		end

		describe "#periodo_exercicio_orcamento_para_convenio" do
			it 'percorre periodo de exercicio do orcamento' do
			  novo_periodo = @orcamento.exercicio..@orcamento.exercicio + 2
				expect(@convenio.periodo_exercicio_orcamento_para_convenio @orcamento).to eq novo_periodo
			end
		end

		describe "#convenio_ja_foi_importado" do
			it 'retorna verdadeiro caso convenio já esteja importado' do
				convenio_ppa = FactoryBot.create(:ppa_convenio)
				novo_convenio = Contabilidade::Convenio.new(orcamento_id: @orcamento.id, convenio_id: convenio_ppa.id)
				novo_convenio.save(validate: false)
				expect(novo_convenio.id).to eq Contabilidade::Convenio.find_by(convenio_id: convenio_ppa.id).id
			end
		end

		describe "#criar_valores_do_convenio_por_ano_do_orcamento_atual" do
			it 'cria um novo convenio por tipo de despesa corrente' do
				skip "Corrigir quando corrigir os convênios no orçamento"
				convenio = Contabilidade::Convenio.find(@convenio.id)
				convenio_ppa = FactoryBot.create(:ppa_convenio)
				convenio.criar_valores_do_convenio_por_ano_do_orcamento_atual_a_partir_do_ppa convenio_ppa
				despesa_corrente = Contabilidade::ValorDoConvenio.find_by(convenio_id: convenio.id)

				expect(despesa_corrente.convenio_id).to eq convenio.id
			end
		end

		describe "#importa_convenios_para_orcamento" do
			it 'importa convenios do ppa para orcamento' do
				@convenios << FactoryBot.create(:ppa_convenio).id
				Contabilidade::Convenio.importa_convenios_para_orcamento @convenios, @orcamento.id

				expect(Contabilidade::Convenio.last.orcamento_id).to eq @orcamento.id
			end

			it 'cria valores de convenio para novo convenio de Contabilidade' do
				@convenios << FactoryBot.create(:ppa_convenio).id
				Contabilidade::Convenio.importa_convenios_para_orcamento @convenios, @orcamento.id
				novo_convenio = Contabilidade::Convenio.last.id

				expect(Contabilidade::ValorDoConvenio.last.convenio_id).to eq novo_convenio
			end
		end
	end

	describe "after_update" do
		context "#atualiza_valor_da_projecao_para_receita_corrente" do
			it 'retorna true' do
				valor_do_convenio = 150.5
				convenio = FactoryBot.create(:convenio0001, receita_de_capital_id: nil)
				convenio_valor = convenio.valores_do_convenio.where(exercicio: 2016, tipo_de_despesa: Base::TipoDeDespesa.find_by(codigo: 1)).last
				convenio_valor.update(valor: valor_do_convenio)
				convenio.save

				expect(Projecao::CalculoPorExercicio.find_by(tipo:3).total).to eq(valor_do_convenio)
			end
		end

		context "#atualiza_valor_da_projecao_para_receita_de_capital" do
			it 'retorna true' do
				valor_do_convenio = 150.5
				convenio = FactoryBot.create(:convenio0001, receita_corrente_id: nil)
				convenio_valor = convenio.valores_do_convenio.where(exercicio: 2016, tipo_de_despesa: Base::TipoDeDespesa.find_by(codigo: 2)).last
				convenio_valor.update(valor: valor_do_convenio)
				convenio.save

				expect(Projecao::CalculoPorExercicio.find_by(tipo:3).total).to eq(valor_do_convenio)
			end
		end

		describe "#atualiza_valor_por_receita_corrente_alterado" do
			context "ao trocar uma receita corrente por outra receita corrente" do
				# it "retira valor de calculo por exercicio da receita corrente anterior" do
				# 	receita_corrente = FactoryBot.create(:nova_natureza_receita_corrente, :novo_tipo)
				# 	outra_receita_corrente = FactoryBot.create(:nova_natureza_receita_corrente, :novo_tipo, codigo: '0011110111600000')
				#
				# 	orcamento = receita_corrente.modulo
				#
				# 	convenio = FactoryBot.create(:convenio0001, receita_corrente_id: receita_corrente.id, receita_de_capital_id: nil)
				# 	# FactoryBot.create(:contabilidade_valor_do_convenio, :despesa_corrente, convenio_id: convenio.id)
				#
				# 	valor_do_convenio_que_vai_pra_projecao = convenio.valores_do_convenio.find_by(exercicio: orcamento.exercicio, tipo_de_despesa_id: Base::TipoDeDespesa.find_by(codigo:receita_corrente.categoria_economica.to_i) )
				# 	valor_do_convenio_que_vai_pra_projecao.update(valor: 1000)
				# 	convenio.save
				#
				# 	calculo = Projecao::CalculoPorExercicio.find_by(total: 1000)
				#
				# 	convenio.update(receita_corrente_id: outra_receita_corrente.id)
				# 	calculo.reload
				# 	expect(calculo.total).to eq 0
				# end

				it "continua com valor do convenio projetado para a nova receita corrente" do
					receita_corrente = FactoryBot.create(:nova_natureza_receita_corrente, :novo_tipo)
					outra_receita_corrente = FactoryBot.create(:nova_natureza_receita_corrente, :novo_tipo, codigo: '0011110111600000')

					orcamento = receita_corrente.modulo

					convenio = FactoryBot.create(:convenio0001, receita_corrente_id: receita_corrente.id, receita_de_capital_id: nil)
					valor_do_convenio_que_vai_pra_projecao = convenio.valores_do_convenio.find_by(exercicio: orcamento.exercicio, tipo_de_despesa_id: Base::TipoDeDespesa.find_by(codigo:receita_corrente.categoria_economica.to_i) )
					valor_do_convenio_que_vai_pra_projecao.update(valor: 1000)
					convenio.save

					convenio.update(receita_corrente_id: outra_receita_corrente.id)
					valor_do_convenio_que_vai_pra_projecao.reload
					expect(valor_do_convenio_que_vai_pra_projecao.valor).to eq 1000
				end
			end

			context "ao trocar uma receita corrente por uma receita de capital" do
				# it "zera os valores do convenio da receita corrente" do
				# 	receita_corrente = FactoryBot.create(:nova_natureza_receita_corrente, :novo_tipo)
				# 	receita_capital = FactoryBot.create(:nova_natureza_receita_capital, :novo_tipo)
				#
				# 	orcamento = receita_corrente.modulo
				#
				# 	convenio = FactoryBot.create(:convenio0001, receita_corrente_id: receita_corrente.id, receita_de_capital_id: nil)
				# 	valor_do_convenio_que_vai_pra_projecao = convenio.valores_do_convenio.find_by(exercicio: orcamento.exercicio, tipo_de_despesa_id: Base::TipoDeDespesa.find_by(codigo:receita_corrente.categoria_economica.to_i) )
				# 	valor_do_convenio_que_vai_pra_projecao.update(valor: 1000)
				# 	convenio.save
				#
				# 	calculo = Projecao::CalculoPorExercicio.find_by(total: 1000)
				# 	convenio.update(receita_corrente_id: nil, receita_de_capital_id: receita_capital.id)
				# 	calculo.reload
				# 	expect(calculo.total).to eq 0
				# end

				it "zera valor do convenio projetado para a nova receita de capital" do
					skip "Corrigir quando corrigir os convênios no orçamento"
					receita_corrente = FactoryBot.create(:nova_natureza_receita_corrente, :novo_tipo)
					receita_capital = FactoryBot.create(:nova_natureza_receita_capital, :novo_tipo)

					orcamento = receita_corrente.modulo

					convenio = FactoryBot.create(:convenio0001, receita_corrente_id: receita_corrente.id, receita_de_capital_id: nil)
					valor_do_convenio_que_vai_pra_projecao = convenio.valores_do_convenio.find_by(exercicio: orcamento.exercicio, tipo_de_despesa_id: Base::TipoDeDespesa.find_by(codigo:receita_corrente.categoria_economica.to_i) )
					valor_do_convenio_que_vai_pra_projecao.update(valor: 1000)
					convenio.save

					convenio.update(receita_corrente_id: nil, receita_de_capital_id: receita_capital.id)
					convenio.save

					valor_do_convenio_que_vai_pra_projecao.reload
					expect(valor_do_convenio_que_vai_pra_projecao.valor).to eq 0
				end
			end
		end

		describe "#atualiza_valor_por_receita_de_capital_alterado" do
			context "ao trocar uma receita de capital por outra receita de capital" do
				# it "retira valor de calculo por exercicio da receita de capital anterior" do
				# 	receita_capital = FactoryBot.create(:nova_natureza_receita_capital, :novo_tipo)
				# 	outra_receita_capital = FactoryBot.create(:nova_natureza_receita_capital, :novo_tipo, codigo: '0021110111600000')
				#
				# 	orcamento = receita_capital.modulo
				#
				# 	convenio = FactoryBot.create(:convenio0001, receita_de_capital_id: receita_capital.id, receita_corrente_id: nil)
				# 	valor_do_convenio_que_vai_pra_projecao = convenio.valores_do_convenio.find_by(exercicio: orcamento.exercicio, tipo_de_despesa_id: Base::TipoDeDespesa.find_by(codigo:receita_capital.categoria_economica.to_i) )
				# 	valor_do_convenio_que_vai_pra_projecao.update(valor: 1000)
				# 	convenio.save
				#
				# 	calculo = Projecao::CalculoPorExercicio.find_by(total: 1000)
				#
				# 	convenio.update(receita_de_capital_id: outra_receita_capital.id)
				# 	calculo.reload
				# 	expect(calculo.total).to eq 0
				# end

				it "continua com valor do convenio projetado para a nova receita de capital" do
					receita_capital = FactoryBot.create(:nova_natureza_receita_capital, :novo_tipo)
					outra_receita_capital = FactoryBot.create(:nova_natureza_receita_capital, :novo_tipo, codigo: '0021110111600000')

					orcamento = receita_capital.modulo

					convenio = FactoryBot.create(:convenio0001, receita_corrente_id: receita_capital.id, receita_de_capital_id: nil)
					valor_do_convenio_que_vai_pra_projecao = convenio.valores_do_convenio.find_by(exercicio: orcamento.exercicio, tipo_de_despesa_id: Base::TipoDeDespesa.find_by(codigo:receita_capital.categoria_economica.to_i) )
					valor_do_convenio_que_vai_pra_projecao.update(valor: 1000)
					convenio.save

					convenio.update(receita_corrente_id: outra_receita_capital.id)
					valor_do_convenio_que_vai_pra_projecao.reload
					expect(valor_do_convenio_que_vai_pra_projecao.valor).to eq 1000
				end
			end

			context "ao trocar uma receita de capital por uma receita corrente" do
				# it "zera os valores do convenio da receita capital" do
				# 	receita_corrente = FactoryBot.create(:nova_natureza_receita_corrente, :novo_tipo)
				# 	receita_capital = FactoryBot.create(:nova_natureza_receita_capital, :novo_tipo)
				#
				# 	orcamento = receita_corrente.modulo
				#
				# 	convenio = FactoryBot.create(:convenio0001, receita_corrente_id: nil, receita_de_capital_id: receita_capital.id)
				# 	valor_do_convenio_que_vai_pra_projecao = convenio.valores_do_convenio.find_by(exercicio: orcamento.exercicio, tipo_de_despesa_id: Base::TipoDeDespesa.find_by(codigo:receita_capital.categoria_economica.to_i) )
				# 	valor_do_convenio_que_vai_pra_projecao.update(valor: 1000)
				# 	convenio.save
				#
				# 	calculo = Projecao::CalculoPorExercicio.find_by(total: 1000)
				#
				# 	convenio.update(receita_corrente_id: receita_corrente.id, receita_de_capital_id: nil)
				# 	calculo.reload
				# 	expect(calculo.total).to eq 0
				# end

				it "zera valor do convenio projetado para a nova receita de corrente e troca o tipo de despesa" do
					skip "Corrigir quando corrigir os convênios no orçamento"
					receita_corrente = FactoryBot.create(:nova_natureza_receita_corrente, :novo_tipo)
					receita_capital = FactoryBot.create(:nova_natureza_receita_capital, :novo_tipo)

					orcamento = receita_corrente.modulo

					convenio = FactoryBot.create(:convenio0001, receita_corrente_id: nil, receita_de_capital_id: receita_capital.id)
					valor_do_convenio_que_vai_pra_projecao = convenio.valores_do_convenio.find_by(exercicio: orcamento.exercicio, tipo_de_despesa_id: Base::TipoDeDespesa.find_by(codigo:receita_capital.categoria_economica.to_i) )
					valor_do_convenio_que_vai_pra_projecao.update(valor: 1000)
					convenio.save

					convenio.update(receita_corrente_id: receita_capital.id, receita_de_capital_id: nil)
					convenio.save

					valor_do_convenio_que_vai_pra_projecao.reload
					expect(valor_do_convenio_que_vai_pra_projecao.valor).to eq 0
				end
			end
		end
	end

	describe "before_destroy" do
		context "#atualiza_valor_da_projecao_para_receita_corrente" do
			it 'retorna true' do
				skip "Corrigir quando corrigir os convênios no orçamento"
				convenio = FactoryBot.create(:convenio0001, receita_de_capital_id: nil)
				convenio_valor = convenio.valores_do_convenio.where(exercicio: 2016, tipo_de_despesa: Base::TipoDeDespesa.find_by(codigo: 1)).last
				convenio_valor.update(valor: 150.5)
				convenio.save

				convenio.destroy

				expect(Projecao::CalculoPorExercicio.find_by(tipo:3).total).to eq(0)
			end
		end

		context "#atualiza_valor_da_projecao_para_receita_de_capital" do
			it 'retorna nil' do
				skip "Corrigir quando corrigir os convênios no orçamento"
				convenio = FactoryBot.create(:convenio0001, receita_corrente_id: nil)
				convenio_valor = convenio.valores_do_convenio.where(exercicio: 2016, tipo_de_despesa: Base::TipoDeDespesa.find_by(codigo: 2)).last
				convenio_valor.update(valor: 150.5)
				convenio.save

				convenio.destroy
				expect(Projecao::CalculoPorExercicio.find_by(tipo:3).total).to eq(0)
			end
		end
	end

	describe 'criar convenios com ao menos um tipo de receita' do
		context 'salvando sem nenhum receita' do
			it 'retorna erro' do
				convenio = FactoryBot.build(:ppa_convenio, receita_corrente_id: '', receita_de_capital_id: '')
				convenio.save
				expect(convenio.errors[:receita_corrente_id]).to include "No mínimo uma receita corrente ou de capital deve ser escolhida."
				expect(convenio.errors[:receita_de_capital_id]).to include "No mínimo uma receita corrente ou de capital deve ser escolhida."
			end
		end

		context 'salvar com ao menos uma receita' do
			it 'salva convênio' do
				receita = FactoryBot.create(:receita_corrente)
				convenio = FactoryBot.build(:ppa_convenio, receita_corrente_id: receita.id, receita_de_capital_id: '')
				convenio.save
				expect(convenio).to be_persisted
			end
		end
	end
end
