diff --git a/app/assets/javascripts/survey.js b/app/assets/javascripts/survey.js index 1c20029..9691e5a 100644 --- a/app/assets/javascripts/survey.js +++ b/app/assets/javascripts/survey.js @@ -32,6 +32,7 @@ function setData(l, length, optionsI, className) { _title_translations: [id+l+"_title_translations", name+l+"][title_translations]", "questions_title_"+l,{"en":"","zh_tw":""}], _description_translations: [id+l+"_description_translations", name+l+"][description_translations]", "questions_depiction_"+l,{"en":"","zh_tw":""}], _type: [id+l+"_type", name+l+"][type]"], + _weight: [id+l+"_weight", name+l+"][weight]", 1], _selectable_question: [name+l+"][selectable_question]", ''], _selectable_question_type: [name+l+"][selectable_question_type]",''], _question_type: [question_type_name,'',String(question_type_name).replaceAll(/\[|\]/g,'')], @@ -73,6 +74,7 @@ function setEditData(l, length, d, optionsI, className) { _title_translations: [id+l+"_title_translations", name+l+"][title_translations]", "questions_title_"+l,d.title_translations], _description_translations: [id+l+"_description_translations", name+l+"][description_translations]", "questions_depiction_"+l,d.description_translations], _type: [id+l+"_type", name+l+"][type]",d.type], + _weight: [id+l+"_weight", name+l+"][weight]", d.weight], _selectable_question: [name+l+"][selectable_question]", d.selectable_question], _selectable_question_type: [name+l+"][selectable_question_type]",d.selectable_question_type], _question_type: [name+l+"][question_type]",d.question_type,String(name+l+"][question_type]").replaceAll(/\[|\]/g,'')], @@ -213,10 +215,13 @@ function onQuestionTypeChanged ( $fieldType, _val ){ if(_val < 2) { $fieldType.fadeOut(300); $fieldType.next(".date-format").fadeOut(300); + $fieldType.siblings(".weight_block").addClass("hide"); }else if(_val == 6){ $fieldType.fadeOut(300); $fieldType.next(".date-format").fadeIn(300); + $fieldType.siblings(".weight_block").addClass("hide"); } else { + $fieldType.siblings(".weight_block").removeClass("hide"); $fieldType.fadeIn(300); $fieldType.next(".date-format").fadeOut(300); if (_val == 7){ diff --git a/app/controllers/admin/surveys_controller.rb b/app/controllers/admin/surveys_controller.rb index 33f8075..e12db27 100644 --- a/app/controllers/admin/surveys_controller.rb +++ b/app/controllers/admin/surveys_controller.rb @@ -94,6 +94,7 @@ class Admin::SurveysController < OrbitAdminController respond_to do |format| if @survey.save + @survey.update_total_weight format.html { redirect_to(admin_surveys_path) } format.xml { render :xml => @survey, :status => :created, :location => @survey } else @@ -124,6 +125,8 @@ class Admin::SurveysController < OrbitAdminController @survey.total_points = total respond_to do |format| if @survey.update_attributes(survey_params) + @survey.update_answer_score + @survey.update_total_weight if params[:et] == "result" format.html { redirect_to(set_answers_admin_survey_path(@survey.id)) } else diff --git a/app/controllers/surveys_controller.rb b/app/controllers/surveys_controller.rb index 53caee4..efc8b8c 100644 --- a/app/controllers/surveys_controller.rb +++ b/app/controllers/surveys_controller.rb @@ -141,6 +141,7 @@ class SurveysController < ApplicationController @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 @@ -161,7 +162,7 @@ class SurveysController < ApplicationController tmp['other'] = answer["#{qid}_#{answer[qid]}_custom_option"] end @answer_model[qid] = tmp - p = (opt.points == nil ? 0 : opt.points) rescue 0 + p = (opt.points.to_i * weight) rescue 0 total = total + p individual_total << p end @@ -182,7 +183,7 @@ class SurveysController < ApplicationController tmp['other'] = answer["#{qid}_#{oid}_custom_option"] end @answer_model[qid] << tmp - p = (opt.points == nil ? 0 : opt.points) rescue 0 + p = (opt.points.to_i * weight) rescue 0 total = total + p t = t + p end @@ -192,7 +193,7 @@ class SurveysController < ApplicationController 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) ] }] + 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 @@ -234,10 +235,10 @@ class SurveysController < ApplicationController if question.custom_option_each_option && !answer["#{qid}_#{oid}_custom_option"].blank? tmp['other'] = answer["#{qid}_#{oid}_custom_option"] end - p = (opt.points == nil ? 0 : opt.points) rescue 0 + 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 + p += opt2.points.to_i * weight opt2.name_translations end tmp['level2'] = opt2_names diff --git a/app/models/questionnaire_survey.rb b/app/models/questionnaire_survey.rb index 82b07e8..499018e 100644 --- a/app/models/questionnaire_survey.rb +++ b/app/models/questionnaire_survey.rb @@ -28,7 +28,7 @@ class QuestionnaireSurvey field :needs_login, :type => Boolean, :default => false field :answer_repeat, :type => Boolean, :default => false field :total_points, type: Integer, :default => 0 - + field :total_weight, type: Integer field :result_type, :type => Integer, :default => 0 field :extern_link mount_uploader :upload_file, AssetUploader @@ -373,6 +373,123 @@ class QuestionnaireSurvey return new_object, clone_target end end + def update_answer_score + if self.survey_questions.where(:need_update_score => true).count != 0 + puts "Updating answer's scores" + tmp_weights = [] + tmp_score_data = self.survey_questions.map do |question| + qid = question.id.to_s + tmp = {} + weight = (question.weight.nil? ? 1 : question.weight) + tmp_weights << weight + case question.type + when SurveyQuestion::Radio, SurveyQuestion::Select, SurveyQuestion::Check, SurveyQuestion::Radiogroup + question.survey_question_options.each do |opt| + oid = opt.id.to_s + tmp[oid] = {"base"=>(opt.points.to_i * weight)} + end + when SurveyQuestion::Oneline, SurveyQuestion::Multiline, SurveyQuestion::DateTime + tmp = 0 + when SurveyQuestion::DoubleLevelOption + question.survey_question_options.each do |opt| + oid = opt.id.to_s + tmp[oid] = {"base"=>(opt.points.to_i * weight)} + opt.level2.each do |opt2| + tmp[oid][opt2.id.to_s] = opt2.points.to_i * weight + end + end + end + [qid,tmp] + end.to_h + self.survey_answers.each do |answer| + total = 0 + individual_total = [] + tmp_total_weight = 0 + tmp_score_data.each_with_index do |(qid,tmp),i| + if answer[qid] + tmp_total_weight += tmp_weights[i] + if tmp.class == Fixnum #Oneline, Multiline, DateTime + total += tmp + individual_total << tmp + else + if answer[qid].class == Array #Check , DoubleLevelOption + t = 0 + answer[qid].each do |d| + if d.class != BSON::Document + break + end + level2s = [] + oid = nil + if d.has_key?("level1_id") + oid = d["level1_id"] + level2s = Array(d["level1_ids"]) + else + oid = d['oid'] + end + t2 += tmp[oid]["base"] rescue nil + if t2 + t += t2 + level2s.each do |level2_id| + t += tmp[oid][level2_id] + end + end + end + total += t + individual_total << t + elsif answer[qid].class == BSON::Document #Radio, Select, Radiogroup + if (answer[qid].has_key?('oid') rescue true) + t = tmp[answer[qid]['oid']]["base"] rescue nil + if t + total += t + individual_total << t + end + else + tmp[answer[qid]].each do |oid,d| + t = tmp[oid]["base"] rescue nil + if t + total += t + individual_total << t + end + end + end + else + total += 0 + individual_total << 0 + end + end + else + total += 0 + individual_total << 0 + end + end + answer.scored_points = total + answer.individual_total = individual_total + if tmp_total_weight != 0 + answer.avg_points = (individual_total.to_f / tmp_total_weight).round + else + answer.avg_points = 0 + end + answer.save + end + self.survey_questions.update_all(:need_update_score => false) + end + end + def update_total_weight + self.total_weight = self.survey_questions.pluck(:weight).map{|w| w.nil? ? 1 : w}.sum + self.save + end + def get_total_weight(ans=nil) + if ans.nil? + if self.total_weight.nil? + self.update_total_weight + self.total_weight + else + self.total_weight + end + else + self.survey_questions.where(:id.in=>ans.attributes.keys).pluck(:weight).map{|w| w.nil? ? 1 : w}.sum + end + end protected def check_deadline @@ -380,7 +497,6 @@ class QuestionnaireSurvey self.deadline = nil end end - # def update_avliable_language # VALID_LOCALES.each do |locale| # if (title_translations[locale].blank? rescue true) diff --git a/app/models/survey_answer.rb b/app/models/survey_answer.rb index 73f00e1..6d8f276 100644 --- a/app/models/survey_answer.rb +++ b/app/models/survey_answer.rb @@ -5,6 +5,7 @@ class SurveyAnswer field :user, type: BSON::ObjectId field :scored_points, type: Integer, :default => 0 + field :avg_points, type: Integer field :individual_total, type: Array, :default => [] field :select_question, type: Array, :default => [] belongs_to :questionnaire_survey @@ -41,4 +42,14 @@ class SurveyAnswer end end end + def get_avg_points + if self.avg_points.nil? + total_weight = self.questionnaire_survey.get_total_weight(self) + self.avg_points = (scored_points.to_f / total_weight).round + self.save + self.avg_points + else + self.avg_points + end + end end \ No newline at end of file diff --git a/app/models/survey_answer_group.rb b/app/models/survey_answer_group.rb index 90074b5..d9e03ac 100644 --- a/app/models/survey_answer_group.rb +++ b/app/models/survey_answer_group.rb @@ -7,4 +7,7 @@ class SurveyAnswerGroup def survey_answers SurveyAnswer.where(:id.in=>survey_answer_ids) end + after_destroy do + SurveyAnswer.where(:id.in=>survey_answer_ids).destroy + end end \ No newline at end of file diff --git a/app/models/survey_question.rb b/app/models/survey_question.rb index 031f48e..66207c8 100644 --- a/app/models/survey_question.rb +++ b/app/models/survey_question.rb @@ -11,7 +11,8 @@ class SurveyQuestion include Mongoid::Document include Mongoid::Attributes::Dynamic - + field :need_update_score, :type => Boolean, :default => false + field :weight, :type => Integer, :default => 1 field :title, :localize => true field :description, :localize => true field :is_required, :type => Boolean @@ -43,6 +44,9 @@ class SurveyQuestion before_save do self.custom_option_type = self.custom_option_type.map(&:to_i) + if self.weight_changed? || (self.survey_question_options.select{|opt| opt.points_changed? || (opt.level2.select{|sub_opt| sub_opt.points_changed?}.count != 0)}.count != 0) + self.need_update_score = true + end end def jumpable? diff --git a/app/views/admin/surveys/_questions.html.erb b/app/views/admin/surveys/_questions.html.erb index 977f43f..1579f98 100644 --- a/app/views/admin/surveys/_questions.html.erb +++ b/app/views/admin/surveys/_questions.html.erb @@ -49,6 +49,12 @@ +