require 'rails_helper'
include ActiveSupport::Testing::TimeHelpers

RSpec.describe Licitacao::Contrato, type: :model do
	it { is_expected.to belong_to(:unidade_orcamentaria_por_pedido).class_name('Licitacao::UnidadeOrcamentariaPorPedido') }
	it { is_expected.to belong_to(:contratado).class_name('Licitacao::Contratado') }
	it { is_expected.to belong_to(:projeto).class_name('Licitacao::Projeto').inverse_of(:contratos) }
	it { is_expected.to belong_to(:orcamento).class_name('Orcamento') }
	it { is_expected.to belong_to(:arquivo).class_name('Tcm::Arquivo') }
	it { is_expected.to delegate_method(:unidade_orcamentaria).to(:unidade_orcamentaria_por_pedido) }
	it { is_expected.to delegate_method(:pessoa).to(:pessoa_do_projeto) }
	it { is_expected.to delegate_method(:pessoa_id).to(:pessoa_do_projeto) }
	it { is_expected.to delegate_method(:cpf_ou_cnpj_e_nome).to(:pessoa) }
	it { is_expected.to have_many(:aditivos).class_name('Licitacao::Aditivo') }
	it { is_expected.to have_many(:itens_do_aditivo).through(:aditivos) }
	it { is_expected.to have_many(:itens_dos_lotes_dos_aditivos).through(:itens_do_aditivo).source(:item_do_lote) }
	it { is_expected.to have_many(:lotes_do_contrato).class_name('Licitacao::LoteDoContrato').dependent(:destroy) }
	it { is_expected.to have_many(:lotes).through(:lotes_do_contrato) }
	it { is_expected.to have_many(:itens_dos_lotes).through(:lotes).source(:itens_do_lote) }
	it { is_expected.to have_many(:itens_do_lote_do_contrato).through(:itens_do_contrato).source(:item_do_lote) }
	it { is_expected.to have_many(:orcamentos_da_despesa_do_contrato).class_name('Licitacao::OrcamentoDaDespesaDoContrato').dependent(:destroy) }
	it { is_expected.to have_many(:orcamentos_da_despesa).through(:orcamentos_da_despesa_do_contrato) }
	it { is_expected.to have_many(:itens_do_contrato).class_name('Licitacao::ItemDoContrato').dependent(:destroy) }
	it { is_expected.to have_many(:empenhos).class_name("Contabilidade::Empenho") }
	it { is_expected.to have_many(:itens_dos_empenhos).through(:empenhos).class_name("Contabilidade::ItemDoEmpenho") }
	it { is_expected.to have_many(:operacoes_de_credito_do_contrato).class_name("Licitacao::OperacaoDeCreditoDoContrato") }
	it { is_expected.to have_one(:obra).class_name('Contabilidade::Obra') }
	it { is_expected.to have_many(:operacoes_de_credito).through(:operacoes_de_credito_do_contrato).class_name("Obra::OperacaoDeCredito") }
	it { is_expected.to have_many(:componentes_da_operacao_de_credito).through(:operacoes_de_credito).class_name("Obra::ComponenteDaOperacaoDeCredito") }
	it { is_expected.to have_many(:acoes_do_componente).through(:componentes_da_operacao_de_credito).class_name("Obra::AcaoDoComponente") }
	it { is_expected.to have_many(:acoes_da_operacao_de_credito_do_contrato).through(:operacoes_de_credito_do_contrato).class_name("Licitacao::AcaoDaOperacaoDeCreditoDoContrato") }

	[:numero, :data_do_contrato, :tipo_de_contrato,:inicio_da_vigencia, :fim_da_vigencia].each do |atributo|
		subject { FactoryBot.build :licitacao_contrato }
		it { is_expected.to validate_presence_of atributo }
	end

	[:objeto, :justificativa].each do |atributo|
		before { allow(subject).to receive(:parceria?).and_return(true) }
		it { is_expected.to validate_presence_of atributo }
	end

	it { is_expected.to validate_presence_of(:lotes_do_contrato).with_message("Por favor, selecione ao menos um lote") }

	describe ':motivo_do_cancelamento' do
		context 'com pedido cancelado' do
			subject { FactoryBot.build :licitacao_contrato, :com_lotes_do_contrato, status: :cancelado }
			it{ is_expected.to validate_presence_of :motivo_do_cancelamento }
		end
	end

	describe ":seta_contratado" do
		context "ao salvar um contrato, o ganhador deve ser informado" do
			it "retorna erro se não for informado" do
				contrato = FactoryBot.build(:licitacao_contrato, pessoa_do_projeto_id: nil, contratado: nil, numero: '0004')
				contrato.save
				expect(contrato.errors[:contratado_id]).to include "Informe o ganhador"
			end
			it "salva o contrato" do
				projeto =   FactoryBot.create(:licitacao_projeto, :por_lote)
				pessoa_do_projeto = FactoryBot.create(:licitacao_pessoa_do_projeto, projeto_id: projeto.id)
				contrato = FactoryBot.create(:licitacao_contrato, :com_lotes_do_contrato, pessoa_do_projeto_id: pessoa_do_projeto.id, numero: '0005')
				expect(contrato.persisted?).to be_truthy
			end
		end
	end

	describe ':verifica_unicidade_do_numero_do_contrato' do
		context 'verifica se já existe um contrato com o número' do
			it 'retorna erro' do
				projeto =   FactoryBot.create(:licitacao_projeto, :por_lote)
				pessoa_do_projeto = FactoryBot.create(:licitacao_pessoa_do_projeto, projeto_id: projeto.id)
				contratado = FactoryBot.create(:licitacao_contratado, pessoa_do_projeto: pessoa_do_projeto)
				contrato = FactoryBot.create(:licitacao_contrato, :com_lotes_do_contrato, contratado: contratado, numero: '123453', projeto_id: projeto.id)
				_lote_do_contrato = FactoryBot.create(:lote_do_contrato, contrato_id: contrato.id, lote_id: projeto.lotes.first.id)
				contrato_dois = FactoryBot.build(:licitacao_contrato, :com_lotes_do_contrato, contratado: contratado, numero: '123453', projeto_id: projeto.id)
				contrato_dois.validate
				expect(contrato_dois.errors[:numero]).to include "Número do contrato deve ser único"
			end

			it 'não retorna erro' do
				projeto =   FactoryBot.create(:licitacao_projeto, :por_lote)
				pessoa_do_projeto = FactoryBot.create(:licitacao_pessoa_do_projeto, projeto_id: projeto.id)
				contrato = FactoryBot.create(:licitacao_contrato, :com_lotes_do_contrato, pessoa_do_projeto_id: pessoa_do_projeto.id, numero: '123453')
				_lote_do_contrato = FactoryBot.create(:lote_do_contrato, contrato_id: contrato.id, lote_id: projeto.lotes.first.id)
				contrato_dois = FactoryBot.build(:licitacao_contrato, :com_lotes_do_contrato, pessoa_do_projeto_id: pessoa_do_projeto.id, numero: '1234555')
				contrato_dois.validate
				expect(contrato_dois.errors[:numero]).to_not include "Número do contrato deve ser único"
			end
		end
	end

	describe '#criar_itens_contrato' do
		context 'quando processo é registro de preço' do
			it 'não cria itens do contrato automaticamente' do
				projeto = FactoryBot.create(:licitacao_projeto, registro_de_preco: true)
				item_do_pedido = FactoryBot.create(:item_do_pedido, pedido_id: projeto.pedido.id)
				FactoryBot.create(:item_da_unidade_orcamentaria, quantidade: 10, item_do_pedido_id: item_do_pedido.id)
				FactoryBot.create(:licitacao_item_do_lote, item_do_pedido_id: item_do_pedido.id, lote_id: projeto.lotes.first.id)
				pessoa_do_projeto = FactoryBot.create(:licitacao_pessoa_do_projeto, projeto_id: projeto.id)
				contratado = FactoryBot.create(:licitacao_contratado, pessoa_do_projeto: pessoa_do_projeto)
				contrato = FactoryBot.create(:licitacao_contrato, :com_lotes_do_contrato, contratado: contratado, projeto_id: projeto.id)
				expect(contrato.itens_do_contrato.count).to eq 0
			end
		end
		context 'quando o processo não é registro de preço' do
			it 'cria itens correspondentes à unidade do contrato' do
				projeto = FactoryBot.create(:licitacao_projeto, registro_de_preco: false)
				unidade = FactoryBot.create :loa_fes, :orcamento_2016
				outra_unidade = FactoryBot.create :loa_seduc, :orcamento_2016

				item_do_pedido = projeto.pedido.itens_do_pedido.create(item_id: FactoryBot.create(:caderno).id)

				#Cria quantidades para uma unidade
				unidade_por_pedido = projeto.pedido.unidades_orcamentarias_por_pedido.create(unidade_orcamentaria_id: unidade.id)
				unidade_por_pedido.itens_do_pedido_por_unidade_orcamentaria.create(item_do_pedido_id: item_do_pedido.id, quantidade: 400)

				#Cria quantidades para outra unidade
				outra_unidade_por_pedido = projeto.pedido.unidades_orcamentarias_por_pedido.create(unidade_orcamentaria_id: outra_unidade.id)
				outra_unidade_por_pedido.itens_do_pedido_por_unidade_orcamentaria.create(item_do_pedido_id: item_do_pedido.id, quantidade: 600)

				item_do_lote = projeto.lotes.last.itens_do_lote.create!(item_do_pedido_id: item_do_pedido.id)
				pessoa_do_projeto = FactoryBot.create(:licitacao_pessoa_do_projeto, projeto_id: projeto.id)

				# Cria contrato com a primeira unidade orçamentária
				contrato = FactoryBot.build(:licitacao_contrato, :com_lotes_do_contrato, unidade_orcamentaria_por_pedido_id: unidade_por_pedido.id, pessoa_do_projeto_id: pessoa_do_projeto.id)
				contrato.lotes << projeto.lotes
				contrato.save
				item_do_contrato = contrato.itens_do_contrato.find_by(item_do_lote: item_do_lote)
				expect(item_do_contrato.quantidade).to eq 400 # Cria item do contato com a quantidade esperada
			end
		end
	end

	describe ':numero_de_contratos_de_dispensa_para_contratado' do
		it 'retorna quantidade de contratos com processo de dispensa' do
			projeto = FactoryBot.create(:licitacao_projeto, :dispensa )
			pessoa_do_projeto = FactoryBot.create(:licitacao_pessoa_do_projeto, projeto_id: projeto.id)
			contratado = FactoryBot.create(:licitacao_contratado, pessoa_do_projeto: pessoa_do_projeto)
			contrato = FactoryBot.create(:licitacao_contrato, :com_lotes_do_contrato, contratado: contratado, projeto_id: projeto.id)
			_lote_do_contrato = FactoryBot.create(:lote_do_contrato, contrato_id: contrato.id, lote_id: projeto.lotes.first.id)
			expect(contrato.numero_de_contratos_de_dispensa_para_contratado).to eq 1
		end
	end

	describe ':valor_dentro_do_disponivel_para_unidade_gestora' do
		it "retorna erro" do
			pedido = FactoryBot.create(:pedido, :simplificado, status: 'fechado')
			item_do_pedido = FactoryBot.build(:item_do_pedido, pedido_id: pedido.id, preco_estimativo: 10)
			item_do_pedido.save!
			pedido.reload
			projeto = FactoryBot.create(:licitacao_projeto, :simplificado)
			pessoa_do_projeto = FactoryBot.create(:licitacao_pessoa_do_projeto, projeto_id: projeto.id)
			contratado = FactoryBot.create(:licitacao_contratado, pessoa_do_projeto: pessoa_do_projeto)
			ata_de_registro_de_precos = Licitacao::AtaDeRegistroDePrecos.create(projeto_id: projeto.id, numero: "14.008/2018RP", texto_da_ata: "texto", data_inicio_de_vigencia: Date.parse("20/10/2017"), data_final_de_vigencia: Date.parse("22/11/2017"), )
			contrato = FactoryBot.build(:licitacao_contrato, :com_lotes_do_contrato, inicio_da_vigencia: Date.parse("23/11/2017"), contratado: contratado, projeto_id: projeto.id, ata_de_registro_de_precos: ata_de_registro_de_precos, valor: 100)
			contrato.send(:valor_dentro_do_disponivel_para_unidade_gestora)
			expect(contrato.errors[:valor]).to include "Deve ser menor ou igual ao saldo disponível em #{contrato.unidade_orcamentaria_por_pedido.unidade_orcamentaria.nome}."
		end

		it "não retorna erro" do
			pedido = FactoryBot.create(:pedido, :simplificado, status: 'fechado')
			item_do_pedido = FactoryBot.build(:item_do_pedido, pedido_id: pedido.id, preco_estimativo: 10)
			item_do_pedido.save!
			pedido.reload
			projeto = FactoryBot.create(:licitacao_projeto, :simplificado)
			pessoa_do_projeto = FactoryBot.create(:licitacao_pessoa_do_projeto, projeto_id: projeto.id)
			contratado = FactoryBot.create(:licitacao_contratado, pessoa_do_projeto: pessoa_do_projeto)
			ata_de_registro_de_precos = Licitacao::AtaDeRegistroDePrecos.create(projeto_id: projeto.id, numero: "14.008/2018RP", texto_da_ata: "texto", data_inicio_de_vigencia: Date.parse("20/10/2017"), data_final_de_vigencia: Date.parse("22/11/2017"), )
			contrato = FactoryBot.build(:licitacao_contrato, :com_lotes_do_contrato, inicio_da_vigencia: Date.parse("23/11/2017"), contratado: contratado, projeto_id: projeto.id, ata_de_registro_de_precos: ata_de_registro_de_precos, valor: 0)
			contrato.send(:valor_dentro_do_disponivel_para_unidade_gestora)
			expect(contrato.errors[:valor]).to_not include "Deve ser menor ou igual ao saldo disponível em #{contrato.unidade_orcamentaria_por_pedido.unidade_orcamentaria.nome}."
		end
	end

	describe ':valida_quantidade_de_contratos' do
		context "quando o processo é dispensa, só pode haver um contrato por ganhador" do
			it "retorna erro" do
				projeto = FactoryBot.create(:licitacao_projeto, :dispensa )
				pessoa_do_projeto = FactoryBot.create(:licitacao_pessoa_do_projeto, projeto_id: projeto.id)
				contratado = FactoryBot.create(:licitacao_contratado, pessoa_do_projeto: pessoa_do_projeto)
				contrato_um = FactoryBot.create(:licitacao_contrato, :com_lotes_do_contrato, contratado: contratado, projeto_id: projeto.id)
				contrato_dois = FactoryBot.build(:licitacao_contrato, :com_lotes_do_contrato, contratado: contratado, numero: '23342', projeto_id: projeto.id)
				contrato_dois.send(:valida_quantidade_de_contratos)
				expect(contrato_dois.errors[:base]).to include "Processos de dispensa só podem possuir um contrato para cada ganhador"
			end
		end
		context "quando o processo não é registro de preço, só pode haver um contrato" do
			it "retorna erro" do
				pending("Implementar")
				fail
			end
		end
	end

	describe '#valida_data_pelo_exercicio' do
		it 'retorna erro' do
			contrato = FactoryBot.build :licitacao_contrato, :com_lotes_do_contrato, data_do_contrato: Date.parse("2017-10-18")
			contrato.save
			expect(contrato.errors[:data_do_contrato]).to include "Deve estar contida no exercício do Orçamento logado (2016)"
		end

		it 'não retorna o erro quando uma das datas está nula' do
			contrato = FactoryBot.build :licitacao_contrato, :com_lotes_do_contrato, data_do_contrato: ""
			contrato.save
			expect(contrato.errors[:data_do_contrato]).to_not include "Data de fim de vigência não deve ser maior que a data final do exercício"
		end

		it 'não retorna erro quando as datas são validas' do
			contrato = FactoryBot.build :licitacao_contrato, :com_lotes_do_contrato, data_do_contrato:  Date.parse("2016-10-19")
			contrato.save
			expect(contrato.errors[:data_do_contrato]).to_not include "Data de fim de vigência não deve ser maior que a data final do exercício"
		end
	end

	describe '#valida_data_pela_data_da_ata_de_registro_de_preco' do
		context 'quando a data é diferentedo período de vigência da ata_de_registro_de_preco' do
			it 'retorna erro' do
				projeto = FactoryBot.create(:licitacao_projeto) # data_do_projeto: 19/10/2016, vigencia: 12 meses
				pessoa_do_projeto = FactoryBot.create(:licitacao_pessoa_do_projeto, projeto_id: projeto.id)
				contratado = FactoryBot.create(:licitacao_contratado, pessoa_do_projeto: pessoa_do_projeto)
				ata_de_registro_de_precos = Licitacao::AtaDeRegistroDePrecos.create(projeto_id: projeto.id, numero: "14.008/2018RP", texto_da_ata: "texto", data_inicio_de_vigencia: Date.parse("20/10/2017"), data_final_de_vigencia: Date.parse("22/11/2017"))
				contrato = FactoryBot.build :licitacao_contrato, :com_lotes_do_contrato, inicio_da_vigencia: Date.parse("23/11/2017"), contratado: contratado, projeto_id: projeto.id, ata_de_registro_de_precos: ata_de_registro_de_precos
				contrato.save
				expect(contrato.errors[:inicio_da_vigencia]).to include  "Deve estar dentro do período de vigência da ARP (#{contrato.ata_de_registro_de_precos.data_inicio_de_vigencia} - #{contrato.ata_de_registro_de_precos.data_final_de_vigencia})"
			end
		end
	end

	describe '#valida_data' do
		it 'retorna erro' do
			contrato = FactoryBot.build :licitacao_contrato, :com_lotes_do_contrato, data_do_contrato: Date.parse("2016-10-15"), inicio_da_vigencia:  Date.parse("2016-10-15")
			contrato.save
			expect(contrato.errors[:data_do_contrato]).to include  "Deve ser maior ou igual à data do projeto (19/10/2016)"
		end

		it 'não retorna o erro quando uma das datas está nula' do
			contrato = FactoryBot.build :licitacao_contrato, :com_lotes_do_contrato, data_do_contrato: "", inicio_da_vigencia:  Date.parse("2016-10-15")
			contrato.save
			expect(contrato.errors[:data_do_contrato]).to_not include "Data do contrato e data de inicio de vigência devem ser iguais ou maiores que a data do projeto"
		end

		it 'não retorna erro quando as datas são validas' do
			contrato = FactoryBot.build :licitacao_contrato, :com_lotes_do_contrato, data_do_contrato: Date.parse("2016-10-21"), inicio_da_vigencia:  Date.parse("2016-10-22")
			contrato.save
			expect(contrato.errors[:data_do_contrato]).to_not include "Data do contrato e data de inicio de vigência devem ser iguais ou maiores que a data do projeto"
		end
	end

	describe '#valida_data_fim_da_vigencia' do
		it 'retorna erro' do
			contrato = FactoryBot.build :licitacao_contrato, :com_lotes_do_contrato, inicio_da_vigencia:  Date.parse("2016-10-19"), fim_da_vigencia: Date.parse("2016-10-18")
			contrato.save
			expect(contrato.errors[:fim_da_vigencia]).to include "Deve ser no mínimo um dia após o início da vigência"
		end

		it 'não retorna o erro quando uma das datas está nula' do
			contrato = FactoryBot.build :licitacao_contrato, :com_lotes_do_contrato, inicio_da_vigencia: "", fim_da_vigencia: Date.parse("2016-10-18")
			contrato.save
			expect(contrato.errors[:fim_da_vigencia]).to_not include "Data de fim de vigência deve ser no mínimo um dia depois do inicio da vigência"
		end

		it 'não retorna o erro quando as datas são validas' do
			contrato = FactoryBot.build :licitacao_contrato, :com_lotes_do_contrato, inicio_da_vigencia: Date.parse("2016-10-19"), fim_da_vigencia: Date.parse("2016-10-22")
			contrato.save
			expect(contrato.errors[:fim_da_vigencia]).to_not include "Data de fim de vigência deve ser no mínimo um dia depois do inicio da vigência"
		end
	end

	describe '#data_final_de_acordo_com_aditivos' do
		context 'quando há aditivo de prazo' do
			it 'retorna a última data de expiração dos aditivos' do
				contrato_principal = FactoryBot.create :licitacao_contrato, :com_lotes_do_contrato
				FactoryBot.create :licitacao_aditivo, contrato_id: contrato_principal.id, inicio_da_vigencia: Date.parse("2016-10-22"), fim_da_vigencia: Date.parse("2016-10-30"), status: "confirmado"
				FactoryBot.create :licitacao_aditivo, contrato_id: contrato_principal.id, inicio_da_vigencia: Date.parse("2016-11-01"), fim_da_vigencia: Date.parse("2016-11-30"), status: "confirmado"
				expect(contrato_principal.data_final_de_acordo_com_aditivos.to_s).to eq("30/11/2016")
			end
		end
		context 'quando não há aditivo de prazo' do
			it 'retorna a data de expiração do contrato' do
				contrato_principal = FactoryBot.create :licitacao_contrato, :com_lotes_do_contrato, fim_da_vigencia: "2016-12-12"
				expect(contrato_principal.data_final_de_acordo_com_aditivos.to_s).to eq("12/12/2016")
			end
		end
	end

	describe '#tempo_restante' do
		before(:each) do
			@contrato = Licitacao::Contrato.new(fim_da_vigencia: Date.parse("01/08/2016"))
		end
		context 'retorna 100' do
			it 'quando faltam 100 dias para terminar' do
				travel_to Date.parse('23/04/2016') do
					expect(@contrato.tempo_restante).to eq 100
				end
			end
		end
		context 'retorna 0' do
			it 'quando termina hoje' do
				travel_to Date.parse('01/08/2016') do
					expect(@contrato.tempo_restante).to eq 0
				end
			end
			it 'quando já terminou' do
				travel_to Date.parse('31/08/2016') do
					expect(@contrato.tempo_restante).to eq 0
				end
			end
		end
	end

	describe do
		let(:contrato) { FactoryBot.create :licitacao_contrato, :com_lotes_do_contrato }
		let(:valor_total_do_contrato) {
			contrato.itens_do_contrato.inject(0) { |total, item_do_contrato|
				FactoryBot.create :item_do_projeto_por_pessoa, final: true, preco: 9.99, item_do_lote: item_do_contrato.item_do_lote
				total + (9.99 * item_do_contrato.quantidade)
			}
		}
		describe '#valor_total_do_contrato' do
			context 'retorna valor do contrato baseado nos itens do contrato e itens do aditivo' do
				it "quando só tem itens do contrato" do
					valor_contratado = valor_total_do_contrato
					expect(contrato.valor_total_do_contrato).to eq valor_contratado
				end
				it "quando tem itens do contrato e do aditivo" do
					aditivo = FactoryBot.create :licitacao_aditivo, modalidade: :acrescimo, contrato_id: contrato.id, inicio_da_vigencia: "22/10/2016", fim_da_vigencia: "25/10/2016", status: 'confirmado'
					item_do_aditivo = FactoryBot.create(:licitacao_item_do_aditivo, quantidade: 2, aditivo_id: aditivo.id, item_do_lote_id: contrato.itens_do_contrato.first.item_do_lote.id, valor_adicionado: 10, total: 20)
					expect(contrato.valor_total_do_contrato).to eq 219.8
				end
			end
		end

		describe '#valor_a_empenhar' do
			it 'retorna valor do contrato menos valores de empenhos' do
				valor_total_do_contrato
				contrato = FactoryBot.build :licitacao_contrato, :com_lotes_do_contrato
				contrato.save(validate: false)
				contrato.reload

				orcamento_da_despesa = Loa::OrcamentoDaDespesa.last
				sub_elemento = Contabilidade::SubElementoDeDespesa.last

				empenho1 = contrato.empenhos.new(pessoa_id: contrato.pessoa.id, valor: 60, descriminacao_obrigatoria_de_itens: false, orcamento: contrato.orcamento, modalidade: 0, orcamento_da_despesa_id: orcamento_da_despesa.id, sub_elemento_de_despesa_id: sub_elemento.id, data_do_empenho: '2017-03-22', data_de_solicitacao: '2017-03-22', created_at: '2017-03-22', updated_at: '2017-03-22', projeto_id: contrato.projeto.id, tipo_de_lancamento: 0, unidade_orcamentaria_do_exercicio_id: contrato.unidade_orcamentaria.id)
				empenho1.save!(validate: false)
				empenho2 = contrato.empenhos.new(pessoa_id: contrato.pessoa.id, valor: 40, descriminacao_obrigatoria_de_itens: false, orcamento: contrato.orcamento, modalidade: 0, orcamento_da_despesa_id: orcamento_da_despesa.id, sub_elemento_de_despesa_id: sub_elemento.id, data_do_empenho: '2017-03-22', data_de_solicitacao: '2017-03-22', created_at: '2017-03-22', updated_at: '2017-03-22', projeto_id: contrato.projeto.id, tipo_de_lancamento: 0, unidade_orcamentaria_do_exercicio_id: contrato.unidade_orcamentaria.id)
				empenho2.save(validate: false)
				
				expect(contrato.valor_a_empenhar).to eq valor_total_do_contrato.to_f.round(2) - 100
			end

			it 'quando há restos a pagar cancelados' do
				valor_total_do_contrato
				contrato = FactoryBot.build :licitacao_contrato, :com_lotes_do_contrato
				contrato.save(validate: false)
				contrato.reload

				orcamento_da_despesa = Loa::OrcamentoDaDespesa.last
				sub_elemento = Contabilidade::SubElementoDeDespesa.last

				empenho1 = contrato.empenhos.new(pessoa_id: contrato.pessoa.id, valor: 50, descriminacao_obrigatoria_de_itens: false, orcamento: contrato.orcamento, modalidade: 0, orcamento_da_despesa_id: orcamento_da_despesa.id, sub_elemento_de_despesa_id: sub_elemento.id, data_do_empenho: '2017-03-22', data_de_solicitacao: '2017-03-22', created_at: '2017-03-22', updated_at: '2017-03-22', projeto_id: contrato.projeto.id, tipo_de_lancamento: 0, unidade_orcamentaria_do_exercicio_id: contrato.unidade_orcamentaria.id)
				empenho1.save(validate: false)
				empenho2 = contrato.empenhos.new(pessoa_id: contrato.pessoa.id, valor: 50, descriminacao_obrigatoria_de_itens: false, orcamento: contrato.orcamento, modalidade: 0, orcamento_da_despesa_id: orcamento_da_despesa.id, sub_elemento_de_despesa_id: sub_elemento.id, data_do_empenho: '2017-03-22', data_de_solicitacao: '2017-03-22', created_at: '2017-03-22', updated_at: '2017-03-22', projeto_id: contrato.projeto.id, tipo_de_lancamento: 0, unidade_orcamentaria_do_exercicio_id: contrato.unidade_orcamentaria.id, restos_a_pagar: true, empenho_origem_id: empenho1.id)
				empenho2.save(validate: false)
				
				cancelamento_de_resto_a_pagar = Contabilidade::CancelamentoDeRestoAPagar.new(data: '2017-03-22', orcamento: contrato.orcamento, status: 1, tipo: 0)
				cancelamento_de_resto_a_pagar.save(validate: false)

				restos_a_pagar_cancelados = empenho2.restos_a_pagar_cancelados.new(cancelamento_de_resto_a_pagar_id: cancelamento_de_resto_a_pagar.id, valor_cancelado: 30)
				restos_a_pagar_cancelados.save(validate: false)

				expect(contrato.valor_a_empenhar).to eq valor_total_do_contrato.to_f.round(2) - 20
			end
		end

		describe '#tem_itens?' do
			context 'quando tem itens' do
				it 'retorna true' do
					expect(contrato.tem_itens?).to be_truthy
				end
			end
			context 'quando não tem itens' do
				it 'retorna true' do
					contrato = Licitacao::Contrato.new
					expect(contrato.tem_itens?).to be_falsey
				end
			end
		end
	end

	describe '#tem_aditivos?' do
		context 'quando possui aditivos' do
			it 'retorna true' do
				contrato_principal = FactoryBot.create :licitacao_contrato, :com_lotes_do_contrato
				FactoryBot.create :licitacao_aditivo, contrato_id: contrato_principal.id, inicio_da_vigencia: Date.parse("2016-10-22"), fim_da_vigencia: Date.parse("2016-10-30")
				expect(contrato_principal.tem_aditivos?).to be_truthy
			end
		end
		context 'quando não possui aditivos' do
			it 'retorna false' do
				contrato_principal = FactoryBot.create :licitacao_contrato, :com_lotes_do_contrato
				contrato_principal.aditivos.destroy_all
				expect(contrato_principal.tem_aditivos?).to be_falsey
			end
		end
	end

	describe "#quantidade_total_por_item" do
		context "soma a quantidade dos itens do contrato mais os itens do aditivo do mesmo item" do
			context "quando tem item do contrato e aditivo" do
				it "deve retornar a quantidade total por item" do
					projeto = FactoryBot.create(:licitacao_projeto, registro_de_preco: true)
					pessoa_do_projeto = FactoryBot.create(:licitacao_pessoa_do_projeto, projeto_id: projeto.id)
					contratado = FactoryBot.create(:licitacao_contratado, pessoa_do_projeto: pessoa_do_projeto)
					contrato = FactoryBot.create(:licitacao_contrato, :com_lotes_do_contrato, contratado: contratado, projeto_id: projeto.id)
					item_do_lote = contrato.itens_dos_lotes.first
					contrato.itens_do_contrato.create!(item_do_lote_id: item_do_lote.id, quantidade: 10)
					aditivo = FactoryBot.create :licitacao_aditivo, modalidade: 'acrescimo', contrato_id: contrato.id
					aditivo.itens_do_aditivo.create!(item_do_lote_id: item_do_lote.id, quantidade: 2, aditivo_id: aditivo.id)
					expect(contrato.quantidade_total_por_item(item_do_lote.item)).to eq 12
				end
			end
			context "quando tem apenas item do contrato" do
				it "deve retornar a quantidade total por item" do
					projeto = FactoryBot.create(:licitacao_projeto, registro_de_preco: true)
					pessoa_do_projeto = FactoryBot.create(:licitacao_pessoa_do_projeto, projeto_id: projeto.id)
					contratado = FactoryBot.create(:licitacao_contratado, pessoa_do_projeto: pessoa_do_projeto)
					contrato = FactoryBot.create(:licitacao_contrato, :com_lotes_do_contrato, contratado: contratado, projeto_id: projeto.id)
					item_do_lote = contrato.itens_dos_lotes.first
					contrato.itens_do_contrato.create!(item_do_lote_id: item_do_lote.id, quantidade: 10)
					expect(contrato.quantidade_total_por_item(item_do_lote.item)).to eq 10
				end
			end
		end
	end

	describe '#itens_da_ata_por_lote_vencedor' do
		context	'Quando retorna os itens' do
			it "Quando item do lote do item da ata tem o mesmo fornecedor ganhador do contrato" do
				contrato = FactoryBot.build(:licitacao_contrato, :com_ata_de_registro_de_preco)
				contrato.projeto.lotes.last.update_attribute(:ganhador_id, contrato.contratado.pessoa_do_projeto_id)
				
				item_da_ata = Licitacao::ItemDaAta.new(ata_de_registro_de_preco_id: contrato.ata_de_registro_de_preco_id, item_do_lote_id: contrato.projeto.lotes.last.itens_do_lote.last.id)
				item_da_ata.save(validate: false)
				
				contrato.ata_de_registro_de_precos.reload
				expect(contrato.itens_da_ata_por_lote_do_fornecedor_vencedor).to include item_da_ata
			end
		end
		context 'Quando não retorna os itens' do
			it "Quando item do lote do item da ata não tem o mesmo fornecador ganhador do contrato" do
				contrato = FactoryBot.build(:licitacao_contrato, :com_ata_de_registro_de_preco)
				
				item_da_ata = Licitacao::ItemDaAta.new(ata_de_registro_de_preco_id: contrato.ata_de_registro_de_preco_id, item_do_lote_id: contrato.projeto.lotes.last.itens_do_lote.last.id)
				item_da_ata.save(validate: false)
				
				contrato.ata_de_registro_de_precos.reload
				expect(contrato.itens_da_ata_por_lote_do_fornecedor_vencedor).to_not include item_da_ata
			end
		end
	end


	describe "#empenhado_total?" do
		it "description" do
			pending("Implementar")
			fail
		end
	end

	describe "#empenhado_parcial?" do
		it "description" do
			pending("Implementar")
			fail
		end
	end

	describe "#a_empenhar?" do
		it "description" do
			pending("Implementar")
			fail
		end
	end

	describe "#seta_pessoa_do_projeto" do
		it "description" do
			pending("Implementar")
			fail
		end
	end

	describe "#liquidado?" do
		it "description" do
			pending("Implementar")
			fail
		end
	end

end
