module GestaoDeEstoque
class TransferenciasController < ApplicationController
	include ControllerConcern
	before_action :authenticate_usuario!
	before_action :autoriza_usuario!
	before_action :set_transferencia, only: [:show, :edit, :update, :destroy, :editar_itens_da_transferencias , :atualiza_itens_da_transferencias, :retornar_para_confirmado]
	before_action :disponibiliza_dependencias , only: [:index]
	before_action :disponibiliza_dependencias_form , only: [:edit, :new]
	before_action :adicionar_dependencias_escolas, only: [:new, :create, :edit]

	# GET /gestao_de_estoque/transferencias
	def index
		trans_origem = GestaoDeEstoque::Transferencia.joins(:almoxarifado).where('gestao_de_estoque_almoxarifados.tipo_de_almoxarifado = 9')
		trans_destino = GestaoDeEstoque::Transferencia.joins(:almoxarifado_de_destino).where('gestao_de_estoque_almoxarifados.tipo_de_almoxarifado = 9')

		@q = GestaoDeEstoque::Transferencia.where.not(id: trans_origem.pluck(:id).uniq).where.not(id: trans_destino.pluck(:id).uniq).where(unidade_orcamentaria: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)).order(data_de_transferencia: :desc).search(params[:q])
		@transferencias = @q.result(distinct: false).where(orcamento: contexto_atual).paginate(page: params[:page], per_page: 10)
	end

	# GET /gestao_de_estoque/transferencias/1
	def show
	end

	# GET /gestao_de_estoque/transferencias/new
	def new
		@transferencia = Transferencia.new
		@transferencia.programas_por_almoxarifado_e_transferencia.build if @transferencia.programas_por_almoxarifado_e_transferencia.empty?
	end

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

	# POST /gestao_de_estoque/transferencias
	def create
		@transferencia = Transferencia.new(transferencia_params)
		@transferencia.orcamento = contexto_atual
		if @transferencia.save
			if @transferencia.transferir_todos_os_itens || @transferencia.usa_programa?
				redirect_to gestao_de_estoque_transferencia_path(@transferencia)
			else
				redirect_to gestao_de_estoque_editar_itens_da_transferencias_path(@transferencia)
			end
		else
			disponibiliza_dependencias_form
			render :new
		end
	end

	# PATCH/PUT /gestao_de_estoque/transferencias/1
	def update
		if @transferencia.update( transferencia_params )
			redirect_to @transferencia, notice: 'Transferencia foi atualizado(a) com sucesso.'
		else
			disponibiliza_dependencias_form
			render :edit
		end
	end

	# DELETE /gestao_de_estoque/transferencias/1
	def destroy
		mensagem = apaga_e_retorna_mensagem(@transferencia)
		redirect_to gestao_de_estoque_transferencias_url, mensagem
	end

	def listar_todos_os_itens_da_transferencia
		@transferencia = GestaoDeEstoque::Transferencia.find(params[:id])
		@itens = Base::Item.joins(:estoques).where("gestao_de_estoque_estoques.almoxarifado_id = #{@transferencia.almoxarifado_id} AND gestao_de_estoque_estoques.unidade_orcamentaria_id = #{@transferencia.unidade_orcamentaria_id}").all
		@estoques = GestaoDeEstoque::Estoque.where("gestao_de_estoque_estoques.almoxarifado_id = #{@transferencia.almoxarifado_id} AND gestao_de_estoque_estoques.unidade_orcamentaria_id = #{@transferencia.unidade_orcamentaria_id}").select{ |estoque| estoque.quantidade_total_saldo > 0 }
		unless @transferencia.itens_da_transferencia.present?
			@transferencia.itens_da_transferencia.build
		end
	end

	def atualiza_itens_da_transferencias
		unless defined?(@itens)
			self.listar_todos_os_itens_da_transferencia
		end
		@transferencia = GestaoDeEstoque::Transferencia.find(params[:id])
		@transferencia.transaction do
			if @transferencia.update(itens_da_transferencia_params)
				redirect_to gestao_de_estoque_transferencia_path(@transferencia)
			else
				render :editar_itens_da_transferencias
			end

		rescue Exception => e
			render :editar_itens_da_transferencias
			flash[:alert] = "Erro ao atualizar os saldos no estoque #{e.message}"
			raise ActiveRecord::Rollback
		end

	end

	# PATCH /liquidacoes/1/retornar_para_confirmado
	def retornar_para_confirmado
		@transferencia.status = GestaoDeEstoque::Transferencia.status[:solicitado]
		if @transferencia.save(validate: false)
			redirect_to gestao_de_estoque_transferencia_path(@transferencia), success: 'A transferência foi retornada para edição.'
		else
			redirect_to gestao_de_estoque_transferencia_path(@transferencia), alert: 'Não foi possível retornar a transferência. Por favor, confira se ela contém erros.'
		end
	end

	def solicitar_transferencia
		@transferencia = GestaoDeEstoque::Transferencia.find(params[:id])
		if @transferencia.solicitar_transferencia!
			redirect_to gestao_de_estoque_transferencia_path(@transferencia) ,notice: "A Transferencia foi Confirmada"
		else
			redirect_to gestao_de_estoque_transferencia_path(@transferencia)
		end
	end

	def confirmar_transferencia
		@transferencia = GestaoDeEstoque::Transferencia.find(params[:id])
		if @transferencia.confirmar_transferencia!
			redirect_to gestao_de_estoque_transferencia_path(@transferencia) ,notice: "A Transferencia foi Confirmada"
		else
			redirect_to gestao_de_estoque_transferencia_path(@transferencia)
		end
	end

	def confirmar_recebimento_da_transferencia
		@transferencia = GestaoDeEstoque::Transferencia.find(params[:id])
		if @transferencia.confirmar_recebimento_da_transferencia!
			redirect_to gestao_de_estoque_transferencia_path(@transferencia) ,notice: "A Transferencia foi Concluida"
		else
			redirect_to gestao_de_estoque_transferencia_path(@transferencia)
		end
	end

	def editar_itens_da_transferencias
		listar_todos_os_itens_da_transferencia
	end

	private
		def set_transferencia
			@transferencia = Transferencia.find( params[:id] )
		end

		def disponibiliza_dependencias
			@unidades_de_medida = UnidadeDeMedida.order("id ASC")
			@tipos_de_materiais = GestaoDeEstoque::Transferencia.tipos_de_materiais
			@classificacoes_tipo_de_material = GestaoDeEstoque::Transferencia.classificacoes_tipo_de_material
			@unidades_orcamentarias = contexto_atual.unidades_orcamentarias.where(id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)).order(:codigo, :nome)
			@almoxarifados = GestaoDeEstoque::Almoxarifado.where("orcamento_id = #{contexto_atual.id}").order("id ASC")
		end

		def adicionar_dependencias_escolas
			if @transferencia.present?
				@programas = []
				@transferencia.programas_por_almoxarifado_e_transferencia.each do |campo|
					@programas << campo.programa
				end
			else
				@programas = Array.new
			end
		end

		def disponibiliza_dependencias_form
			@tipos_de_materiais = GestaoDeEstoque::Transferencia.tipos_de_materiais
			@classificacoes_tipo_de_material = GestaoDeEstoque::Transferencia.classificacoes_tipo_de_material
			@unidades_orcamentarias = contexto_atual.unidades_orcamentarias.where(id: current_usuario.unidades_orcamentarias_por_usuario.pluck(:unidade_orcamentaria_id)).order(:codigo, :nome)
			@almoxarifados_de_origem = GestaoDeEstoque::Almoxarifado.joins(:unidades_orcamentarias_do_almoxarifado).where("gestao_de_estoque_unidades_orcamentarias_do_almoxarifado.unidade_orcamentaria_id = ? and gestao_de_estoque_almoxarifados.orcamento_id = ? ", @transferencia.try(:unidade_orcamentaria_id), contexto_atual.id).order("id ASC") || Array.new
			@almoxarifados_de_destino = GestaoDeEstoque::Almoxarifado.joins(:unidades_orcamentarias_do_almoxarifado).where("gestao_de_estoque_unidades_orcamentarias_do_almoxarifado.unidade_orcamentaria_id = ? and gestao_de_estoque_almoxarifados.orcamento_id = ? ", @transferencia.try(:unidade_orcamentaria_de_destino_id), contexto_atual.id).order("id ASC") || Array.new
		end
		# Permite apenas os parâmetros específicos
		def transferencia_params
			params.require(:gestao_de_estoque_transferencia).permit(:tipo_de_material,
				:tipo_de_entrada,
				:almoxarifado_id,
				:unidade_orcamentaria_id,
				:almoxarifado_de_destino_id,
				:unidade_orcamentaria_de_destino_id,
				:transferir_todos_os_itens,
				:classificacao_tipo_de_material,
				:observacao,
				:data_de_transferencia,
				:orcamento_id,
				:usa_programa,
				:codigo,itens_da_transferencia_attributes: [
					:id,
					:item_id,
					:transferencia_id,
					:quantidade,
					:valor_unitario,
					:marca,
					:total,
					:quantidade_de_conversao,
					:unidade_de_medida_de_conversao_id,
					:saldo_em_quantidade,
					:valor_unitario_conversao,
					:_destroy,
					:estoque_id,
					:quantidade_disponivel,
					:descricao
				],programas_por_almoxarifado_e_transferencia_attributes: [
					:id,
					:almoxarifado_id,
					:transferencia_id,
					:programa_por_escola_id,
					:_destroy
				]
			)
		end

		def itens_da_transferencia_params
			params.require(:gestao_de_estoque_transferencia).permit(
				itens_da_transferencia_attributes: [
					:id,
					:item_id,
					:transferencia_id,
					:quantidade,
					:valor_unitario,
					:marca,
					:total,
					:quantidade_de_conversao,
					:unidade_de_medida_de_conversao_id,
					:saldo_em_quantidade,
					:valor_unitario_conversao,
					:_destroy,
					:estoque_id,
					:quantidade_disponivel,
					:descricao,
					:enviando_ao_almoxarifado_pelo_patrimonio_attribute
				])
		end
	end

end
