class Licitacao::ItemDaOrdemDeCompra < ApplicationRecord
	has_paper_trail

	belongs_to :item, class_name: 'Base::Item', required: true
	belongs_to :ordem_de_compra, class_name: 'Licitacao::OrdemDeCompra', required: true

	delegate :empenho, to: :ordem_de_compra
	delegate :descricao_codigo_na_prefeitura_e_unidade, to: :item

	validate :valida_saldo_de_itens, if: Proc.new{ (self.ordem_de_compra.try(:empenho).try(:itens_do_empenho).present? && ordem_de_compra.descrimina_itens_do_empenho.present?) || self.ordem_de_compra.try(:ordem_de_compra_primaria).present?}
	validate :limite_do_total_digitado_pelo_calculo, if: Proc.new{ !self.quantidade.blank? && !self.valor_unitario.blank? && !self.total.blank?}
	validates_uniqueness_of :item_id, scope: [:ordem_de_compra_id], message: "já existe o item inserido"
	validates_presence_of :marca, if: Proc.new { self.ordem_de_compra.eh_ordem_de_fornecimento? }, message: "Marca dos Itens é Obrigatório para Ordem de Fornecimento."

	after_save :apaga_a_si_mesmo_se_quantidade_igual_a_zero

	def saldo_disponivel_na_origem_da_compra
		if empenho.itens_do_empenho.present?
			itens_nas_ordens_de_compra = empenho.ordens_de_compra.valido.joins(:itens_da_ordem_de_compra).where('licitacao_itens_da_ordem_de_compra.item_id = ?', item.try(:id)).sum(:quantidade).to_f
			itens_anulados_no_empenho = empenho.itens_do_empenho.find_by(item_id: self.item_id).quantidade_anulada.to_f rescue 0.0
			saldo_disponivel = ((empenho.itens_do_empenho.find_by(item_id: self.item_id).try(:quantidade).to_f rescue 0.0) - itens_anulados_no_empenho - itens_nas_ordens_de_compra)
			if saldo_disponivel >= 0
				return saldo_disponivel
			else
				return 0
			end
		end
	end

	def marca_do_item item_id, pessoa_id
		if empenho.projeto.present?
			if !empenho.contrato.nil? && empenho.contrato.aditivos.confirmados.where(altera_marca: true).any? && item_possui_aditivo_de_alteracao_de_marca(item_id)
				aditivo = aditivo_de_alteracao_de_marca_do_item(item_id)
				item_do_contrato = empenho.contrato.itens_do_contrato.joins(item_do_lote: {item_do_pedido: :item}).find_by(base_itens: {id: item_id})
				@item_do_aditivo_de_alteracao_de_marca = aditivo.itens_do_aditivo_de_alteracao_de_marca.where(item_do_lote_id: item_do_contrato.item_do_lote_id)
				marca = @item_do_aditivo_de_alteracao_de_marca.first.marca_atualizada if @item_do_aditivo_de_alteracao_de_marca.any?
			else
				@ganhador = empenho.projeto.pessoas_do_projeto.joins(:pessoa).find_by(base_pessoas: {id: pessoa_id})
				@itens_do_projeto_por_pessoa = @ganhador.itens_do_projeto_por_pessoa.joins(item_do_lote: {item_do_pedido: :item}).where(base_itens: {id: item_id})
				marca = @itens_do_projeto_por_pessoa.first.marca if @itens_do_projeto_por_pessoa.any?
			end
			return marca
			nil
		else
			nil
		end
	end

	def marca_editavel? item_id, pessoa_id
		marca_do_item(item_id, pessoa_id).blank? || marca_do_item(item_id, pessoa_id).split(" ").first.chars.uniq.size == 1
	end

	def item_possui_aditivo_de_alteracao_de_marca item_id
		if aditivo_de_alteracao_de_marca_do_item(item_id).nil?
			return false
		else
			return true
		end
	end

	def aditivo_de_alteracao_de_marca_do_item item_id
		item_do_contrato = empenho.contrato.itens_do_contrato.joins(item_do_lote: {item_do_pedido: :item}).find_by(base_itens: {id: item_id})
		empenho.contrato.aditivos.confirmados.where(altera_marca: true).order(id: :desc).each do |aditivo|
			@item_do_aditivo_de_alteracao_de_marca = aditivo.itens_do_aditivo_de_alteracao_de_marca.where(item_do_lote_id: item_do_contrato.item_do_lote_id)
			if @item_do_aditivo_de_alteracao_de_marca.any?
				return aditivo
			end
		end
		return nil
	end

	def periodicidade_do_item
		if empenho.projeto.present? & empenho.try(:contrato).try(:projeto).try(:pedido).try(:possui_periodicidade_nos_itens?)
			return item_no_empenho.item_do_contrato.item_do_pedido.periodicidade_e_unidade_de_medida
		end
	end

	def valor_unico
		if item_no_empenho.present?
			item_no_empenho.valor_unitario
		else
			valor_unitario
		end
	end

	def valor_total
		if item_no_empenho.present?
			item_no_empenho.valor_unitario * quantidade
		else
			valor_unitario * quantidade
		end
	end

	def item_no_empenho
		empenho = ordem_de_compra.empenho
		return empenho.itens_do_empenho.find_by(item_id: item_id)
	end

	def total_agora
		self.total
	end

	def apaga_a_si_mesmo_se_quantidade_igual_a_zero
		self.delete unless self.quantidade.to_f > 0
	end

	def valida_saldo_de_itens
		if self.ordem_de_compra.ordem_de_compra_primaria.present?
			ordem_de_compra_primaria = self.ordem_de_compra.ordem_de_compra_primaria
			item_da_ordem_primaria = Licitacao::ItemDaOrdemDeCompra.where('ordem_de_compra_id = ? and item_id = ?', ordem_de_compra_primaria.id, self.item_id).first
			if self.item.present? && quantidade.to_f > 0
				errors.add(:quantidade, "não pode ser maior que o saldo do item da Ordem Primária") if quantidade.to_f > item_da_ordem_primaria.quantidade_a_receber
			end
		else
			if self.item.present? && quantidade.to_f > 0
				errors.add(:quantidade, "não pode ser maior que o saldo de itens do empenho") if quantidade.to_f > saldo_disponivel_na_origem_da_compra.to_f
			end
		end
	end

	def quantidade_recebida
		GestaoDeEstoque::ItemDoRecebimentoDeMaterial.joins(:recebimento_de_material)
			.where('gestao_de_estoque_recebimento_de_materiais.status != ? AND gestao_de_estoque_recebimento_de_materiais.ordem_de_compra_id = ? AND (gestao_de_estoque_itens_do_recebimento_de_materiais.item_id = ? OR gestao_de_estoque_itens_do_recebimento_de_materiais.item_original_id = ?)', 
			GestaoDeEstoque::RecebimentoDeMaterial.status[:devolvido_ao_fornecedor], self.ordem_de_compra_id, self.item_id, self.item_id).sum(:quantidade).to_f rescue 0
	end

	def quantidade_a_receber 
		quantidade - quantidade_recebida
	end	

	def valor_total_quantidade_recebida
		(quantidade_recebida * valor_unitario)
	end

	def valor_total_quantidade_a_receber
		(quantidade_a_receber * valor_unitario)
	end

	def limite_do_total_digitado_pelo_calculo
		total_calculado = self.quantidade * self.valor_unitario
		errors.add(:total, "não pode ser mais que 10 centavos do valor calculado da quantidade x preço unitário") if self.total > (total_calculado + 0.1)
		errors.add(:total, "não pode ser menos que 10 centavos do valor calculado da quantidade x preço unitário") if self.total < (total_calculado - 0.1)
	end
end
