require 'rails_helper'

RSpec.describe Licitacao::ItemDoAditivo, type: :model do
	it { is_expected.to belong_to(:item_do_lote).class_name('Licitacao::ItemDoLote').required(true) }
	it { is_expected.to belong_to(:aditivo).class_name('Licitacao::Aditivo').required(true) }

	it { is_expected.to delegate_method(:contrato).to(:aditivo) }

	it { is_expected.to validate_presence_of(:item_do_lote_id) }
	it { is_expected.to validate_presence_of(:aditivo_id) }

	it { is_expected.to validate_numericality_of(:quantidade).is_greater_than_or_equal_to(0).allow_nil }

	describe "#valor_do_item" do
		describe "Descriminação de item" do
			before(:each) do
				@contrato = FactoryBot.create :licitacao_contrato, :com_lotes_do_contrato
				@aditivo = FactoryBot.create :licitacao_aditivo, contrato_id: @contrato.id, inicio_da_vigencia: "22/10/2016", fim_da_vigencia: "25/10/2016" , objeto: "Objeto de Teste"
			end

			it "retorna o preco unitario" do
				item_do_aditivo = FactoryBot.create(:licitacao_item_do_aditivo, quantidade: 15, aditivo_id: @aditivo.id, item_do_lote_id: @aditivo.itens_do_lote_do_contrato.first.id)
				expect(item_do_aditivo.valor_do_item).to eq 9.99
			end

			it "tem reajuste de preco no contrato" do
				aditivo_reajuste = FactoryBot.create :licitacao_aditivo,:de_reajuste, contrato_id: @contrato.id, inicio_da_vigencia: "20/10/2016", objeto: "Objeto de Teste", status: "confirmado"
				item_do_aditivo_de_reajuste = FactoryBot.create(:licitacao_item_do_aditivo, quantidade: 9, aditivo_id: aditivo_reajuste.id, item_do_lote_id: aditivo_reajuste.itens_do_lote_do_contrato.first.id, valor_adicionado: 10)
				aditivo_reajuste_2 = FactoryBot.create :licitacao_aditivo,:de_reajuste, contrato_id: @contrato.id, inicio_da_vigencia: "21/10/2016", objeto: "Objeto de Teste", status: "confirmado"
				item_do_aditivo_de_reajuste_2 = FactoryBot.create(:licitacao_item_do_aditivo, quantidade: 9, aditivo_id: aditivo_reajuste_2.id, item_do_lote_id: aditivo_reajuste_2.itens_do_lote_do_contrato.first.id, valor_adicionado: 10)
				expect(item_do_aditivo_de_reajuste_2.valor_do_item).to eq 19.99
			end

			it "tem aditivo na ata de registro de preco" do
				contrato = FactoryBot.build(:licitacao_contrato, :com_ata_de_registro_de_preco, discriminacao_obrigatoria_de_itens: true, status: 1)
        contrato.save(validate: false)
				FactoryBot.create(:licitacao_item_do_contrato, contrato_id: contrato.id , quantidade: 10)
        item_da_ata = contrato.ata_de_registro_de_precos.itens_da_ata.build(item_do_lote_id: contrato.itens_do_contrato.first.item_do_lote_id)
				item_da_ata.save
				aditivo_reajuste = FactoryBot.create :licitacao_aditivo_da_ata, ata_de_registro_de_precos_id: contrato.ata_de_registro_de_precos.id, data_do_aditivo: "20/10/2016", objeto: "Objeto de Teste", status: "confirmado"
				item_do_aditivo_de_reajuste = FactoryBot.build(:licitacao_item_do_aditivo_da_ata, quantidade: 9, aditivo_da_ata_id: aditivo_reajuste.id, item_do_lote_id: item_da_ata.item_do_lote.id, valor_adicionado: 10)
				item_do_aditivo_de_reajuste.save(validate: false)
				aditivo_reajuste_2 = FactoryBot.create :licitacao_aditivo, :de_reajuste, contrato_id: contrato.id, inicio_da_vigencia: "21/10/2016", objeto: "Objeto de Teste", status: "confirmado"
				item_do_aditivo_de_reajuste_2 = FactoryBot.create(:licitacao_item_do_aditivo, quantidade: 9, aditivo_id: aditivo_reajuste_2.id, item_do_lote_id: aditivo_reajuste_2.itens_do_lote_do_contrato.first.id, valor_adicionado: 10)
				expect(item_do_aditivo_de_reajuste_2.valor_do_item).to eq 10.0
			end

			it "tem item por desconto" do
				pedido = FactoryBot.create(:pedido, :com_itens_por_valor, status: "fechado")
				item_do_pedido = FactoryBot.build(:item_do_pedido, pedido_id: pedido.id, tipo: "por_desconto")
				item_do_pedido.save!
				item_do_pedido_por_unidade_orcamentaria = FactoryBot.build(:item_da_unidade_orcamentaria, item_do_pedido_id: item_do_pedido.id, unidade_orcamentaria_por_pedido_id: pedido.unidade_orcamentaria.id, valor_previsto_desconto: 100)
				item_do_pedido_por_unidade_orcamentaria.save!
				projeto = Licitacao::Projeto.create(pedido_id: pedido.id)
				projeto.save(validate: false)
				item_do_lote = FactoryBot.build(:licitacao_item_do_lote, item_do_pedido_id: item_do_pedido.id)
				item_do_lote.save(validate: false)
				contrato = FactoryBot.build(:licitacao_contrato, projeto_id: projeto.id )
				contrato.save(validate: false)
				item_do_contrato = FactoryBot.build(:licitacao_item_do_contrato, item_do_lote_id: item_do_lote.id, contrato_id: contrato.id)
				item_do_contrato.save(validate: false)

				aditivo = FactoryBot.create :licitacao_aditivo, contrato_id: contrato.id, inicio_da_vigencia: "22/10/2016", fim_da_vigencia: "25/10/2016" , objeto: "Objeto de Teste"
				item_do_aditivo = FactoryBot.create(:licitacao_item_do_aditivo, quantidade: 3, aditivo_id: aditivo.id, item_do_lote_id: item_do_lote.id, valor_adicionado: 10)
				expect(item_do_aditivo.valor_do_item).to eq 100.0
			end

		end
	end

	describe "#lote_de_produto?" do
		before(:each) do
			@item_do_aditivo = FactoryBot.build(:licitacao_item_do_aditivo)
		end
		it "retorna true se o item tiver lote e for de produto" do
			@item_do_aditivo.item_do_lote.lote.produto!
			@item_do_aditivo.save
			expect(@item_do_aditivo.lote_de_produto?).to be true
		end
		it "retorna false se o item tiver lote e for de serviço" do
			@item_do_aditivo.item_do_lote.lote.servico!
			@item_do_aditivo.save
			expect(@item_do_aditivo.lote_de_produto?).to be false
		end
		it "retorna false se o item não tiver lote" do
			@item_do_aditivo.item_do_lote.lote = nil
			@item_do_aditivo.save
			expect(@item_do_aditivo.lote_de_produto?).to be false
		end
	end

	describe "#lote_de_servico?" do
		before(:each) do
			@item_do_aditivo = FactoryBot.build(:licitacao_item_do_aditivo)
		end
		it "retorna true se o item tiver lote e for de serviço" do
			@item_do_aditivo.item_do_lote.lote.servico!
			@item_do_aditivo.save
			expect(@item_do_aditivo.lote_de_servico?).to be true
		end
		it "retorna false se o item tiver lote e for de produto" do
			@item_do_aditivo.item_do_lote.lote.produto!
			@item_do_aditivo.save
			expect(@item_do_aditivo.lote_de_servico?).to be false
		end
		it "retorna false se o item não tiver lote" do
			@item_do_aditivo.item_do_lote.lote = nil
			@item_do_aditivo.save
			expect(@item_do_aditivo.lote_de_servico?).to be false
		end
	end

	describe '#apaga_a_si_mesmo_se_quantidade_for_zero_ou_nula' do
		before(:each) do
			@contrato = FactoryBot.create :licitacao_contrato, :com_lotes_do_contrato
			@aditivo = FactoryBot.create :licitacao_aditivo, contrato_id: @contrato.id, inicio_da_vigencia: "22/10/2016", fim_da_vigencia: "25/10/2016" , objeto: "Objeto de Teste"
		end

		it 'quando a qtd do item é zero' do
			item_do_aditivo = FactoryBot.build(:licitacao_item_do_aditivo, quantidade: 0, aditivo_id: @aditivo.id, item_do_lote_id: @aditivo.itens_do_lote_do_contrato.first.id)
			item_do_aditivo.save
			expect(item_do_aditivo.persisted?).to be_falsey
		end

		it 'quando a qtd do item é nula' do
			item_do_aditivo = FactoryBot.build(:licitacao_item_do_aditivo, quantidade: nil, aditivo_id: @aditivo.id, item_do_lote_id: @aditivo.itens_do_lote_do_contrato.first.id)
			item_do_aditivo.save
			expect(item_do_aditivo.persisted?).to be_falsey
		end

		it 'quando a qtd do item é maior que zero' do
			item_do_aditivo = FactoryBot.create(:licitacao_item_do_aditivo, quantidade: 15, aditivo_id: @aditivo.id, item_do_lote_id: @aditivo.itens_do_lote_do_contrato.first.id)
			item_do_aditivo.reload
			item_do_aditivo.quantidade = 10
			item_do_aditivo.save

			expect(item_do_aditivo.persisted?).to be_truthy
		end
	end

	describe "#valida_quantidade_de_itens_para_aditivo_de_acrescimo" do
		before(:each) do
			@contrato = FactoryBot.create :licitacao_contrato, :com_lotes_do_contrato
			@aditivo = FactoryBot.create :licitacao_aditivo, modalidade: :reajuste_de_valor_acrescimo, contrato_id: @contrato.id, inicio_da_vigencia: "21/10/2016", fim_da_vigencia: "25/10/2016" , objeto: "Objeto de Teste"
		end
		context "quando a qtd é maior que 50% da qtd do item do contrato" do
			it "retorna erro se o lote for de produto" do
				# qtd do item do contrato = 10
				item_do_aditivo = FactoryBot.build(:licitacao_item_do_aditivo, quantidade: 11, aditivo_id: @aditivo.id, item_do_lote_id: @aditivo.itens_do_lote_do_contrato.first.id)
				item_do_aditivo.item_do_lote.lote.produto!
				item_do_aditivo.save
				expect(item_do_aditivo.errors[:quantidade]).to include("não pode ser maior que o limite disponível")
			end

		#	it "deixa passar se o lote for de serviço" do
			#	item_do_aditivo = FactoryBot.build(:licitacao_item_do_aditivo, quantidade: 20, aditivo_id: @aditivo.id, item_do_lote_id: @aditivo.itens_do_lote_do_contrato.first.id)
			#	item_do_aditivo.item_do_lote.lote.servico!
		#		item_do_aditivo.save
			#	expect(item_do_aditivo.errors[:quantidade]).to_not include("Não pode ser maior que 50% do saldo da quantidade de itens do contrato")
		#	end
		end
	end

	#describe "#quantidade_permitida_para_acrescimo" do
	#	before(:each) do
	#		@contrato = FactoryBot.create :licitacao_contrato, :com_lotes_do_contrato
	#		@aditivo = FactoryBot.create :licitacao_aditivo, modalidade: :acrescimo, contrato_id: @contrato.id, inicio_da_vigencia: "22/10/2016", fim_da_vigencia: "25/10/2016" , objeto: "Objeto de Teste"
	#	end

		#context "quando o lote do item for de produto" do
			#context "e não tiver aditivos" do
			#	it "retorna 50% da quantidade do item do contrato" do
			#		item_do_aditivo = FactoryBot.build(:licitacao_item_do_aditivo, quantidade: 0, aditivo_id: @aditivo.id, item_do_lote_id: @aditivo.itens_do_lote_do_contrato.first.id)
			#		item_do_aditivo.item_do_lote.lote.produto!
			#		item_do_aditivo.save
					# qtd do item do contrato = 10
					# 50% de 10 = 5
			#		expect(item_do_aditivo.quantidade_permitida_para_acrescimo).to eq 5
			#	end
			#end

		#	context "e tiver aditivos" do
		#		it "retorna 50% da quantidade do item do contrato menos a qtd dos aditivos" do
		#			item_do_aditivo = FactoryBot.build(:licitacao_item_do_aditivo, quantidade: 1, aditivo_id: @aditivo.id, item_do_lote_id: @aditivo.itens_do_lote_do_contrato.first.id)
		#			item_do_aditivo.item_do_lote.lote.produto!
		#			item_do_aditivo.save
					# qtd do item do contrato = 10
					# 50% de 10 = 5
					# 5 - 1 do aditivo = 4
		#			expect(item_do_aditivo.quantidade_permitida_para_acrescimo).to eq 4
		#		end
		#	end
		#end

	#	context "quanto o lote do item for de serviço" do
	#		it "retorna o saldo do item do contrato" do
	#			item_do_lote = @aditivo.itens_do_lote_do_contrato.first
	#			@contrato.itens_do_contrato.find_by_item_do_lote_id(item_do_lote).update_column(:quantidade, 100)
	#			item_do_aditivo = FactoryBot.build(:licitacao_item_do_aditivo, quantidade: 25, aditivo_id: @aditivo.id, item_do_lote_id: @aditivo.itens_do_lote_do_contrato.first.id)
	#			item_do_aditivo.item_do_lote.lote.servico!
	#			item_do_aditivo.save
				# qtd do item do contrato = 100
				# 100 + 25 do aditivo => 125
	#			expect(item_do_aditivo.quantidade_permitida_para_acrescimo).to eq 125
	#		end
	#	end
	#end

	describe "#valida_quantidade_de_itens_para_aditivo_de_reducao" do
		before(:each) do
			@contrato = FactoryBot.create :licitacao_contrato, :com_lotes_do_contrato
			@aditivo = FactoryBot.create :licitacao_aditivo, modalidade: :reducao, contrato_id: @contrato.id, inicio_da_vigencia: "22/10/2016", fim_da_vigencia: "25/10/2016" , objeto: "Objeto de Teste"
		end

		context "quando o lote do item é de produto" do
			it "retorna erro se a qtd for maior que 50% da qtd do item do contrato" do
				#qtd do item do contrato = 10
				#50% da qtd = 5
				item_do_aditivo = FactoryBot.build(:licitacao_item_do_aditivo, quantidade: 11, aditivo_id: @aditivo.id, item_do_lote_id: @aditivo.itens_do_lote_do_contrato.first.id)
				item_do_aditivo.item_do_lote.lote.produto!
				item_do_aditivo.save
				expect(item_do_aditivo.errors[:quantidade]).to include("não pode ser maior que o saldo de itens no contrato")
			end
		end

		#context "quando o lote do item é de serviço" do #removido eh uma validação repetida
		#	it "retorna erro se a qtd for maior que o saldo do item do contrato" do
		#		#saldo do item do contrato = 10
		#		item_do_aditivo = FactoryBot.build(:licitacao_item_do_aditivo, quantidade: 11, aditivo_id: @aditivo.id, item_do_lote_id: @aditivo.itens_do_lote_do_contrato.first.id)
		#		item_do_aditivo.item_do_lote.lote.servico!
		#		item_do_aditivo.save
		#		expect(item_do_aditivo.errors[:quantidade]).to include("não pode ser maior que o saldo de itens no contrato")
		#	end
		#end
	end

	describe "#quantidade_permitida_para_reducao" do
		before(:each) do
			@contrato = FactoryBot.create :licitacao_contrato, :com_lotes_do_contrato
			@aditivo = FactoryBot.create :licitacao_aditivo, modalidade: :reducao, contrato_id: @contrato.id, inicio_da_vigencia: "22/10/2016", fim_da_vigencia: "25/10/2016" , objeto: "Objeto de Teste"
		end

		context "quando o lote do item for de produto" do
			context "e não tiver aditivos" do
				it "retorna 50% da quantidade do item do contrato" do
					item_do_aditivo = FactoryBot.build(:licitacao_item_do_aditivo, quantidade: 0, aditivo_id: @aditivo.id, item_do_lote_id: @aditivo.itens_do_lote_do_contrato.first.id)
					item_do_aditivo.item_do_lote.lote.produto!
					item_do_aditivo.save
					# qtd do item do contrato = 10
					# 50% de 10 = 5
					expect(item_do_aditivo.quantidade_permitida_para_reducao).to eq 10
				end
			end

			context "e tiver aditivos" do
				it "retorna 50% da quantidade do item do contrato menos a qtd dos aditivos" do
					item_do_aditivo = FactoryBot.build(:licitacao_item_do_aditivo, quantidade: 1, aditivo_id: @aditivo.id, item_do_lote_id: @aditivo.itens_do_lote_do_contrato.first.id)
					item_do_aditivo.item_do_lote.lote.produto!
					item_do_aditivo.save
					# qtd do item do contrato = 10
					# 50% de 10 = 5
					# 5 - 1 do aditivo = 4
					expect(item_do_aditivo.quantidade_permitida_para_reducao).to eq 10
				end
			end
		end

		context "quanto o lote do item for de serviço" do
			it "retorna o saldo do item do contrato" do
				item_do_lote = @aditivo.itens_do_lote_do_contrato.first
				@contrato.itens_do_contrato.find_by_item_do_lote_id(item_do_lote).update_column(:quantidade, 100)
				item_do_aditivo = FactoryBot.build(:licitacao_item_do_aditivo, quantidade: 25, aditivo_id: @aditivo.id, item_do_lote_id: @aditivo.itens_do_lote_do_contrato.first.id)
				item_do_aditivo.item_do_lote.lote.servico!
				item_do_aditivo.save
				# qtd do item do contrato = 100
				# 100 - 25 do aditivo => 75
				expect(item_do_aditivo.quantidade_permitida_para_reducao).to eq 100
			end
		end
	end
end
