require 'rails_helper'

include ActiveSupport::Testing::TimeHelpers

RSpec.describe GestaoDeEstoque::RecebimentoDeMaterial, type: :model do
  it { is_expected.to belong_to(:fornecedor).class_name("Base::Pessoa") }
  it { is_expected.to belong_to(:doador).class_name("Base::Pessoa") }
  it { is_expected.to belong_to(:ordem_de_compra).class_name("Licitacao::OrdemDeCompra") }
  it { is_expected.to belong_to(:almoxarifado).class_name("GestaoDeEstoque::Almoxarifado") }
  it { is_expected.to belong_to(:unidade_orcamentaria).class_name("Loa::UnidadeOrcamentaria") }
  it { is_expected.to belong_to(:orcamento).class_name("Orcamento") }

  it{ is_expected.to have_many(:itens_do_recebimento_de_materiais).class_name('GestaoDeEstoque::ItemDoRecebimentoDeMaterial') }
  it{ is_expected.to have_many(:movimentacoes_do_estoque).class_name("GestaoDeEstoque::MovimentacaoDoEstoque") }

  it { is_expected.to accept_nested_attributes_for(:itens_do_recebimento_de_materiais).allow_destroy(true) }

  [:almoxarifado_id, :orcamento_id, :codigo, :data_do_recebimento, :tipo_de_material, :unidade_orcamentaria_id, :status].each do |atributo|
		it { is_expected.to validate_presence_of(atributo) }
	end

  describe "Validações de Tamanho" do
    it { is_expected.to validate_length_of(:codigo).is_at_most(8) }
    it { is_expected.to validate_length_of(:numero_da_nota).is_at_most(15) }
    it { is_expected.to validate_length_of(:serie).is_at_most(5) }
    it { is_expected.to validate_length_of(:observacao).is_at_most(600) }
  end

  describe "Validações Quando Não Possui Classificação" do
    before{ allow(subject).to receive(:possui_classificacao?).and_return(false) }
    it { is_expected.to validate_presence_of(:tipo_de_entrada) }
  end

  describe "Validações Quando Classificação" do
      before{ allow(subject).to receive(:possui_classificacao?).and_return(true) }
      it { is_expected.to_not validate_presence_of(:ordem_de_compra_id) }
  end

  describe "Validações Quando Possui Classificação e o material não é permanente" do
    subject { FactoryBot.build(:gestao_de_estoque_recebimento_de_material, classificacao: :requisicao) }
    it { is_expected.to validate_presence_of(:classificacao_tipo_de_material) }
  end

  describe "Validações Quando Possui Classificação e o material é permanente" do
    subject { FactoryBot.build(:gestao_de_estoque_recebimento_de_material, classificacao: :requisicao, tipo_de_material: :permanente) }

    it { is_expected.to validate_presence_of(:sub_elemento_de_despesa_id) }
  end

  describe "Validações Classificação é Doação" do
    subject { FactoryBot.build(:gestao_de_estoque_recebimento_de_material, classificacao: :doacao) }
    it { is_expected.to validate_presence_of(:doador_id) }
  end

  context "Valida data de emissão" do
    it "Data de emissão superior a do recebimento" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      data_do_recebimento: "01/01/2021", data_de_emissao: "02/01/2021")
      recebimento.validate
      expect(recebimento.errors[:data_de_emissao]).to include "Data de emissão superior a data do recebimento"
    end
    it "Data de emissão inferior ou igual a do recebimento" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      data_do_recebimento: "02/01/2021", data_de_emissao: "02/01/2021")
      recebimento.validate
      expect(recebimento.errors[:data_de_emissao]).to be_blank
    end
    it "Quando não tem ordem de compra e possui data do empenho" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      data_do_empenho: "02/01/2021", data_de_emissao: "01/01/2021")
      recebimento.ordem_de_compra_id = nil
      recebimento.save
      expect(recebimento.errors[:data_de_emissao]).to include "Data de emissão inferior a data do empenho"
    end
    it "Quando tem ordem de compra" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      data_de_emissao: "01/10/2016")
      recebimento.validate
      expect(recebimento.errors[:data_de_emissao]).to include "Data de emissão inferior a data do empenho"
    end
  end

  context "Recebimento Parcial" do
    before(:each) do
      @recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material, tipo_de_recebimento: :recebimento_parcial)
      @recebimento.save(validate: false)
      @item_da_ordem_de_compra = FactoryBot.build(:licitacao_item_da_ordem_de_compra,
      ordem_de_compra_id: @recebimento.ordem_de_compra_id)
      @item_da_ordem_de_compra.save(validate: false)
    end
    it "Quando recebimento parcial recebe todos os itens" do
      item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material,
        recebimento_de_material_id: @recebimento.id, quantidade: 9,
        item_id: @item_da_ordem_de_compra.item_id)
      item_do_recebimento.save(validate: false)
      @recebimento.reload
      @recebimento.validate
      expect(@recebimento.errors[:tipo_de_recebimento]).to include "Não pode receber todos os itens disponíveis em um recebimento parcial."
    end
    it "Quando recebimento parcial não recebe todos os itens" do
      item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material,
        recebimento_de_material_id: @recebimento.id, quantidade: 8,
        item_id: @item_da_ordem_de_compra.item_id)
      item_do_recebimento.save(validate: false)
      @recebimento.reload
      @recebimento.validate
      expect(@recebimento.errors[:tipo_de_recebimento]).to_not include "Não pode receber todos os itens disponíveis em um recebimento parcial."
    end
  end

  describe "AASM" do
    context "Quando é Remoto" do
      before(:each) do
        @unidade_orcamentaria = FactoryBot.build(:loa_hgf)
        @unidade_orcamentaria.save(validate: false)
        @almoxarifado = FactoryBot.build(:gestao_de_estoque_almoxarifado)
        @almoxarifado.unidades_orcamentarias_do_almoxarifado.build(unidade_orcamentaria_id: @unidade_orcamentaria.id)
        @almoxarifado.save(validate: false)
        @almoxarifado_de_destino =  FactoryBot.build(:gestao_de_estoque_almoxarifado, nome: "Segundo Almoxarifado")
        @almoxarifado_de_destino.unidades_orcamentarias_do_almoxarifado.build(unidade_orcamentaria_id: @unidade_orcamentaria.id)
        @almoxarifado_de_destino.save(validate: false)
        @classificacao_remota = 4
      end
      it "Quando é Remoto Comum" do
        entrada_remota_comum = 2
        recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
            tipo_de_entrada: entrada_remota_comum,
            almoxarifado_id: @almoxarifado.id,
            classificacao: @classificacao_remota,
            classificacao_tipo_de_material: 1,
            almoxarifado_de_destino_id: @almoxarifado_de_destino.id,
            unidade_orcamentaria_de_destino_id: @unidade_orcamentaria.id)

          recebimento.save(validate: false)

          item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material, recebimento_de_material_id: recebimento.id, quantidade: 10)
          item_do_recebimento.save(validate: false)
          FactoryBot.create(:gestao_de_estoque_informacao_extra, item_do_recebimento_de_material_id: item_do_recebimento.id, quantidade: 10 )

          item_do_recebimento.reload
          recebimento.reload
        expect(recebimento).to transition_from(:aberto).to(:recebido).on_event(:remoto_comum)
      end
      it "Quando é Remoto Consumo" do
        entrada_remota_comum = 3
        recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
            tipo_de_entrada: entrada_remota_comum,
            almoxarifado_id: @almoxarifado.id,
            classificacao: @classificacao_remota,
            classificacao_tipo_de_material: 1,
            almoxarifado_de_destino_id: @almoxarifado_de_destino.id,
            unidade_orcamentaria_de_destino_id: @unidade_orcamentaria.id)

        recebimento.save(validate: false)

        item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material, recebimento_de_material_id: recebimento.id, quantidade: 10)
        item_do_recebimento.save(validate: false)
        FactoryBot.create(:gestao_de_estoque_informacao_extra, item_do_recebimento_de_material_id: item_do_recebimento.id, quantidade: 10 )

        item_do_recebimento.reload
        recebimento.reload
        expect(recebimento).to transition_from(:aberto).to(:recebido).on_event(:remoto_consumo)
      end
    end
    context "Quando é recebimento parcial" do
      it "Quando é válido" do
        recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material, tipo_de_recebimento: :recebimento_parcial)
        recebimento.save(validate: false)

        item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material, recebimento_de_material_id: recebimento.id, quantidade: 10)
        item_do_recebimento.save(validate: false)
        FactoryBot.create(:gestao_de_estoque_informacao_extra, item_do_recebimento_de_material_id: item_do_recebimento.id, quantidade: 10 )

        item_do_recebimento.reload
        recebimento.reload
        expect(recebimento).to transition_from(:aberto).to(:recebido_parcialmente).on_event(:receber_parcialmente)
      end
    end
    context "Quando é recebimento" do
      it "Quando é válido" do
        recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material)
        recebimento.save(validate: false)

        item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material, recebimento_de_material_id: recebimento.id, quantidade: 10)
        item_do_recebimento.save(validate: false)
        FactoryBot.create(:gestao_de_estoque_informacao_extra, item_do_recebimento_de_material_id: item_do_recebimento.id, quantidade: 10 )

        item_do_recebimento.reload
        recebimento.reload
        expect(recebimento).to transition_from(:aberto).to(:recebido).on_event(:receber)
      end
    end
  end

  context "Cria Requisição Remota" do
    before(:each) do
      @unidade_orcamentaria = FactoryBot.build(:loa_hgf)
      @unidade_orcamentaria.save(validate: false)
      @almoxarifado = FactoryBot.build(:gestao_de_estoque_almoxarifado)
      @almoxarifado.unidades_orcamentarias_do_almoxarifado.build(unidade_orcamentaria_id: @unidade_orcamentaria.id)
      @almoxarifado.save(validate: false)
      @almoxarifado_de_destino =  FactoryBot.build(:gestao_de_estoque_almoxarifado, nome: "Segundo Almoxarifado")
      @almoxarifado_de_destino.unidades_orcamentarias_do_almoxarifado.build(unidade_orcamentaria_id: @unidade_orcamentaria.id)
      @almoxarifado_de_destino.save(validate: false)
      @classificacao_remota = 4
    end
    it "Quando Não é Destino" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
          almoxarifado_id: @almoxarifado.id,
          classificacao: @classificacao_remota,
          classificacao_tipo_de_material: 1)
      recebimento.save(validate: false)
      recebimento.cria_requisicao_do_remoto(false)
      requisicao = Administrativo::RequisicaoDeMaterial.last
      expect(@almoxarifado.id).to eq requisicao.almoxarifado_id
    end
    it "Quando É Destino" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
          almoxarifado_id: @almoxarifado.id,
          classificacao: @classificacao_remota,
          classificacao_tipo_de_material: 1,
          almoxarifado_de_destino_id: @almoxarifado_de_destino.id,
          unidade_orcamentaria_de_destino_id: @unidade_orcamentaria.id)
      recebimento.save(validate: false)
      recebimento.cria_requisicao_do_remoto(true)
      requisicao = Administrativo::RequisicaoDeMaterial.last
      expect(@almoxarifado_de_destino.id).to eq requisicao.almoxarifado_destino_id
    end
  end

  context "Altera status da ordem de compra" do
    it "Quando status recebido" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      status: :recebido, tipo_de_recebimento: :recebimento_total)
      recebimento.save(validate: false)
      expect(recebimento.ordem_de_compra.status).to eq "recebido_pelo_almoxarifado"
    end
    it "Quando status recebido parcialmente" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      status: :recebido_parcialmente, tipo_de_recebimento: :recebimento_parcial)
      recebimento.save(validate: false)
      expect(recebimento.ordem_de_compra.status).to eq "recebido_parcialmente_pelo_almoxarifado"
    end
    it "Quando status não é recebido" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      status: :aberto)
      recebimento.save(validate: false)
      expect(recebimento.ordem_de_compra.status_changed?).to be_falsey
    end
    it "Quando deleta um recebimento" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      status: :aberto)
      recebimento.save(validate: false)
      ordem_de_compra = recebimento.ordem_de_compra
      recebimento.destroy
      ordem_de_compra.reload
      expect(ordem_de_compra.status).to eq "enviado_para_almoxarifado"
    end
  end

  context "Recebimento foi concluido?" do
    it "Quando é recebido parcialmente" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      status: :recebido_parcialmente)
      expect(recebimento.recebimento_foi_concluido?).to be_truthy
    end
    it "Quando é recebido" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      status: :recebido)
      expect(recebimento.recebimento_foi_concluido?).to be_truthy
    end
    it "Quando é aberto" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      status: :aberto)
      expect(recebimento.recebimento_foi_concluido?).to be_falsey
    end
    it "Quando é confirmado" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      status: :confirmado)
      expect(recebimento.recebimento_foi_concluido?).to be_falsey
    end
  end

  context "Retorna unidade orçamentaria" do
    it "Quando possui unidade orçacamentaria" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material)
      expect(recebimento.retorna_unidade_orcamentaria).to eq recebimento.unidade_orcamentaria
    end
    it "Quando não possui unidade orçamentaria e possui ordem de compra" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
        unidade_orcamentaria_id: nil)
      expect(recebimento.retorna_unidade_orcamentaria).to eq recebimento.ordem_de_compra.unidade_orcamentaria
    end
    it "Quando não possui unidade orçamentaria e não possui ordem de compra" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
        unidade_orcamentaria_id: nil, ordem_de_compra_id: nil)
        expect(recebimento.retorna_unidade_orcamentaria).to be_falsey
    end
  end

  context "Retorna almoxarifado" do
    it "Quando possui almoxarifado" do
      almoxarifado = FactoryBot.build(:gestao_de_estoque_almoxarifado)
      almoxarifado.save(validate: false)
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      almoxarifado_id: almoxarifado.id)
      expect(recebimento.retorna_almoxarifado).to eq almoxarifado
    end
    it "Quando não possui almoxarifado mas possui ordem de compra" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material, almoxarifado_id: nil)
      almoxarifado = FactoryBot.build(:gestao_de_estoque_almoxarifado)
      almoxarifado.save(validate: false)
      recebimento.ordem_de_compra.update_attribute(:almoxarifado_id, almoxarifado.id)
      expect(recebimento.retorna_almoxarifado).to eq almoxarifado
    end
    it "Quando não possui almoxarifado e não possui ordem e compra" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,almoxarifado_id: nil,
      ordem_de_compra_id: nil, unidade_orcamentaria_id: nil)
      expect(recebimento.retorna_almoxarifado).to be_falsey
    end
  end

  context "Atribui tipo de material" do
    it "Quando elemento de despesa é consumo" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material)
      recebimento.ordem_de_compra.empenho.elemento_de_despesa.update_attribute(:codigo, "33903000")
      recebimento.atribui_tipo_de_material
      expect(recebimento.tipo_de_material).to eq "consumo"
    end
    it "Quando elemento de despesa é consumo distribuição gratuita" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material)
      recebimento.ordem_de_compra.empenho.elemento_de_despesa.update_attribute(:codigo, "33903200")
      recebimento.atribui_tipo_de_material
      expect(recebimento.tipo_de_material).to eq "consumo_distribuicao_gratuita"
    end
    it "Quando elemento de despesa é permanente" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material)
      recebimento.ordem_de_compra.empenho.elemento_de_despesa.update_attribute(:codigo, "33905200")
      recebimento.atribui_tipo_de_material
      expect(recebimento.tipo_de_material).to eq "permanente"
    end
  end

  context "Atribui almoxarifado e unidade orçamentaria" do
    before(:each) do
      @recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material)
    end
    it "Quando tem ordem de compra(atribuindo almoxarifado)" do
      almoxarifado = FactoryBot.build(:gestao_de_estoque_almoxarifado)
      almoxarifado.save(validate: false)
      @recebimento.ordem_de_compra.update_attribute(:almoxarifado_id, almoxarifado.id)
      @recebimento.atribui_almoxarifado_e_unidade
      expect(@recebimento.almoxarifado).to eq @recebimento.ordem_de_compra.almoxarifado
    end
    it "Quando tem ordem de compra(atribuindo unidade)" do
      @recebimento.atribui_almoxarifado_e_unidade
      expect(@recebimento.unidade_orcamentaria).to eq @recebimento.ordem_de_compra.unidade_orcamentaria
    end
    it "Quando tem ordem mas não tem almoxarifado" do
      @recebimento.atribui_almoxarifado_e_unidade
      expect(@recebimento.almoxarifado).to eq nil
    end
    it "Quando tem ordem mas não tem unidade" do
      @recebimento.atribui_almoxarifado_e_unidade
      @recebimento.ordem_de_compra.update_attribute(:empenho_id, nil)
      @recebimento.atribui_almoxarifado_e_unidade
      expect(@recebimento.unidade_orcamentaria).to eq nil
    end
  end

  context "Valor total do recebimento" do
    before(:each) do
      @recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material)
    end
    it "Quando tem item" do
      @recebimento.save(validate: false)
      item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material,
        recebimento_de_material_id: @recebimento.id, quantidade: 9, total: 15)
      item_do_recebimento.save(validate: false)
      expect(@recebimento.valor_total_do_recebimento).to eq 15
    end
    it "Quando não tem itens" do
      expect(@recebimento.valor_total_do_recebimento).to eq 0.0
    end
  end

  context "Existe requisição para o recebimento" do
    before(:each) do
      @recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material)
    end
    it "Quando existe" do
      @recebimento.save(validate: false)
      FactoryBot.build(:administrativo_requisicao_de_material,
        recebimento_de_material_id: @recebimento.id).save(validate: false)
      expect(@recebimento.existe_requisicao_ou_saida_para_esse_recebimento?).to be_truthy
    end
    it "Quando não existe" do
      expect(@recebimento.existe_requisicao_ou_saida_para_esse_recebimento?).to be_falsey
    end
  end

  context "Número da ordem de compra e fornecedor" do
    it "Quando tem ordem de compra" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material)
      expect(recebimento.numero_da_ordem_de_compra_e_fornecedor).to eq "30110001 - Antonio de Sousa"
    end
    it "Quando não tem ordem de compra e tem fornecedor" do
      pessoa = FactoryBot.create(:pessoa_fisica, nome: "João")
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      ordem_de_compra_id: nil, unidade_orcamentaria: nil, numero_da_ordem_de_compra: "291122",
      fornecedor_id: pessoa.id)
      expect(recebimento.numero_da_ordem_de_compra_e_fornecedor).to eq "291122 - João"
    end
  end

  context "Retorna categoria de consumo" do
    before(:each) do
      @recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material)
    end
    it "Retorna material de consumo" do
      categoria = FactoryBot.create(:categoria, codigo: '30', titulo: 'Material de Consumo')
      expect(@recebimento.retorna_categoria_de_consumo).to eq categoria
    end
    it "Não retorna material de consumo quando não existe" do
      expect(@recebimento.retorna_categoria_de_consumo).to be_falsey
    end
  end

  context "Retorna se o item pertence a uma categoria" do
    before(:each) do
      @recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material)
      @recebimento.save(validate: false)
    end
    it "Quando é Alimenticio" do
      item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material,
      recebimento_de_material_id: @recebimento.id)
      item_do_recebimento.save(validate: false)
      categoria = FactoryBot.create(:categoria, codigo: '30', titulo: 'Material de Consumo')
      item_do_recebimento.item.categoria.update_attribute(:codigo, '07')
      item_do_recebimento.item.categoria.update_attribute(:categoria_superior_id, categoria.id)
      expect(@recebimento.eh_alimenticio?).to be_truthy
    end
    it "Quando não é Alimenticio" do
      expect(@recebimento.eh_alimenticio?).to be_falsey
    end
    it "Quando é Farmacéutico (CODIGO: 09)" do
      item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material,
      recebimento_de_material_id: @recebimento.id)
      item_do_recebimento.save(validate: false)
      categoria = FactoryBot.create(:categoria, codigo: '30', titulo: 'Material de Consumo')
      item_do_recebimento.item.categoria.update_attribute(:codigo, '09')
      item_do_recebimento.item.categoria.update_attribute(:categoria_superior_id, categoria.id)
      expect(@recebimento.eh_farmaceutico?).to be_truthy
    end
    it "Quando é Farmacéutico (CODIGO: 10)" do
      item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material,
      recebimento_de_material_id: @recebimento.id)
      item_do_recebimento.save(validate: false)
      categoria = FactoryBot.create(:categoria, codigo: '30', titulo: 'Material de Consumo')
      item_do_recebimento.item.categoria.update_attribute(:codigo, '10')
      item_do_recebimento.item.categoria.update_attribute(:categoria_superior_id, categoria.id)
      expect(@recebimento.eh_farmaceutico?).to be_truthy
    end
    it "Quando não é Farmacéutico" do
      expect(@recebimento.eh_farmaceutico?).to be_falsey
    end
    it "Quando é Limpeza (CODIGO: 21)" do
      item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material,
      recebimento_de_material_id: @recebimento.id)
      item_do_recebimento.save(validate: false)
      categoria = FactoryBot.create(:categoria, codigo: '30', titulo: 'Material de Consumo')
      item_do_recebimento.item.categoria.update_attribute(:codigo, '21')
      item_do_recebimento.item.categoria.update_attribute(:categoria_superior_id, categoria.id)
      expect(@recebimento.eh_limpeza?).to be_truthy
    end
    it "Quando é Limpeza (CODIGO: 35)" do
      item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material,
      recebimento_de_material_id: @recebimento.id)
      item_do_recebimento.save(validate: false)
      categoria = FactoryBot.create(:categoria, codigo: '30', titulo: 'Material de Consumo')
      item_do_recebimento.item.categoria.update_attribute(:codigo, '35')
      item_do_recebimento.item.categoria.update_attribute(:categoria_superior_id, categoria.id)
      expect(@recebimento.eh_limpeza?).to be_truthy
    end
    it  "Quando é Limpeza (CODIGO: 36)" do
      item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material,
      recebimento_de_material_id: @recebimento.id)
      item_do_recebimento.save(validate: false)
      categoria = FactoryBot.create(:categoria, codigo: '30', titulo: 'Material de Consumo')
      item_do_recebimento.item.categoria.update_attribute(:codigo, '36')
      item_do_recebimento.item.categoria.update_attribute(:categoria_superior_id, categoria.id)
      expect(@recebimento.eh_limpeza?).to be_truthy
    end
  end

  context "Cria requisição remota" do
    it "Quando tem valores válidos para criar uma requsição" do
      unidade_orcamentaria = FactoryBot.build(:loa_hgf)
      unidade_orcamentaria.save(validate: false)
      almoxarifado = FactoryBot.build(:gestao_de_estoque_almoxarifado)
      almoxarifado.save(validate: false)
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      almoxarifado_id: almoxarifado.id, unidade_orcamentaria_id: unidade_orcamentaria.id,
      classificacao_tipo_de_material: :material_de_consumo)
      expect(recebimento.cria_requisicao_do_remoto(false)).to be_truthy
    end
    it "Quando não tem valores suficientes para criar uma requisição" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material)
      expect(recebimento.cria_requisicao_do_remoto(false)).to be_falsey
    end
  end

  context "Descriçaõ dos itens" do
    before(:each) do
      @recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material)
      @recebimento.save(validate: false)
    end
    it "Quando tem item" do
      item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material,
      recebimento_de_material_id: @recebimento.id)
      segundo_item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material,
      recebimento_de_material_id: @recebimento.id)
      item_do_recebimento.save(validate: false)
      segundo_item_do_recebimento.save(validate: false)
      expect(@recebimento.descricao_itens).to eq "#{item_do_recebimento.item.descricao}, #{segundo_item_do_recebimento.item.descricao}"
    end
    it "Quando não tem item" do
      expect(@recebimento.descricao_itens).to be_blank
    end
  end

  context "Cria recebimento de desitno" do
    it "Quando tem dados válidos para criar um recebimento" do
      unidade_orcamentaria = FactoryBot.build(:loa_hgf)
      unidade_orcamentaria.save(validate: false)
      almoxarifado = FactoryBot.build(:gestao_de_estoque_almoxarifado)
      almoxarifado.save(validate: false)
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material,
      almoxarifado_de_destino_id: almoxarifado.id, unidade_orcamentaria_de_destino_id: unidade_orcamentaria.id,
      classificacao_tipo_de_material: :material_de_consumo, tipo_de_material: :consumo)
      expect(recebimento.cria_recebimento_de_destino).to be_truthy
    end
    it "Quando não tem dados válidos para criar um recebimento" do
      recebimento = FactoryBot.build(:gestao_de_estoque_recebimento_de_material)
      expect(recebimento.cria_recebimento_de_destino).to be_falsey
    end
  end

  describe "#remove_movimentacao_do_estoque" do
    context "Quando tem movimentacoes" do
      it "remove as movimentações" do
        recebimento = FactoryBot.create(:gestao_de_estoque_recebimento_de_material)
        FactoryBot.create(:gestao_de_estoque_movimentacao_do_estoque, :entrada, origem_id: recebimento.id)
        FactoryBot.create(:gestao_de_estoque_movimentacao_do_estoque, :entrada, origem_id: recebimento.id)

        total_movimentacao = GestaoDeEstoque::MovimentacaoDoEstoque.all.size
        recebimento.remove_movimentacao_do_estoque

        expect(GestaoDeEstoque::MovimentacaoDoEstoque.all.size).to eq total_movimentacao - 2
      end
    end
    context " Quando não tem Movimentação" do
      it "nao remove movimentacao" do
        recebimento = FactoryBot.create(:gestao_de_estoque_recebimento_de_material)

        total_movimentacao = GestaoDeEstoque::MovimentacaoDoEstoque.all.size
        recebimento.remove_movimentacao_do_estoque

        expect(GestaoDeEstoque::MovimentacaoDoEstoque.all.size).to eq total_movimentacao
      end
    end
  end

  describe "#valida_se_existe_quantidade_recebida" do
    it "é valido quando a soma das quantidades dos itens é superior a 0" do
      recebimento = FactoryBot.create(:gestao_de_estoque_recebimento_de_material, tipo_de_recebimento: :recebimento_parcial)
      item_do_recebimento = FactoryBot.create(:gestao_de_estoque_itens_do_recebimento_de_material, recebimento_de_material_id: recebimento.id)
      item_do_recebimento.update_attribute(:quantidade, 15)
      recebimento.reload

      recebimento.validate
      expect(recebimento.errors[:base]).to_not include("É necessário receber pelo menos 1 item")
    end
    it "é invalido quando a soma das quantidade dos itens é inferior a 0" do
      recebimento = FactoryBot.create(:gestao_de_estoque_recebimento_de_material, tipo_de_recebimento: :recebimento_parcial)
      item_do_recebimento = FactoryBot.create(:gestao_de_estoque_itens_do_recebimento_de_material, recebimento_de_material_id: recebimento.id)
      item_do_recebimento.update_attribute(:quantidade, 0)
      recebimento.reload

      recebimento.validate
      expect(recebimento.errors[:base]).to include("É necessário receber pelo menos 1 item")
    end
  end

  describe "#todos_os_itens_tem_informacoes_extras?" do
    before(:each) do
      @recebimento = FactoryBot.create(:gestao_de_estoque_recebimento_de_material)
    end
    context "Quando os valores batem" do
      it "retorna true" do
        item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material, recebimento_de_material_id: @recebimento.id, quantidade: 10)
        item_do_recebimento.save(validate: false)
        FactoryBot.create(:gestao_de_estoque_informacao_extra, item_do_recebimento_de_material_id: item_do_recebimento.id, quantidade: 10 )

        item_do_recebimento.reload
        @recebimento.reload
        expect(@recebimento.todos_os_itens_tem_informacoes_extras?).to be_truthy
      end
    end
    context "Quando os valores não batem" do
      it "retorna false " do
        item_do_recebimento = FactoryBot.build(:gestao_de_estoque_itens_do_recebimento_de_material, recebimento_de_material_id: @recebimento.id, quantidade: 10)
        item_do_recebimento.save(validate: false)
        FactoryBot.create(:gestao_de_estoque_informacao_extra, item_do_recebimento_de_material_id: item_do_recebimento.id, quantidade: 50 )

        item_do_recebimento.reload
        @recebimento.reload
        expect(@recebimento.todos_os_itens_tem_informacoes_extras?).to be_falsey
      end
    end
  end

  describe "#valida_se_existe_quantidade_recebida" do
    it "é valido quando a soma das quantidades dos itens é superior a 0" do
      recebimento = FactoryBot.create(:gestao_de_estoque_recebimento_de_material, tipo_de_recebimento: :recebimento_parcial)
      item_do_recebimento = FactoryBot.create(:gestao_de_estoque_itens_do_recebimento_de_material, recebimento_de_material_id: recebimento.id)
      item_do_recebimento.update_attribute(:quantidade, 15)
      recebimento.reload

      recebimento.validate
      expect(recebimento.errors[:base]).to_not include("É necessário receber pelo menos 1 item")
    end
    it "é invalido quando a soma das quantidade dos itens é inferior a 0" do
      recebimento = FactoryBot.create(:gestao_de_estoque_recebimento_de_material, tipo_de_recebimento: :recebimento_parcial)
      item_do_recebimento = FactoryBot.create(:gestao_de_estoque_itens_do_recebimento_de_material, recebimento_de_material_id: recebimento.id)
      item_do_recebimento.update_attribute(:quantidade, 0)
      recebimento.reload

      recebimento.validate
      expect(recebimento.errors[:base]).to include("É necessário receber pelo menos 1 item")
    end
  end
end
