# frozen_string_literal: true module Lists class ExperimentsService < BaseService private def fetch_records done_status_id = MyModuleStatusFlow.first.final_status.id @records = @raw_data.joins(:project) .includes(my_modules: { my_module_status: :my_module_status_implications }) .includes(workflowimg_attachment: :blob, user_assignments: %i(user_role user)) .joins('LEFT OUTER JOIN my_modules AS active_tasks ON active_tasks.experiment_id = experiments.id AND active_tasks.archived = FALSE') .joins( ActiveRecord::Base.sanitize_sql_array([ 'LEFT OUTER JOIN my_modules AS active_completed_tasks ON active_completed_tasks.experiment_id = experiments.id AND active_completed_tasks.archived = FALSE AND active_completed_tasks.my_module_status_id = ?', done_status_id ]) ) .readable_by_user(@user) .with_favorites(@user) .select('experiments.*') .select('COUNT(DISTINCT active_tasks.id) AS task_count') .select('COUNT(DISTINCT active_completed_tasks.id) AS completed_task_count') .group('experiments.id') view_mode = if @params[:project].archived? 'archived' else @params[:view_mode] || 'active' end @records = @records.archived if view_mode == 'archived' && @params[:project].active? @records = @records.active if view_mode == 'active' end def filter_records if @params[:search].present? @records = @records.where_attributes_like( ['experiments.name', 'experiments.description', Experiment::PREFIXED_ID_SQL], @params[:search] ) end if @filters[:query].present? @records = @records.where_attributes_like( ['experiments.name', 'experiments.description', Experiment::PREFIXED_ID_SQL], @filters[:query] ) end @records = @records.where('experiments.start_date >= ?', @filters[:start_date_from]) if @filters[:start_date_from].present? @records = @records.where('experiments.start_date <= ?', @filters[:start_date_to]) if @filters[:start_date_to].present? @records = @records.where('experiments.due_date >= ?', @filters[:due_date_from]) if @filters[:due_date_from].present? @records = @records.where('experiments.due_date <= ?', @filters[:due_date_to]) if @filters[:due_date_to].present? @records = @records.where('experiments.updated_at > ?', @filters[:updated_on_from]) if @filters[:updated_on_from].present? if @filters[:updated_on_to].present? @records = @records.where('experiments.updated_at < ?', @filters[:updated_on_to]) end if @filters[:archived_on_from].present? @records = @records.where('COALESCE(experiments.archived_on, projects.archived_on) > ?', @filters[:archived_on_from]) end if @filters[:archived_on_to].present? @records = @records.where('COALESCE(experiments.archived_on, projects.archived_on) < ?', @filters[:archived_on_to]) end if @filters[:statuses].present? scopes = { 'not_started' => @records.not_started, 'in_progress' => @records.in_progress, 'done' => @records.done } selected_scopes = @filters[:statuses].values.filter_map { |status| scopes[status] } @records = selected_scopes.reduce(@records.none, :or) if selected_scopes.any? end end def sortable_columns @sortable_columns ||= { created_at: 'experiments.created_at', name: 'experiments.name', code: 'experiments.id', archived_on: 'archived_on', updated_at: 'experiments.updated_at', completed_tasks: 'completed_task_count', description: 'experiments.description', start_date: 'start_date', due_date: 'due_date', status: 'status', favorite: 'favorite' } end def sort_records return unless @params[:order] && sortable_columns[order_params[:column].to_sym].present? @records = case order_params[:column] when 'archived_on' if order_params[:dir] == 'asc' @records.order(Arel.sql('COALESCE(experiments.archived_on, projects.archived_on) ASC')) .group('experiments.archived_on', 'projects.archived_on') else @records.order(Arel.sql('COALESCE(experiments.archived_on, projects.archived_on) DESC')) .group('experiments.archived_on', 'projects.archived_on') end when 'favorite' @records.order(Arel.sql("favorite #{sort_direction(order_params) == 'ASC' ? 'DESC' : 'ASC'}")) when 'status' @records.order(Arel.sql("CASE WHEN experiments.started_at IS NULL AND experiments.done_at IS NULL THEN -1 WHEN experiments.done_at IS NULL THEN 0 ELSE 1 END #{sort_direction(order_params)}")) else sort_by = "#{sortable_columns[order_params[:column].to_sym]} #{sort_direction(order_params)}" @records.order(sort_by) end @records = @records.order(:id) end end end