module GestaoDeEstoque
	class RecebimentoDeMateriaisController < ApplicationController
		include ControllerConcern

		before_action :authenticate_usuario!
		before_action :autoriza_usuario!, except: [
			:listar_todos_os_itens_do_recebimento_de_material,
			:tornar_definitivo,
			:listar_itens_do_recebimento_por_codigo,
			:recebimento_de_materiais_por_unidade_orcamentaria_e_almoxarifado,
			:adicionar_informacoes_adicionais,
			:atualiza_informacoes_adicionais,
			:editar_itens_do_recebimento_de_materiais,
			:atualiza_itens_do_recebimento_de_materiais,
			:reabrir, :fechar, :receber_parcialmente, :receber, :remoto, :devolver_ao_fornecedor,
			:confirmar_multiplos_recebimentos
		]
		before_action :set_recebimento_de_material, only: [:show, :edit, :update, :destroy, :adicionar_informacoes_adicionais, 
			:atualiza_informacoes_adicionais, :editar_itens_do_recebimento_de_materiais, :atualiza_itens_do_recebimento_de_materiais, 
			:reabrir, :fechar, :receber_parcialmente, :receber, :remoto, :devolver_ao_fornecedor, :enviar_ao_patrimonio, 
			:set_item_do_recebimento, :atualiza_informacoes_extras, :editar_itens_para_nota_mista, :atualizar_itens_para_nota_mista]
		before_action :set_item_do_recebimento, only: [:adicionar_informacoes_adicionais, :atualiza_informacoes_extras]
		#before_action :disponibiliza_dependencias_informacoes_adicionais, only: [:adicionar_informacoes_adicionais, :atualiza_informacoes_adicionais]
		before_action :disponibiliza_dependencias, only: [:index, :show, :new, :create, :edit, :update, :adicionar_informacoes_adicionais, :atualiza_informacoes_adicionais, :editar_itens_do_recebimento_de_materiais, :atualiza_itens_do_recebimento_de_materiais]
		before_action :listar_ordens_de_compras_recebidas, only: [:index, :edit]
		before_action :listar_ordens_de_compras_enviadas, only: [:new, :create]

		# GET /gestao_de_estoque/recebimento_de_materiais
		def index
			@q =
				if configuracao.usa_modulo_administrativo? && params[:tipo].blank?
					GestaoDeEstoque::RecebimentoDeMaterial.where('gestao_de_estoque_recebimento_de_materiais.ordem_de_compra_id is not null and gestao_de_estoque_recebimento_de_materiais.unidade_orcamentaria_id in (?)', current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)).order('data_do_recebimento DESC').search(params[:q])
				elsif params[:tipo].present? && params[:tipo] == "outros"
					GestaoDeEstoque::RecebimentoDeMaterial.where('gestao_de_estoque_recebimento_de_materiais.ordem_de_compra_id is null and gestao_de_estoque_recebimento_de_materiais.unidade_orcamentaria_id in (?)', current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)).order('data_do_recebimento DESC').search(params[:q])
				else
					GestaoDeEstoque::RecebimentoDeMaterial.where('gestao_de_estoque_recebimento_de_materiais.unidade_orcamentaria_id in (?)', current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)).order('data_do_recebimento DESC').search(params[:q])
				end

			@recebimento_de_materiais = @q.result(distinct: false).where(orcamento: contexto_atual).paginate(page: params[:page], per_page: 10)
		end

		# GET /gestao_de_estoque/recebimento_de_materiais/1
		def show
		end

		# GET /gestao_de_estoque/recebimento_de_materiais/new
		def new
			@recebimento_de_material = GestaoDeEstoque::RecebimentoDeMaterial.new
			if params[:tipo].present? && params[:tipo] == "outros"
				@recebimento_de_material.classificacao = GestaoDeEstoque::RecebimentoDeMaterial.classificacoes[:doacao] if @recebimento_de_material.classificacao.nil?
			elsif params[:ordem_de_compra_id].present? && !params[:ordem_de_compra_id].nil?
				@recebimento_de_material.avulso = false
				@ordem_de_compra = Licitacao::OrdemDeCompra.find(params[:ordem_de_compra_id])
				@recebimento_de_material.ordem_de_compra = @ordem_de_compra
				@recebimento_de_material.atribui_tipo_de_material
				@recebimento_de_material.atribui_almoxarifado_e_unidade
			elsif params[:devolucao_de_material_id].present?
				@devolucao = GestaoDeEstoque::DevolucaoDeMaterial.find(params[:devolucao_de_material_id])
				@recebimento_de_material.devolucao_de_material = @devolucao
				@recebimento_de_material.classificacao = :devolucao_estorno
				@recebimento_de_material.tipo_de_recebimento = :recebimento_total
				@recebimento_de_material.atribui_almoxarifado_e_unidade
			end
		end

		# GET /gestao_de_estoque/recebimento_de_materiais/1/edit
		def edit
		end

		# POST /gestao_de_estoque/recebimento_de_materiais
		def create
			@recebimento_de_material = GestaoDeEstoque::RecebimentoDeMaterial.new(recebimento_de_material_params)
			@recebimento_de_material.orcamento = contexto_atual
			@recebimento_de_material.data_provisoria = @recebimento_de_material.data_do_recebimento if @recebimento_de_material.provisorio?			
			converte_unidades = @recebimento_de_material.converte_unidades == "1" || @recebimento_de_material.recebimento_parcial? || @recebimento_de_material.entrada_por_outros?

			listar_todos_os_itens_do_recebimento_de_material unless converte_unidades
			@recebimento_de_material.transaction do
				if @recebimento_de_material.save
					if converte_unidades
						redirect_to gestao_de_estoque_editar_itens_do_recebimento_de_materiais_path(@recebimento_de_material)
					else
						redirect_to @recebimento_de_material, notice: 'Recebimento de material efetuado com sucesso.'
					end
				else
					disponibiliza_dependencias
					render :new
				end
			rescue Exception => e
				disponibiliza_dependencias
				render :new
				flash[:alert] = "Erro ao efetuar o recebimento #{e.message}"
				raise ActiveRecord::Rollback
			end
		end

		# PATCH/PUT /gestao_de_estoque/recebimento_de_materiais/1
		def update
			converte_unidades = recebimento_de_material_params[:converte_unidades] == "1" || recebimento_de_material_params[:tipo_de_recebimento] == "recebimento_parcial" || @recebimento_de_material.entrada_por_outros?
			listar_todos_os_itens_do_recebimento_de_material unless converte_unidades

			@recebimento_de_material.transaction do
				if @recebimento_de_material.tipo_de_recebimento == "recebimento_total" && recebimento_de_material_params[:tipo_de_recebimento] == "recebimento_parcial"
					@recebimento_de_material.itens_do_recebimento_de_materiais.destroy_all
				end
				
				if @recebimento_de_material.update(recebimento_de_material_params)
					if converte_unidades #&& @recebimento_de_material.itens_do_recebimento_de_materiais.present?
						redirect_to gestao_de_estoque_editar_itens_do_recebimento_de_materiais_path(@recebimento_de_material)
					else
						redirect_to @recebimento_de_material, notice: 'Recebimento de material foi atualizado(a) com sucesso.'
					end
				else
					disponibiliza_dependencias
					render :edit
				end
			rescue Exception => e
				disponibiliza_dependencias
				render :edit
				flash[:alert] = "Erro ao efetuar o recebimento #{e.message}"
				raise ActiveRecord::Rollback
			end
		end

		# DELETE /gestao_de_estoque/recebimento_de_materiais/1
		def destroy
			mensagem = apaga_e_retorna_mensagem(@recebimento_de_material)
			redirect_to gestao_de_estoque_recebimento_de_materiais_url, mensagem
		end

		def listar_todos_os_itens_do_recebimento_de_material
			if @recebimento_de_material.itens_do_recebimento_de_materiais.empty? && @recebimento_de_material.possui_ordem_de_compra? && @recebimento_de_material.tipo_de_recebimento == "recebimento_total"
				@itens = @recebimento_de_material.ordem_de_compra.itens_da_ordem_de_compra
				@itens.each do |item_da_ordem_de_compra|
					@recebimento_de_material.itens_do_recebimento_de_materiais.build(
						item_id: item_da_ordem_de_compra.item.id,
						marca: item_da_ordem_de_compra.marca,
						quantidade: item_da_ordem_de_compra.quantidade_a_receber,
						valor_unitario: item_da_ordem_de_compra.try(:valor_unitario),
						total: item_da_ordem_de_compra.try(:valor_total_quantidade_a_receber)
					) if item_da_ordem_de_compra.quantidade_a_receber > 0
				end
				@itens_paginados = @recebimento_de_material.itens_do_recebimento_de_materiais.to_a.paginate(page: params[:page], per_page: 500)
			elsif @recebimento_de_material.itens_do_recebimento_de_materiais.empty? && @recebimento_de_material.possui_ordem_de_compra? && @recebimento_de_material.tipo_de_recebimento == "recebimento_parcial"
				@itens = @recebimento_de_material.ordem_de_compra.itens_da_ordem_de_compra
				@itens.each do |item_da_ordem_de_compra|
					@recebimento_de_material.itens_do_recebimento_de_materiais.build(
						item_id: item_da_ordem_de_compra.item.id,
						marca: item_da_ordem_de_compra.marca,
						quantidade: 0,
						valor_unitario: item_da_ordem_de_compra.try(:valor_unitario),
						total: item_da_ordem_de_compra.try(:total)
					) if item_da_ordem_de_compra.quantidade_a_receber > 0
				end
				@itens_paginados = @recebimento_de_material.itens_do_recebimento_de_materiais.to_a.paginate(page: params[:page], per_page: 500)
			elsif @recebimento_de_material.devolucao_de_material.present? && @recebimento_de_material.itens_do_recebimento_de_materiais.empty?
				@itens = @recebimento_de_material.devolucao_de_material.itens_das_devolucoes_de_materiais
				@itens.each do |item_da_devolucao|
					@recebimento_de_material.itens_do_recebimento_de_materiais.build(
						item_id: item_da_devolucao.item.id,
						quantidade: item_da_devolucao.quantidade_devolvida,
						valor_unitario: item_da_devolucao.try(:valor_unitario_medio),
						total: item_da_devolucao.try(:valor_total)
					) if item_da_devolucao.quantidade_devolvida > 0
				end
				@itens_paginados = @recebimento_de_material.itens_do_recebimento_de_materiais.to_a.paginate(page: params[:page], per_page: 500)
			else
				if @recebimento_de_material.ordem_de_compra.present?
					if @recebimento_de_material.itens_do_recebimento_de_materiais.present?
						@itens = @recebimento_de_material.itens_do_recebimento_de_materiais
					else
						@itens = @recebimento_de_material.ordem_de_compra.itens_da_ordem_de_compra
						@itens.each do |item_da_ordem_de_compra|
							@recebimento_de_material.itens_do_recebimento_de_materiais.where.not(item_id: @recebimento_de_material.itens_do_recebimento_de_materiais.pluck(:item_id)).build(
								item_id: item_da_ordem_de_compra.item.id,
								marca: item_da_ordem_de_compra.marca,
								quantidade: 0,
								valor_unitario: item_da_ordem_de_compra.try(:valor_unitario),
								total: item_da_ordem_de_compra.try(:total)
							) 
						end
					end
					@itens_paginados = @recebimento_de_material.itens_do_recebimento_de_materiais.to_a.paginate(page: params[:page], per_page: 500)
				else
					if @recebimento_de_material.itens_do_recebimento_de_materiais.empty?
						@recebimento_de_material.itens_do_recebimento_de_materiais.build
					end
					@itens_paginados = @recebimento_de_material.itens_do_recebimento_de_materiais.to_a.paginate(page: params[:page], per_page: 500)
				end
			end
		end

		def tornar_definitivo
			return if bloqueia_usuario_com_base_em 'update'
			@recebimento_de_material = GestaoDeEstoque::RecebimentoDeMaterial.find(params[:id])
			if @recebimento_de_material.update_attribute(:tipo_de_entrada, :definitivo)
				redirect_to @recebimento_de_material, notice: 'Recebido definitivamente no almoxarifado com sucesso.'
			end
		end

		def receber_parcialmente
			return if bloqueia_usuario_com_base_em 'update'
			if @recebimento_de_material.receber_parcialmente!
				redirect_to gestao_de_estoque_recebimento_de_material_path(@recebimento_de_material), notice: 'O recebimento parcialmente foi realizado com sucesso.'
			else
				render :show
			end
		end

		def receber
			return if bloqueia_usuario_com_base_em 'update'
			if @recebimento_de_material.receber!
				redirect_to gestao_de_estoque_recebimento_de_material_path(@recebimento_de_material), notice: 'O recebimento realizado com sucesso.'
			else
				render :show
			end
		end

		def reabrir
			return if bloqueia_usuario_com_base_em 'update'
			if @recebimento_de_material.reabrir!
				redirect_to gestao_de_estoque_recebimento_de_material_path(@recebimento_de_material), notice: 'O recebimento está aberto, novamente.'
			else
				render :show
			end
		end

		def devolver_ao_fornecedor
			return if bloqueia_usuario_com_base_em 'update'
			if @recebimento_de_material.devolver_ao_fornecedor!
				@recebimento_de_material.ordem_de_compra.devolver_ao_fornecedor!
				redirect_to ordem_de_compra_path(@recebimento_de_material.ordem_de_compra), notice: 'O recebimento foi devolvido ao fornecedor.'
			end
		end

		def recebimento_de_materiais_por_unidade_orcamentaria_e_almoxarifado
			@recebimento_de_materiais =
				GestaoDeEstoque::RecebimentoDeMaterial.joins(
					ordem_de_compra: [
						empenho: [
							orcamento_da_despesa: [
								elemento_de_despesa_por_subacao: :subacao
							]
						]
					]).where({
						loa_subacoes: {
							unidade_orcamentaria_id: params[:unidade_orcamentaria_id]
						}, licitacao_ordens_de_compra: {
							almoxarifado_id: params[:almoxarifado_id]
						}
					}).order(id: :desc)

			respond_to do |format|
				format.json { render json: @recebimento_de_materiais, methods: :numero_da_ordem_de_compra_e_fornecedor }
			end
		end

		def remoto
			@recebimento_de_material.transaction do
				if @recebimento_de_material.remoto!
					redirect_to gestao_de_estoque_recebimento_de_material_path(@recebimento_de_material), notice: 'Recebimento Remoto Realizado'
				else
					render :show
				end
			rescue Exception => e
				render :show
				flash[:alert] = "Erro ao atualizar os saldos no estoque #{e.message}"
				raise ActiveRecord::Rollback
			end
		end

		def listar_itens_do_recebimento_por_codigo
			@item = GestaoDeEstoque::ItemDoRecebimentoDeMaterial.includes(:item).find_by(id: params[:id])

			respond_to do |format|
				format.json { render json: @item, methods: [
					:codigo_e_descricao_com_unidade_de_medida_especifica,
					:retorna_unidade_de_medida_ou_conversao,
					:unidade_de_medida_descricao,
					:quantidade_total_disponivel_da_ordem_de_compra,
					:saldo_atual_do_recebimento_de_material
				]}
			end
		end

		def buscar_valor_a_receber_do_item
			item = Licitacao::ItemDaOrdemDeCompra.where(item_id: params[:item_id], ordem_de_compra_id: params[:ordem_de_compra_id]).first

			respond_to do |format|
				format.json { render json: item, methods: :quantidade_a_receber}
			end
		end

		def adicionar_informacoes_adicionais
			if @item_do_recebimento.informacoes_extras.empty?
				@item_do_recebimento.informacoes_extras.build
			end
		end

		def atualiza_informacoes_adicionais
			return if bloqueia_usuario_com_base_em 'update'
			@recebimento_de_material = GestaoDeEstoque::RecebimentoDeMaterial.find(params[:id])
			if @recebimento_de_material.update(informacoes_adicionais_params)
				redirect_to @recebimento_de_material, notice: 'Informações adicionadas com sucesso.'
			else
				render :adicionar_informacoes_adicionais
			end
		end

		def atualiza_itens_do_recebimento_de_materiais
			return if bloqueia_usuario_com_base_em 'update'

			itens_atualizados = itens_do_recebimento_de_materiais_params
			itens_atualizados.values.each do |item|
				item = item.values.first

				next if @recebimento_de_material.avulso? || item["valor_unitario"].present?
				index = @recebimento_de_material.itens_do_recebimento_de_materiais.index {|r| r.id.to_s == item["id"]}
				
				novo_valor_unitario = nil
				if index == nil
					ordem_de_compra_id = @recebimento_de_material.ordem_de_compra.id
					novo_valor_unitario = item_da_ordem_de_compra = Licitacao::ItemDaOrdemDeCompra.where(
							item_id: item["item_id"], 
							ordem_de_compra_id: ordem_de_compra_id
						).first
						 .valor_unitario 
				else
					item_atual = @recebimento_de_material.itens_do_recebimento_de_materiais[index]
					novo_valor_unitario = item_atual.valor_unitario
				end

				item["valor_unitario"] = novo_valor_unitario
			end

			if @recebimento_de_material.update(itens_atualizados)
				redirect_to gestao_de_estoque_recebimento_de_material_path(@recebimento_de_material), notice: 'Os itens do recebimento foram atualizados com sucesso.'
			else
				listar_todos_os_itens_do_recebimento_de_material
				render :editar_itens_do_recebimento_de_materiais
			end
			# @recebimento_de_material.transaction do
			# 	if @recebimento_de_material.update(itens_do_recebimento_de_materiais_params)
			# 		listar_todos_os_itens_do_recebimento_de_material
			# 		respond_to do |format|
			# 			format.json { render json: true }
			# 		end
			# 	else
			# 		listar_todos_os_itens_do_recebimento_de_material
			# 		respond_to do |format|
			# 			recebimento_de_material = @recebimento_de_material.errors.to_hash
			# 			id_dos_itens = recebimento_de_material_params[:itens_do_recebimento_de_materiais_attributes].values.map { |item_do_recebimento_de_material| item_do_recebimento_de_material[:id] } rescue []
			# 			itens_invalidos = @recebimento_de_material.itens_do_recebimento_de_materiais.select { |item| id_dos_itens.include?(item.id.to_s) && item.invalid? }
			# 			json_errors = {}

			# 			itens_invalidos.each do |item_invalido|
			# 				json_errors[item_invalido.id.to_s.to_sym] = item_invalido.errors.to_hash
			# 			end
			# 			json_errors[0] = recebimento_de_material
			# 			format.json {render json: json_errors}
			# 		end
			# 	end
			# rescue Exception => e
			# 	render :editar_itens_do_recebimento_de_materiais
			# 	flash[:alert] = "Erro ao atualizar os saldos no estoque #{e.message}"
			# 	raise ActiveRecord::Rollback
			# end
		end

		def enviar_ao_patrimonio
			return if bloqueia_usuario_com_base_em 'update'
			if @recebimento_de_material.enviar_ao_patrimonio!
				render :show, notice: 'O recebimento foi enviado ao Patrimônio com sucesso.'
			end
		end

		def editar_itens_do_recebimento_de_materiais
			if params[:todos].present? && params[:todos] == "true" && @recebimento_de_material.ordem_de_compra.present?
				itens_da_ordem_de_compra = @recebimento_de_material.ordem_de_compra.itens_da_ordem_de_compra
				itens_do_recebimento_de_materiais = @recebimento_de_material.itens_do_recebimento_de_materiais.where(item_id: @recebimento_de_material.itens_do_recebimento_de_materiais.map(&:item_id))
				@itens = itens_da_ordem_de_compra - itens_do_recebimento_de_materiais
				@itens.each do |item_da_ordem_de_compra|
					unless @recebimento_de_material.itens_do_recebimento_de_materiais.pluck(:item_id).include?(item_da_ordem_de_compra.item_id)
						@recebimento_de_material.itens_do_recebimento_de_materiais.build(
							item_id: item_da_ordem_de_compra.item.id,
							marca: item_da_ordem_de_compra.marca,
							quantidade: 0,
							valor_unitario: item_da_ordem_de_compra.try(:valor_unitario),
							total: item_da_ordem_de_compra.try(:total)
						)
					end
				end
				@itens_paginados = @recebimento_de_material.itens_do_recebimento_de_materiais.to_a.paginate(page: params[:page], per_page: 500)
			else
				# listar_todos_os_itens_do_recebimento_de_material
				if @recebimento_de_material.tipo_de_recebimento == "recebimento_total"
					@itens = @recebimento_de_material.ordem_de_compra.itens_da_ordem_de_compra
					@itens.each do |item_da_ordem_de_compra|
						@recebimento_de_material.itens_do_recebimento_de_materiais.build(
							item_id: item_da_ordem_de_compra.item.id,
							marca: item_da_ordem_de_compra.marca,
							quantidade: item_da_ordem_de_compra.quantidade_a_receber,
							valor_unitario: item_da_ordem_de_compra.try(:valor_unitario),
							total: item_da_ordem_de_compra.try(:valor_total_quantidade_a_receber)
						) if item_da_ordem_de_compra.quantidade_a_receber > 0
					end
				else
					@recebimento_de_material.itens_do_recebimento_de_materiais.build if @recebimento_de_material.itens_do_recebimento_de_materiais.empty?
				end

				@itens_paginados = @recebimento_de_material.itens_do_recebimento_de_materiais.to_a.paginate(page: params[:page], per_page: 500)
			end
		end

		#POST /gestao_de_estoque/recebimento_de_materiais/confirmar_multiplos_recebimentos
		def confirmar_multiplos_recebimentos
			return if bloqueia_usuario_com_base_em 'update'

			recebimento_de_materiais = params[:gestao_de_estoque_recebimento_de_material]
			if recebimento_de_materiais.nil?
				redirect_to intermodulos_entradas_path, alert: "Nenhuma Entrada foi selecionada"
				return
			end
			recebidas = Array.new
			erros = Set.new
			quantidade_enviada = 0
			status_final = ""
			ActiveRecord::Base.transaction do
				recebimento_de_materiais.each do |id, valor|
					if valor.eql?("1")
						quantidade_enviada += 1
						recebimento_de_material = GestaoDeEstoque::RecebimentoDeMaterial.find(id.to_s.to_i)
						recebimento_de_material.status = GestaoDeEstoque::RecebimentoDeMaterial.status[:confirmado]
						if recebimento_de_material.save
							recebidas << id
						else
							recebimento_de_material.errors.full_messages.each do |erro|
								erros << erro
							end
							raise ActiveRecord::Rollback
						end
					end
				end
			end
			if recebidas.size == 0
				if erros.size == 0
					redirect_to intermodulos_entradas_path, alert: "Nenhuma Entrada foi confirmada"
				else
					redirect_to intermodulos_entradas_path, alert: "Falha ao confirmar Entradas: #{erros.to_a.join(', ')}"
				end
			elsif recebidas.size == 1
				redirect_to gestao_de_estoque_recebimento_de_material_path(id: recebidas[0]), success: "Entrada confirmada com sucesso"
			else
				redirect_to intermodulos_entradas_path, success: "Todas #{recebidas.size} Entradas foram confirmadas com sucesso"
			end
		end

		def atualiza_informacoes_extras
			if @item_do_recebimento.update(informacoes_extras_params)
				redirect_to gestao_de_estoque_recebimento_de_material_path(@item_do_recebimento.recebimento_de_material.id), success: " Foram Cadastrado Todas as Informações Extras do item #{@item_do_recebimento.item.descricao_do_item}"
			else
				render :adicionar_informacoes_adicionais
			end
		end

		def editar_itens_para_nota_mista
			@itens = Base::Item.all.where('base_itens.ncm_id is NOT NULL')
		end

		def atualizar_itens_para_nota_mista
			return if bloqueia_usuario_com_base_em 'update'
			@recebimento_de_material.transaction do
				if @recebimento_de_material.update(itens_do_recebimento_de_materiais_params)
					redirect_to gestao_de_estoque_recebimento_de_material_path(@recebimento_de_material), notice: 'Itens atualizados com sucesso.'
				else
					render :editar_itens_para_nota_mista
				end
			rescue Exception => e
				@itens = Base::Item.all
				render :editar_itens_para_nota_mista
				flash[:alert] = "Erro ao atualizar os Itens #{e.message}"
				raise ActiveRecord::Rollback
			end
		end

		private

		def disponibiliza_dependencias
			@unidades_de_medida = UnidadeDeMedida.order("id ASC")
			@classificacoes = GestaoDeEstoque::RecebimentoDeMaterial.classificacoes
			@tipos_de_entradas = GestaoDeEstoque::RecebimentoDeMaterial.tipos_de_entradas
			@tipos_de_recebimento = GestaoDeEstoque::RecebimentoDeMaterial.tipos_de_recebimento
			@modalidades_de_licitacao = GestaoDeEstoque::RecebimentoDeMaterial.modalidades_de_licitacao
			@tipos_de_materiais = GestaoDeEstoque::RecebimentoDeMaterial.tipos_de_materiais
			@classificacoes_tipo_de_material = GestaoDeEstoque::RecebimentoDeMaterial.classificacoes_tipo_de_material
			@fornecedores = Base::Pessoa.includes(:tipo_de_pessoa).where(fornecedor: :true)
			@doadores = Base::Pessoa.includes(:tipo_de_pessoa).order("id ASC")
			@unidades_orcamentarias = contexto_atual.unidades_orcamentarias.where(id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)).order(:codigo, :nome)
			@almoxarifados = GestaoDeEstoque::Almoxarifado.joins(:unidades_orcamentarias_do_almoxarifado).where("gestao_de_estoque_almoxarifados.orcamento_id = ? and gestao_de_estoque_unidades_orcamentarias_do_almoxarifado.unidade_orcamentaria_id = ?", contexto_atual.id, @recebimento_de_material.try(:unidade_orcamentaria_id)).order("id ASC") || Array.new
			@almoxarifados_de_destino = GestaoDeEstoque::Almoxarifado.joins(:unidades_orcamentarias_do_almoxarifado).where("gestao_de_estoque_almoxarifados.orcamento_id = ? and gestao_de_estoque_unidades_orcamentarias_do_almoxarifado.unidade_orcamentaria_id = ?", contexto_atual.id, @recebimento_de_material.try(:unidade_orcamentaria_de_destino_id)).order("id ASC") || Array.new
			@unidades_orcamentarias_de_destino = contexto_atual.unidades_orcamentarias if params[:tipo].blank?

			if @recebimento_de_material.present? && @recebimento_de_material.tipo_de_material.present?
				if @recebimento_de_material.permanente?
					@sub_elementos_de_despesa  = Contabilidade::SubElementoDeDespesa.ativos.joins(elemento_de_despesa: [modalidade_de_aplicacao: [grupo_de_natureza_da_despesa: :categoria_economica]]).where("base_elementos_de_despesa.codigo = '44905200' and base_categorias_economicas.modulo_type = 'Orcamento' and base_categorias_economicas.modulo_id = ?", contexto_atual.id).order(codigo: :asc)
				elsif @recebimento_de_material.consumo?
					@sub_elementos_de_despesa  = Contabilidade::SubElementoDeDespesa.ativos.joins(elemento_de_despesa: [modalidade_de_aplicacao: [grupo_de_natureza_da_despesa: :categoria_economica]]).where("base_elementos_de_despesa.codigo = '33903000' and base_categorias_economicas.modulo_type = 'Orcamento' and base_categorias_economicas.modulo_id = ?", contexto_atual.id).order(codigo: :asc)
				else
					@sub_elementos_de_despesa  = Contabilidade::SubElementoDeDespesa.ativos.joins(elemento_de_despesa: [modalidade_de_aplicacao: [grupo_de_natureza_da_despesa: :categoria_economica]]).where("base_elementos_de_despesa.codigo = '33903200' and base_categorias_economicas.modulo_type = 'Orcamento' and base_categorias_economicas.modulo_id = ?", contexto_atual.id).order(codigo: :asc)
				end
			else
				@sub_elementos_de_despesa = Array.new
			end

			@tipo = params[:tipo]
			@classificacoes_do_detalhamento = Contabilidade::SubElementoDeDespesa.ativos.joins(elemento_de_despesa: [modalidade_de_aplicacao: [grupo_de_natureza_da_despesa: :categoria_economica]]).where("base_elementos_de_despesa.codigo = '33903000' and base_categorias_economicas.modulo_type = 'Orcamento' and base_categorias_economicas.modulo_id = ?", contexto_atual.id).order(codigo: :asc)

			if @recebimento_de_material.try(:ordem_de_compra).present?
				@itens = @recebimento_de_material.ordem_de_compra.itens.all
			else
				if @recebimento_de_material.present? && @recebimento_de_material.sub_elemento_de_despesa.present?
					@tipo = @recebimento_de_material.sub_elemento_de_despesa.descricao
					categorias = Base::Categoria.find_by_sql("SELECT * FROM base_categorias WHERE titulo ilike '%#{@tipo}%'")
					@itens = Base::Item.includes(:unidade_de_medida).joins(:categoria).where('base_categorias.id in (?)', categorias.pluck(:id))
				else
					@itens = Base::Item.includes(:unidade_de_medida).all
				end
			end
			
			@itens_select = @itens
		end

		def listar_ordens_de_compras_recebidas
			@ordens_de_compra = contexto_atual.ordens_de_compra.joins(:recebimento_de_materiais).where(
				'licitacao_ordens_de_compra.status in (3,5) and gestao_de_estoque_recebimento_de_materiais.unidade_orcamentaria_id in (?)', current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)
			).all
		end

		def listar_ordens_de_compras_enviadas
			@ordens_de_compra = contexto_atual.ordens_de_compra.joins(:recebimento_de_materiais).where(
				'licitacao_ordens_de_compra.status in (2) and gestao_de_estoque_recebimento_de_materiais.unidade_orcamentaria_id in (?)', current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)
			).all
		end

		def set_recebimento_de_material
			@recebimento_de_material = GestaoDeEstoque::RecebimentoDeMaterial.find(params[:id])
		end

		def set_item_do_recebimento
			@item_do_recebimento = GestaoDeEstoque::RecebimentoDeMaterial.find(params[:id]).itens_do_recebimento_de_materiais.find_by(id: params[:item_do_recebimento_id]) rescue nil
		end

		# Permite apenas os parâmetros específicos
		def recebimento_de_material_params
			params.require(:gestao_de_estoque_recebimento_de_material)
				.permit(
					:codigo, :data_do_recebimento, :tipo_de_material, :tipo_de_entrada, :ordem_de_compra_id,
					:orcamento_id, :observacao, :local, :tipo_de_recebimento, :numero_da_nota,
					:serie, :data_de_emissao, :fornecedor_id, :almoxarifado_id, :unidade_orcamentaria_id,
					:numero_do_empenho, :data_do_empenho, :exercicio_do_empenho, :modalidade_de_licitacao, :numero_do_processo,
					:numero_do_contrato, :numero_da_ordem_de_compra, :classificacao, :unidade_orcamentaria_de_destino_id, :almoxarifado_de_destino_id,
					:transferir_todos_os_itens, :doador_id, :avulso, :fabricante, :lote, :classificacao_do_detalhamento_id, :data_provisoria,
					:validade, :classificacao_tipo_de_material, :devolucao_de_material_id, :sub_elemento_de_despesa_id, :converte_unidades,
					itens_do_recebimento_de_materiais_attributes: [
						:id,
						:item_id,
						:item_selecionado,
						:item_original_id,
						:recebimento_de_material_id,
						:quantidade,
						:valor_unitario,
						:marca,
						:total,
						:quantidade_de_conversao,
						:unidade_de_medida_de_conversao_id,
						:saldo_em_quantidade,
						:valor_unitario_de_conversao,
						:_destroy
					]
				)
		end

		def itens_do_recebimento_de_materiais_params
			params.require(:gestao_de_estoque_recebimento_de_material)
				.permit(
					itens_do_recebimento_de_materiais_attributes: [
						:id,
						:item_id,
						:item_selecionado,
						:item_original_id,
						:recebimento_de_material_id,
						:quantidade,
						:valor_unitario,
						:marca,
						:total,
						:quantidade_de_conversao,
						:valor_unitario_de_conversao,
						:unidade_de_medida_de_conversao_id,
						:saldo_em_quantidade,
						:valor_unitario_de_conversao,
						:_destroy
					]
				)
		end

		def informacoes_adicionais_params
			params.require(:gestao_de_estoque_recebimento_de_material)
				.permit(
					:id,
					:fabricante,
					:lote,
					:validade,
					:perecivel,
					:odor,
					:textura,
					:cor,
					:aspecto_geral,
					:condicao_da_embalagem,
					:registro_no_ministerio_da_saude
				)
		end

		def informacoes_extras_params
			params.require(:gestao_de_estoque_item_do_recebimento_de_material).permit(
				informacoes_extras_attributes: [
					:id,
					:item_id,
					:quantidade,
					:validade,
					:aspecto_geral,
					:perecivel,
					:recebimento_id,
					:lote_de_fabricacao,
					:_destroy
				]
			)
		end

	end
end
