survey/app/controllers/surveys_controller.rb

350 lines
14 KiB
Ruby

class SurveysController < ApplicationController
helper MemberHelper
def index
questionnairesurveys = QuestionnaireSurvey.any_of( {:postdate.lte => Time.now} ).desc(:postdate).page(OrbitHelper.params[:page_no]).per(OrbitHelper.page_data_count)
current_user = OrbitHelper.current_user
surveys = questionnairesurveys.collect do |a|
answer_present = (current_user.nil? ? false : (a.survey_answers.where(:user => current_user.id).count > 0 ? true : false))
show_link = OrbitHelper.url_to_show(a.to_param)
if !OrbitHelper.params[:page_no].blank?
title = ('<a href="'+ show_link + "?method=show_data&page_no=#{OrbitHelper.params[:page_no]}" + '">' + a.title + '</a>').html_safe
else
title = ('<a href="'+ show_link + '?method=show_data">' + a.title + '</a>').html_safe
end
result = QuestionnaireSurvey.result(a)
if answer_present && a.needs_login
result += "<a href=\"#{show_link + "?method=my_record"}\" class=\"btn btn-primary\" title=\"#{t('survey.my_record')}\">#{t('survey.my_record')}</a>".html_safe
end
{
"title" => title,
"time_range" => QuestionnaireSurvey.time_range(a),
"write" => QuestionnaireSurvey.write(a),
"result" => result,
"answer_present" => answer_present
}
end
{
"surveys" => surveys,
"extras" => {
"widget-title"=>t('survey.survey'),
"th_time_range" => t('survey.time_range'),
"th_title" => t("survey.title"),
"th_write" => t('survey.write'),
"th_result" => t('survey.result')
},
"total_pages" => questionnairesurveys.total_pages
}
end
def my_record
params = OrbitHelper.params
survey = QuestionnaireSurvey.find_by(uid: params[:uid])
current_user = OrbitHelper.current_user
page_no = params[:page_no] ? params[:page_no].to_i : 1
survey_answers = (current_user ? survey.survey_answers.where(:user=>current_user.id).desc(:updated_at).page(page_no).per(10) : [] rescue [])
table_fields = ['survey.taken_by', 'survey.taken_date',"survey.records"]
is_answer_list = true
OrbitHelper.set_page_number(page_no)
{
"survey" => survey,
"user" => current_user,
"survey_answers" => survey_answers,
"table_fields" => table_fields,
"is_answer_list" => is_answer_list
}
end
def show_data
params = OrbitHelper.params
survey = QuestionnaireSurvey.find_by(uid: params[:uid])
current_user = OrbitHelper.current_user
answer_group = (current_user ? survey.survey_answer_groups.where(:user => current_user.id).first : nil rescue nil)
answer_present = (current_user.nil? ? false : (answer_group ? true : false))
answer_present = (!survey.needs_login ? false : answer_present)
link_to_answer_set = (answer_present ? "/admin/surveys/#{answer_group.survey_answer_ids.last.to_s}/answer_set" : "")
link_to_my_record = nil
answer_repeat = survey.get_answer_repeat
if answer_present && answer_present
show_page = (OrbitHelper.page.nil? rescue true) ? Page.where(:page_id=>params["page_id"]).first : OrbitHelper.page
show_page_url = show_page.get_url rescue show_page.url
params[:url] = show_page_url
link_to_my_record = OrbitHelper.url_to_show(survey.to_param) + "?method=my_record"
end
{
'survey' => survey,
'answer_present' => answer_present,
'answer_repeat' => answer_repeat,
'link_to_answer_set' => link_to_answer_set,
'link_to_my_record' => link_to_my_record,
'time_range' => QuestionnaireSurvey.time_range(survey)
}
end
def show
params = OrbitHelper.params
survey = QuestionnaireSurvey.find_by(uid: params[:uid])
if survey.redirect_mode
redirect_url = survey.redirect_url
{
'redirect_url' => redirect_url
}
else
questions = survey.survey_questions.all.entries
current_user = OrbitHelper.current_user
answer_present = (current_user.nil? ? false : (survey.survey_answers.where(:user => current_user.id).count > 0 ? true : false))
answer_present = (!survey.needs_login ? false : answer_present)
link_to_answer_set = (answer_present ? "/admin/surveys/#{survey.survey_answers.where(:user => current_user.id).first.id.to_s}/answer_set" : "")
if survey.jump_mode
answers = Hash[questions.collect{ |o| [o.id.to_s, o.id.to_s] }]
jumpable_questions = questions.select{ |q| q.jumpable? && q.can_set_jump? }
jump_tos_map = jumpable_questions.map(&:get_jump_tos).inject(:merge)
end
show_page = (OrbitHelper.page.nil? rescue true) ? Page.where(:page_id=>params["page_id"]).first : OrbitHelper.page
{
'survey' => survey,
'redirect_url' => '',
'link_to_answer_set' => link_to_answer_set,
'questions' => questions,
'answers' => answers,
'answer_present' => answer_present,
'jump_tos_map' => jump_tos_map,
"show_page_url" => (show_page.get_url rescue show_page.url)
}
end
end
def update
uid = params[:id].split('-').last
@survey = QuestionnaireSurvey.find_by(:uid=>uid)
total = 0
individual_total = []
answer = params[:answer]
@answer_model = @survey.survey_answers.new
@answer_model.user = current_user.id if !current_user.nil?
@answer_model.select_question = answer['select_question'].values.flatten unless answer['select_question'].blank?
@survey.survey_questions.each do |question|
qid = question.id.to_s
weight = (question.weight.nil? ? 1 : question.weight)
if question.selectable_question && @answer_model.select_question.exclude?(qid)
next
end
if question.is_required && answer[qid].blank? && !@survey.jump_mode #&& (! @survey.jump_mode || ( @survey.jump_mode && question.jumpable? ) )
@answer_model.errors.add question.title, t('survey_question.required_error')
else
case question.type
when SurveyQuestion::Radio, SurveyQuestion::Select
if answer[qid] == 'custom_option' && question.custom_option_new_option
@answer_model[qid] = answer[qid + '_custom_option']
else
if answer[qid]
oid = answer[qid]
opt = question.survey_question_options.find(oid)
tmp = {value: opt.name_translations}
tmp['oid'] = oid
if question.custom_option_each_option && !answer["#{qid}_#{answer[qid]}_custom_option"].blank?
tmp['other'] = answer["#{qid}_#{answer[qid]}_custom_option"]
end
@answer_model[qid] = tmp
p = (opt.points.to_i * weight) rescue 0
total = total + p
individual_total << p
end
end
when SurveyQuestion::Check
@answer_model[qid] = []
if answer[qid]
t = 0
answer[qid].each do |oid, value|
if value.to_i != 0
if oid == 'custom_option' && question.custom_option_new_option
@answer_model[qid] << answer[qid + '_custom_option']
else
opt = question.survey_question_options.find(oid)
tmp = {'value' => opt.name_translations}
tmp['oid'] = oid
if question.custom_option_each_option && !answer["#{qid}_#{oid}_custom_option"].blank?
tmp['other'] = answer["#{qid}_#{oid}_custom_option"]
end
@answer_model[qid] << tmp
p = (opt.points.to_i * weight) rescue 0
total = total + p
t = t + p
end
end
end
individual_total << t
end
when SurveyQuestion::Radiogroup
@answer_model[qid] = {}
options = Hash[question.survey_question_options.collect{|o| [ o.id.to_s, (o.points.nil? ? 0 : o.points * weight) ] }]
radiogroups = Hash[question.survey_question_radiogroups.collect{|rg| [ rg.id.to_s, rg.name_translations] }]
if answer[qid]
t = 0
answer[qid].each do |oid, value|
unless value.blank?
@answer_model[qid][oid] = {rgid: value, value: radiogroups[value]}
total = total + options[oid]
t = t + options[oid]
else
if question.is_required
@answer_model.errors.add question.title, t('survey_question.required_error')
end
end
if question.custom_option_each_option
unless answer[oid]["custom_group_field"].blank?
@answer_model[qid]["#{oid}_custom_group_field"] = answer[oid]["custom_group_field"]
end
end
end
individual_total << t
end
if question.custom_option_new_option && !answer[qid+ '_custom_option'].blank?
@answer_model[qid]["custom_option"] = answer[qid+ '_custom_option']
end
when SurveyQuestion::Oneline, SurveyQuestion::Multiline, SurveyQuestion::DateTime
@answer_model[qid] = answer[qid]
individual_total << 0
when SurveyQuestion::DoubleLevelOption
@answer_model[qid] = []
if answer[qid]
t = 0
answer[qid].each do |oid|
if oid == 'custom_option' && question.custom_option_new_option
@answer_model[qid] << answer[qid + '_custom_option']
else
opt = question.survey_question_options.find(oid)
tmp = {'level1' => opt.name_translations}
tmp['level1_id'] = oid
if question.custom_option_each_option && !answer["#{qid}_#{oid}_custom_option"].blank?
tmp['other'] = answer["#{qid}_#{oid}_custom_option"]
end
p = (opt.points.to_i * weight) rescue 0
opt2_names = Array(answer["#{qid}_#{oid}"]).collect do |o2id|
opt2 = opt.level2.find(o2id)
p += opt2.points.to_i * weight
opt2.name_translations
end
tmp['level2'] = opt2_names
tmp['level1_ids'] = Array(answer["#{qid}_#{oid}"])
@answer_model[qid] << tmp
total = total + p
t = t + p
end
end
individual_total << t
end
end
end
end
if @answer_model.errors.empty?
@answer_model.scored_points = total
@answer_model.individual_total = individual_total
@answer_model.consent_used = answer[:consent_used]
if @survey.need_assign_color
tmp_result_criteria = @survey.result_criteria.map{|c| {"q"=>c["questions"].map{|q| q.to_i},"r"=>c["range"].map{|r| r.to_i},"c"=>c["color"].blank? ? '#ffffff' : c["color"],"t"=>c["type"].to_i}}
survey_questions_count = @survey.survey_questions.count
weight_relations = @survey.survey_questions.map{|q| [q.id.to_s,(q.weight.nil? ? 1 : q.weight)]}.to_h
if tmp_result_criteria.select{|criteria| (criteria["q"][0] != 1 || criteria["q"][1] != survey_questions_count rescue true)}.count != 0
answer_model_attrs = answer
tmp_result_criteria.each do |c|
total_weight = 0
range = (c["r"].count != 2 ? [0,100] : c["r"])
questions = c["q"].map{|q| (q == 0 ? 0 : q - 1)}
total = 0
questions.each do |x|
if c["t"] == 1
k = weight_relations.keys[x]
if k && answer_model_attrs.has_key?(k)
total_weight += weight_relations[k]
end
end
total += a.individual_total[x].to_i
end
if c["t"] == 0
if (range[0]..range[1]).cover?(total)
@answer_model.color = c["color"]
break
end
else
avg = (total / total_weight rescue 0)
if (range[0]..range[1]).cover?(avg)
@answer_model.color = c["color"]
break
end
end
end
else
tmp_result_criteria.each do |c|
if (c["r"][0]..c["r"][1]).cover?(@answer_model.scored_points)
@answer_model.color = c["color"]
break
end
end
end
end
@answer_model.save!
show_page = (OrbitHelper.page.nil? rescue true) ? Page.where(:page_id=>params["page_id"]).first : OrbitHelper.page
show_page_url = show_page.get_url rescue show_page.url
params[:url] = show_page_url
OrbitHelper.set_params(params,current_user)
redirect_to OrbitHelper.url_to_show(@survey.to_param) + "?method=answer_success&ans=#{@answer_model.id.to_s}"
else
@survey_answer_error = @answer_model.errors.full_messages.join('\n')
render :answer_error
end
end
def answer_success
params = OrbitHelper.params
survey = QuestionnaireSurvey.find_by(uid: params[:uid])
answer = SurveyAnswer.find(params[:ans])
page = Page.where(:page_id => params[:page_id]).first
{
'survey' => survey,
'answer' => answer,
'url' => "/#{I18n.locale.to_s}" + page.url
}
end
def result
params = OrbitHelper.params
survey = QuestionnaireSurvey.find_by(uid: params[:uid])
# survey.result_type = QuestionnaireSurvey::ResultChart if params[:force_chart]
case survey.result_type
when QuestionnaireSurvey::ResultChart
begin
chart_data, survey_questions, survey_answers = survey.generate_chart_data
rescue => e
puts [e,e.backtrace]
end
end
{
'survey' => survey,
'chart_data' => chart_data,
'survey_questions' => survey_questions,
'survey_answers' => survey_answers
}
end
end