require 'rails_helper'

RSpec.describe Contabilidade::Liquidacao, type: :model do
	it{ is_expected.to have_many(:vistos).class_name("Controladoria::Visto") }

	context "Envia para controladoria" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Envia para controladoria quando Configuração está habilitada" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_controladoria: true)
			@liquidacao.update_attribute(:status, :solicitado)
			@liquidacao.enviar_para_controladoria
			expect(@liquidacao.enviado_para_controladoria?).to be_truthy
		end
		it "Não envia para a controladoria quando Configuração está desabilitada" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_controladoria: false)
			@liquidacao.update_attribute(:status, :solicitado)
			@liquidacao.enviar_para_controladoria
			expect(@liquidacao.enviado_para_controladoria?).to be_falsey
		end
	end

	context "Retorna para o Administartivo" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Quando foi reprovado pela controladoria" do
			@liquidacao.update_attribute(:status, :enviado_para_controladoria)
			FactoryBot.build(:controladoria_visto, aprovado: false, vistoriavel_id: @liquidacao.id, vistoriavel_type: "Contabilidade::Liquidacao").save(validate: false)
			@liquidacao.retornar_para_administrativo
			expect(@liquidacao.solicitado?).to be_truthy
		end
		it "Quando não foi reprovado pela controladoria" do
			@liquidacao.update_attribute(:status, :enviado_para_controladoria)
			FactoryBot.build(:controladoria_visto, aprovado: true, vistoriavel_id: @liquidacao.id, vistoriavel_type: "Contabilidade::Liquidacao").save(validate: false)
			@liquidacao.retornar_para_administrativo
			expect(@liquidacao.solicitado?).to be_falsey
		end
		it "Quando está sendo retornado pela contabilidade" do
			@liquidacao.update_attribute(:status, :enviado_para_contabilidade)
			@liquidacao.retornar_para_administrativo
			expect(@liquidacao.solicitado?).to be_truthy
		end
	end

	context "Enviar para a contabilidade" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Quando Configuração para enviar para a contabilidade está habilitada e envia para controladoria desabilitada, e status é solicitado" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: true, envia_liquidacao_para_controladoria: false)
			@liquidacao.update_attribute(:status, :solicitado)
			@liquidacao.enviar_para_contabilidade
			expect(@liquidacao.enviado_para_contabilidade?).to be_truthy
		end
		it " Quando Configuração para enviar para a contabilidade está habilitada e envia para controladoria habilitada, e status é solicitado " do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: true, envia_liquidacao_para_controladoria: true)
			@liquidacao.update_attribute(:status, :solicitado)
			@liquidacao.enviar_para_contabilidade
			expect(@liquidacao.enviado_para_contabilidade?).to be_falsey
		end
		it "Quando status é solicitado e Configuração enviar para contabilidade está desabilitada" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false)
			@liquidacao.update_attribute(:status, :solicitado)
			@liquidacao.enviar_para_contabilidade
			expect(@liquidacao.enviado_para_contabilidade?).to be_falsey
		end
		it "Quando status é enviado_para_controladoria e está aprovado pela controladoria e Configuração está habilidata para enviar para contabilidade" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: true)
			@liquidacao.update_attribute(:status, :enviado_para_controladoria)
			FactoryBot.build(:controladoria_visto, aprovado: true, vistoriavel_id: @liquidacao.id, vistoriavel_type: "Contabilidade::Liquidacao").save(validate: false)
			@liquidacao.enviar_para_contabilidade
			expect(@liquidacao.enviado_para_contabilidade?).to be_truthy
		end
		it "Quando status é enviado_para_contabilidade e está reprovado pela contorladoria e Configuração está habilitada para enviar para contabilidade" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: true)
			@liquidacao.update_attribute(:status, :enviado_para_controladoria)
			FactoryBot.build(:controladoria_visto, aprovado: false, vistoriavel_id: @liquidacao.id, vistoriavel_type: "Contabilidade::Liquidacao").save(validate: false)
			@liquidacao.enviar_para_contabilidade
			expect(@liquidacao.enviado_para_contabilidade?).to be_falsey
		end
		it "Quando status é enviado_para_controladoria e está aprovado pela controladoria e Configuração está desabilitada para enviar para contabilidade" do
		FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false)
		@liquidacao.update_attribute(:status, :enviado_para_controladoria)
		FactoryBot.build(:controladoria_visto, aprovado: true, vistoriavel_id: @liquidacao.id, vistoriavel_type: "Contabilidade::Liquidacao").save(validate: false)
		@liquidacao.enviar_para_contabilidade
		expect(@liquidacao.enviado_para_contabilidade?).to be_falsey
		end
	end

	context "Receber" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Quando status é enviado_para_contabilidade" do
			@liquidacao.update_attribute(:status, :enviado_para_contabilidade)
			@liquidacao.receber
			expect(@liquidacao.recebido?).to be_truthy
		end
		it "Quando status não é enviado_para_contabilidade" do
			@liquidacao.update_attribute(:status, :enviado_para_controladoria)
			@liquidacao.receber
			expect(@liquidacao.recebido?).to be_falsey
		end
	end

	context "Enviar para o financeiro" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Quando existem itens e status é confirmado e nota fiscal preenchida" do
			FactoryBot.create(:item_da_nota_fiscal_caderno, liquidacao_id: @liquidacao.id)
			@liquidacao.update_attribute(:status, :confirmado)
			nota_fiscal = FactoryBot.build(:contabilidade_nota_fiscal, liquidacao_id: @liquidacao.id)
			nota_fiscal.save(validate: false)
			@liquidacao.reload
			@liquidacao.enviar_para_o_financeiro
			expect(@liquidacao.enviado_para_o_financeiro?).to be_truthy
		end
		it "Quando existem itens e status é confirmado mas nota fiscal não está preenchida" do
			FactoryBot.create(:item_da_nota_fiscal_caderno, liquidacao_id: @liquidacao.id)
			@liquidacao.update_attribute(:status, :confirmado)
			@liquidacao.reload
			@liquidacao.enviar_para_o_financeiro
			expect(@liquidacao.enviado_para_o_financeiro?).to be_falsey
		end
		it "Quando existem itens e status não é confirmado e nota fiscal esta preenchida" do
			FactoryBot.create(:item_da_nota_fiscal_caderno, liquidacao_id: @liquidacao.id)
			@liquidacao.update_attribute(:status, :enviado_para_contabilidade)
			nota_fiscal = FactoryBot.build(:contabilidade_nota_fiscal, liquidacao_id: @liquidacao.id)
			nota_fiscal.save(validate: false)
			@liquidacao.reload
			@liquidacao.enviar_para_o_financeiro
			expect(@liquidacao.enviado_para_o_financeiro?).to be_falsey
		end
	end

	context "Receber pelo financeiro" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Quando status é enviado_para_o_financeiro" do
			@liquidacao.update_attribute(:status, :enviado_para_o_financeiro)
			@liquidacao.receber_pelo_financeiro
			expect(@liquidacao.recebido_pelo_financeiro?).to be_truthy
		end
		it "Quando status não é enviado_para_o_financeiro" do
			@liquidacao.update_attribute(:status, :confirmado)
			@liquidacao.receber_pelo_financeiro
			expect(@liquidacao.recebido_pelo_financeiro?).to be_falsey
		end
	end

	context "Enviar para Administrativo" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Quando status é enviado_para_controladoria e foi aprovado pela controladoria e não usa Configuração da Contabilidade" do
			@liquidacao.update_attribute(:status, :enviado_para_controladoria)
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false)
			FactoryBot.build(:controladoria_visto, aprovado: true, vistoriavel_id: @liquidacao.id, vistoriavel_type: "Contabilidade::Liquidacao").save(validate: false)
			@liquidacao.enviar_para_administrativo
			expect(@liquidacao.enviado_para_administrativo?).to be_truthy
		end
		it "Quando status é enviado_para_controladoria e foi reaprovado pela controladoria e não usa Configuração da Contabilidade" do
			@liquidacao.update_attribute(:status, :enviado_para_controladoria)
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false)
			FactoryBot.build(:controladoria_visto, aprovado: false, vistoriavel_id: @liquidacao.id, vistoriavel_type: "Contabilidade::Liquidacao").save(validate: false)
			@liquidacao.enviar_para_administrativo
			expect(@liquidacao.enviado_para_administrativo?).to be_falsey
		end
		it "Quando status não é enviado_para_controladoria e foi aprovado pela controladoria e não usa Configuração da Contabilidade" do
			@liquidacao.update_attribute(:status, :confirmado)
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false)
			FactoryBot.build(:controladoria_visto, aprovado: true, vistoriavel_id: @liquidacao.id, vistoriavel_type: "Contabilidade::Liquidacao").save(validate: false)
			@liquidacao.enviar_para_administrativo
			expect(@liquidacao.enviado_para_administrativo?).to be_falsey
		end
		it "Quando status é enviado_para_controladoria e foi aprovado pela controladoria e usa Configuração da Contabilidade" do
			@liquidacao.update_attribute(:status, :enviado_para_controladoria)
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: true)
			FactoryBot.build(:controladoria_visto, aprovado: true, vistoriavel_id: @liquidacao.id, vistoriavel_type: "Contabilidade::Liquidacao").save(validate: false)
			@liquidacao.enviar_para_administrativo
			expect(@liquidacao.enviado_para_administrativo?).to be_falsey
		end
	end

	context "Confirmar" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Quando tem itens e o valor é igual a liquidação e status é enviado_para_administrativo" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false)
			FactoryBot.build(:item_da_nota_fiscal_caderno, liquidacao_id: @liquidacao.id, total: 123).save(validate: false)
			@liquidacao.update_attribute(:status, :enviado_para_administrativo)
			@liquidacao.reload
			@liquidacao.confirmar
			expect(@liquidacao.confirmado?).to be_truthy
		end
		it "Quando tem itens e o valor é igual a liquidação e status é enviado_para_o_financeiro" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false)
			FactoryBot.build(:item_da_nota_fiscal_caderno, liquidacao_id: @liquidacao.id, total: 123).save(validate: false)
			@liquidacao.update_attribute(:status, :enviado_para_o_financeiro)
			@liquidacao.reload
			@liquidacao.confirmar
			expect(@liquidacao.confirmado?).to be_truthy
		end
		it "Quando tem itens e o valor é igual a liquidação e status é recebido_pelo_financeiro" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false)
			FactoryBot.build(:item_da_nota_fiscal_caderno, liquidacao_id: @liquidacao.id, total: 123).save(validate: false)
			@liquidacao.update_attribute(:status, :recebido_pelo_financeiro)
			@liquidacao.reload
			@liquidacao.confirmar
			expect(@liquidacao.confirmado?).to be_truthy
		end
		it "Quando tem itens e o valor é igual a liquidação e status é recebido" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false)
			FactoryBot.build(:item_da_nota_fiscal_caderno, liquidacao_id: @liquidacao.id, total: 123).save(validate: false)
			@liquidacao.update_attribute(:status, :recebido)
			@liquidacao.reload
			@liquidacao.confirmar
			expect(@liquidacao.confirmado?).to be_truthy
		end
		it "Quando tem itens e o valor é igual a liquidação e status é solicitado Configuração não envia pra contabilidade e nem para controladoria e nota fiscal preenchida e está logado na contabilidade" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false, envia_liquidacao_para_controladoria: false)
			FactoryBot.build(:item_da_nota_fiscal_caderno, liquidacao_id: @liquidacao.id, total: 123).save(validate: false)
			@liquidacao.update_attribute(:status, :solicitado)
			@liquidacao.update_attribute(:tipo_de_reconhecimento_do_passivo, :reconhecido_na_liquidacao_da_despesa)
			nota_fiscal = FactoryBot.build(:contabilidade_nota_fiscal, liquidacao_id: @liquidacao.id)
			nota_fiscal.save(validate: false)
			@liquidacao.reload
			allow(@liquidacao).to receive(:logado_na_contabilidade).and_return(true)
			@liquidacao.confirmar
			expect(@liquidacao.confirmado?).to be_truthy
		end
		it "Quando tem itens e o valor é igual a liquidação e status é solicitado Configuração não envia pra contabilidade e nem para controladoria e não está logado na contabilidade" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false, envia_liquidacao_para_controladoria: false)
			FactoryBot.build(:item_da_nota_fiscal_caderno, liquidacao_id: @liquidacao.id, total: 123).save(validate: false)
			@liquidacao.update_attribute(:status, :solicitado)
			@liquidacao.reload
			allow(@liquidacao).to receive(:logado_na_contabilidade).and_return(false)
			@liquidacao.confirmar
			expect(@liquidacao.confirmado?).to be_truthy
		end
		it "Quando não tem itens e status é solicitado e Configuração não envia para contabilidade e nem para controladoria e tem nota fiscal" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false, envia_liquidacao_para_controladoria: false)
			@liquidacao.update_attribute(:status, :solicitado)
			nota_fiscal = FactoryBot.build(:contabilidade_nota_fiscal, liquidacao_id: @liquidacao.id)
			nota_fiscal.save(validate: false)
			@liquidacao.reload
			allow(@liquidacao).to receive(:logado_na_contabilidade).and_return(false)
			@liquidacao.confirmar
			expect(@liquidacao.confirmado?).to be_falsey
		end
	end

	context "Retornar para Solicitado" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Liquidação não possui pagamentos, não foi estornada, não foi enviada ao SIM e não usa Configuração de enviar para contabilidade" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false)
			@liquidacao.update_attribute(:status, :confirmado)
			@liquidacao.retornar_para_solicitado
			expect(@liquidacao.solicitado?).to be_truthy
		end
		it "Quando usa Configuração de enviar para contabilidade e não possui pagamentos"  do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: true)
			@liquidacao.update_attribute(:status, :confirmado)
			@liquidacao.retornar_para_solicitado
			expect(@liquidacao.solicitado?).to be_falsey
		end
		it "Quando possui Pagamento" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false)
			FactoryBot.build(:pagamento, liquidacao_id: @liquidacao.id).save(validate: false)
			@liquidacao.update_attribute(:status, :confirmado)
			@liquidacao.retornar_para_solicitado
			expect(@liquidacao.solicitado?).to be_falsey
		end
		it "Quando Liquidação foi estornada" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false)
			@liquidacao.update_attribute(:status, :confirmado)
			@liquidacao.update_attribute(:estornada, true)
			@liquidacao.retornar_para_solicitado
			expect(@liquidacao.solicitado?).to be_falsey
		end
		it "Quando Liquidação foi enviada ao sim" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false)
			@liquidacao.update_attribute(:status, :confirmado)
			@liquidacao.update_attribute(:arquivo_id, 1)
			@liquidacao.retornar_para_solicitado
			expect(@liquidacao.solicitado?).to be_falsey
		end
		it "Quando usa Configuração de enviar para contabilidade e possui pagamentos"  do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: true)
			@liquidacao.update_attribute(:status, :confirmado)
			@liquidacao.retornar_para_solicitado
			expect(@liquidacao.enviado_para_contabilidade?).to be_truthy
		end
	end

	context "Autorizar" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Quando status é recebido_pelo_financeiro" do
			@liquidacao.update_attribute(:status, :recebido_pelo_financeiro)
			@liquidacao.autorizar
			expect(@liquidacao.autorizado?).to be_truthy
		end
		it "Quando status não é recebido_pelo_financeiro" do
			@liquidacao.update_attribute(:status, :solicitado)
			@liquidacao.autorizar
			expect(@liquidacao.autorizado?).to be_falsey
		end
	end

	context "Retornar para confirmado" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Quando status é recebido_pelo_financeiro" do
			@liquidacao.update_attribute(:status, :recebido_pelo_financeiro)
			@liquidacao.retornar_para_confirmado
			expect(@liquidacao.confirmado?).to be_truthy
		end
		it "Quando status não é recebido_pelo_financeiro" do
			@liquidacao.update_attribute(:status, :solicitado)
			@liquidacao.retornar_para_confirmado
			expect(@liquidacao.confirmado?).to be_falsey
		end
	end

	context "Retornar para recebido" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it " Quando liquidação não foi enviada ao sim e não possui pagamentos e status é autorizado" do
			@liquidacao.update_attribute(:status, :autorizado)
			@liquidacao.retornar_para_recebido
			expect(@liquidacao.recebido_pelo_financeiro?).to be_truthy
		end
		it "Quando liquidação foi enviada ao sim" do
			@liquidacao.update_attribute(:status, :autorizado)
			@liquidacao.update_attribute(:arquivo_id, 1)
			@liquidacao.retornar_para_recebido
			expect(@liquidacao.recebido_pelo_financeiro?).to be_falsey
		end
		it "Quando lquidação tem pagamento" do
			FactoryBot.build(:pagamento, liquidacao_id: @liquidacao.id).save(validate: false)
			@liquidacao.update_attribute(:status, :autorizado)
			@liquidacao.reload
			@liquidacao.retornar_para_recebido
			expect(@liquidacao.recebido_pelo_financeiro?).to be_falsey
		end
	end

	context "Envia para controladoria" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Quando configuração está habilitada" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_controladoria: true)
			expect(@liquidacao.envia_pra_controladoria?).to be_truthy
		end
		it "Quando COnfiguracação está desabilitada" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_controladoria: false)
			expect(@liquidacao.envia_pra_controladoria?).to be_falsey
		end
	end

	context "Envia para Cofpsin" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Quando configuração está habilitada" do
			FactoryBot.create(:configuracao, envia_empenho_para_copfin: true)
			expect(@liquidacao.envia_pro_copfin?).to be_truthy
		end
		it "Quando COnfiguracação está desabilitada" do
			FactoryBot.create(:configuracao, envia_empenho_para_copfin: false)
			expect(@liquidacao.envia_pro_copfin?).to be_falsey
		end
	end

	context "Envia para contabilidade" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Quando configuração está habilitada" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: true)
			expect(@liquidacao.envia_pra_contabilidade?).to be_truthy
		end
		it "Quando COnfiguracação está desabilitada" do
			FactoryBot.create(:configuracao, envia_liquidacao_para_contabilidade: false)
			expect(@liquidacao.envia_pra_contabilidade?).to be_falsey
		end
	end

	context "Aprovado pela controladoria" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Quando tem visto e é positivo" do
			FactoryBot.build(:controladoria_visto, aprovado: true, vistoriavel_id: @liquidacao.id, vistoriavel_type: "Contabilidade::Liquidacao").save(validate: false)
			expect(@liquidacao.reload.aprovado_pela_controladoria?).to be_truthy
		end
		it "Quando tem visto e é negativo" do
			FactoryBot.build(:controladoria_visto, aprovado: false, vistoriavel_id: @liquidacao.id, vistoriavel_type: "Contabilidade::Liquidacao").save(validate: false)
			expect(@liquidacao.reload.aprovado_pela_controladoria?).to be_falsey
		end
		it "Quando não tem visto" do
			expect(@liquidacao.reload.aprovado_pela_controladoria?).to be_falsey
		end
	end

	context "Reprovado pela controladoria" do
		before(:each) do
			@liquidacao = FactoryBot.create(:liquidacao_001)
		end
		it "Quando tem visto e é negativo" do
			FactoryBot.build(:controladoria_visto, aprovado: false, vistoriavel_id: @liquidacao.id, vistoriavel_type: "Contabilidade::Liquidacao").save(validate: false)
			expect(@liquidacao.reload.reprovado_pela_controladoria?).to be_truthy
		end
		it "Quando tem visto e é positivo" do
			FactoryBot.build(:controladoria_visto, aprovado: true, vistoriavel_id: @liquidacao.id, vistoriavel_type: "Contabilidade::Liquidacao").save(validate: false)
			expect(@liquidacao.reload.reprovado_pela_controladoria?).to be_falsey
		end
		it "Quando não tem visto" do
			expect(@liquidacao.reload.reprovado_pela_controladoria?).to be_falsey
		end
	end
end
