diff --git a/app/assets/javascripts/survey-front-form.js b/app/assets/javascripts/survey-front-form.js index 4c79f1c..5501f6d 100644 --- a/app/assets/javascripts/survey-front-form.js +++ b/app/assets/javascripts/survey-front-form.js @@ -7,14 +7,16 @@ function repeat_string(str,num){ } function set_dot_for_double_level(){ - var width = $('div.o-question').width() - var font_size = parseInt($('.double-level .o-question-option').css('font-size').slice(0,-2)) - $('.double-level tr').each(function(){ - var tr_w = $(this).find('.o-question-option').width()+$(this).find('.level2-list').width() - if (tr_w/width<0.95){ - $('.dot').text(repeat_string('•',(width*0.95-tr_w)/font_size-2)) - } - }) + if($('.double-level .o-question-option').length != 0){ + var width = $('div.o-question').width() + var font_size = parseInt($('.double-level .o-question-option').css('font-size').slice(0,-2)) + $('.double-level tr').each(function(){ + var tr_w = $(this).find('.o-question-option').width()+$(this).find('.level2-list').width() + if (tr_w/width<0.95){ + $('.dot').text(repeat_string('•',(width*0.95-tr_w)/font_size-2)) + } + }) + } } $(function(){ set_dot_for_double_level() diff --git a/app/controllers/admin/surveys_controller.rb b/app/controllers/admin/surveys_controller.rb index f9a5a27..33f8075 100644 --- a/app/controllers/admin/surveys_controller.rb +++ b/app/controllers/admin/surveys_controller.rb @@ -27,8 +27,13 @@ class Admin::SurveysController < OrbitAdminController def answer_sets if can_edit_or_delete?(@survey) - @table_fields = ['survey.taken_by', 'survey.taken_date'] - @survey_answers = @survey.survey_answers.desc(:created_at).page(params[:page]).per(15) + @table_fields = ['survey.taken_by', 'survey.taken_date',"survey.records"] + @survey_answer_groups = @survey.survey_answer_groups.desc(:last_modified).page(params[:page]).per(15) + if params[:search] + match_user_ids = User.where(:id.in=>@survey.survey_answer_groups.pluck(:user),:member_name=>/#{params[:search]}/).pluck(:id) rescue []; + @survey_answer_groups = @survey_answer_groups.where(:user.in=>match_user_ids) + end + @answer_repeat = @survey.get_answer_repeat else render_401 end @@ -38,8 +43,36 @@ class Admin::SurveysController < OrbitAdminController @survey_answer = SurveyAnswer.find(params["id"]) rescue nil @survey = @survey_answer.questionnaire_survey if !@survey_answer.nil? @user = @survey_answer.user.nil? ? nil : (User.find(@survey_answer.user) rescue nil) + #render :html => @survey_answer and return + end + def answer_list + @table_fields = ['survey.taken_by', 'survey.taken_date',"survey.records"] + @survey_answer_group = SurveyAnswerGroup.find(params["id"]) rescue nil + @survey = @survey_answer_group.questionnaire_survey + @survey_answers = @survey_answer_group.survey_answers.desc(:updated_at).page(params[:page]).per(15) + @user = @survey_answer_group.user.nil? ? nil : (User.find(@survey_answer_group.user) rescue nil) + @is_answer_list = true + render "answer_sets" + end + def export_answers + @survey_answer_group = SurveyAnswerGroup.find(params["id"]) rescue nil + @survey = @survey_answer_group.questionnaire_survey + @user = @survey_answer_group.user.nil? ? nil : (User.find(@survey_answer_group.user) rescue nil) + @survey_answers = @survey_answer_group.survey_answers + extra_filename = "_#{@user.member_name rescue nil}" + title = @survey.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'') + f = "public/uploads/survey_export/#{@survey.id}/#{title}#{extra_filename}.xlsx" + File.delete(f) if File.exists?(f) + locale = I18n.locale + Thread.new do + begin + SurveysHelper.generate_xlsx(@survey.id,locale,{:id=>params["id"]},extra_filename) + rescue => e + puts [e,e.backtrace] + end + end + render :json => {"success" => true, "title" => title}.to_json end - def new @survey = QuestionnaireSurvey.new @primary_locale = I18n.locale.to_s @@ -133,11 +166,10 @@ class Admin::SurveysController < OrbitAdminController end def export - I18n.locale = :zh_tw title = @survey.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'') f = "public/uploads/survey_export/#{@survey.id}/#{title}.xlsx" File.delete(f) if File.exists?(f) - I18n.locale = locale + locale = I18n.locale Thread.new do begin SurveysHelper.generate_xlsx(@survey.id,locale) diff --git a/app/controllers/surveys_controller.rb b/app/controllers/surveys_controller.rb index d2b12ef..333aaa2 100644 --- a/app/controllers/surveys_controller.rb +++ b/app/controllers/surveys_controller.rb @@ -36,20 +36,47 @@ class SurveysController < ApplicationController } 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_present = (current_user.nil? ? false : (survey.survey_answers.where(:user => current_user.id).count > 0 ? true : false)) + 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/#{survey.survey_answers.where(:user => current_user.id).first.id.to_s}/answer_set" : "") + 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) } @@ -82,6 +109,7 @@ class SurveysController < ApplicationController 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' => '', @@ -89,7 +117,8 @@ class SurveysController < ApplicationController 'questions' => questions, 'answers' => answers, 'answer_present' => answer_present, - 'jump_tos_map' => jump_tos_map + 'jump_tos_map' => jump_tos_map, + "show_page_url" => (show_page.get_url rescue show_page.url) } end @@ -224,9 +253,11 @@ class SurveysController < ApplicationController @answer_model.scored_points = total @answer_model.individual_total = individual_total @answer_model.save! + params[:url] = params[: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(',') + @survey_answer_error = @answer_model.errors.full_messages.join('\n') render :answer_error end end diff --git a/app/helpers/surveys_helper.rb b/app/helpers/surveys_helper.rb index 665d895..e25bf1d 100644 --- a/app/helpers/surveys_helper.rb +++ b/app/helpers/surveys_helper.rb @@ -26,7 +26,7 @@ module SurveysHelper def self.parse_checkbox_value_html(answer,locale=nil) locale = self.get_locale(locale) Array(answer).collect do |v| - self.parse_value(v['value'],locale) + self.parse_value(v,locale) end.join(", ") end @@ -54,7 +54,7 @@ module SurveysHelper values << answer['other'] end else - values = [answer['value'][locale],answer['other']].compact + values = [(answer['value'][locale] rescue nil),answer['other']].compact end else if options @@ -201,7 +201,7 @@ module SurveysHelper values end - def self.generate_xlsx(id,locale) + def self.generate_xlsx(id,locale,match_args={},extra_filename="") def self.remove_illegal_utf8(str) if String.method_defined?(:encode) str.encode!('UTF-8', 'UTF-8', :invalid => :replace) @@ -214,7 +214,7 @@ module SurveysHelper I18n.with_locale(locale) do survey = QuestionnaireSurvey.find(id) puts survey.inspect - chart_data, survey_questions, survey_answers = survey.generate_chart_data + chart_data, survey_questions, survey_answers = survey.generate_chart_data(match_args) ac = ActionController::Base.new() xlsx = ac.render_to_string handlers: [:axlsx], formats: [:xlsx], @@ -225,10 +225,11 @@ module SurveysHelper } dirname = "public/uploads/survey_export/#{id}" FileUtils.mkdir_p(dirname) unless File.exists?(dirname) - f = "#{dirname}/#{survey.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'')}.xlsx" - file = File.open(f, "w") - xlsx.force_encoding("utf-8") - file.write(xlsx) + f = "#{dirname}/#{survey.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'')}#{extra_filename}.xlsx" + File.open(f, "w+") do |file| + xlsx.force_encoding("utf-8") + file.write(xlsx) + end puts 'success' end end diff --git a/app/models/questionnaire_survey.rb b/app/models/questionnaire_survey.rb index 469be20..82b07e8 100644 --- a/app/models/questionnaire_survey.rb +++ b/app/models/questionnaire_survey.rb @@ -12,7 +12,7 @@ class QuestionnaireSurvey include OrbitCategory::Categorizable scope :can_display, ->{where(is_hidden: false)} - + field :already_fix_data, :type => Boolean, :default => false field :copy_id field :except_clone_relations, :type=>Array, :default => [] field :title, as: :slug_title, type: String, localize: true @@ -26,6 +26,7 @@ class QuestionnaireSurvey field :is_hidden, :type => Boolean, :default => false field :needs_login, :type => Boolean, :default => false + field :answer_repeat, :type => Boolean, :default => false field :total_points, type: Integer, :default => 0 field :result_type, :type => Integer, :default => 0 @@ -43,6 +44,7 @@ class QuestionnaireSurvey has_many :survey_questions, :autosave => true, :dependent => :destroy has_many :survey_answers, :autosave => true, :dependent => :destroy + has_many :survey_answer_groups, :autosave => true, :dependent => :destroy has_many :survey_sections, :autosave => true, :dependent => :destroy accepts_nested_attributes_for :survey_questions, :allow_destroy => true @@ -52,12 +54,16 @@ class QuestionnaireSurvey has_many :survey_paginations, :autosave => true, :dependent => :destroy accepts_nested_attributes_for :survey_paginations, :allow_destroy => true before_create do + self.already_fix_data = true if self.copy_id.present? clone_new(true) self.created_at = DateTime.now self.updated_at = DateTime.now end end + def get_answer_repeat + self.needs_login && self.answer_repeat + end def update_user User.find(update_user_id) rescue nil end @@ -97,13 +103,22 @@ class QuestionnaireSurvey end end - def generate_chart_data + def generate_chart_data(match_args={}) survey_questions = self.survey_questions.all - survey_answers = self.survey_answers.all.order_by(created_at: :desc) - + tmp_answer_repeat = self.needs_login && self.answer_repeat + survey_answers = [] + if tmp_answer_repeat + survey_answers = self.survey_answers.where(match_args).order_by(created_at: :desc) + else + survey_answer_ids = self.survey_answer_groups.where(match_args).pluck(:survey_answer_ids).map{|ids| ids ? ids[-1] : nil} + survey_answers = self.survey_answers.where(:id.in=>survey_answer_ids).order_by(created_at: :desc) + end + survey_answers = survey_answers.to_a chart_data = {} answers =(0...survey_answers.count).map{{}} - + survey_answers.each_with_index do |answer,i| + answers[i]["name"] = User.find(answer.user).member_name rescue "" + end SurveysHelper.set_locale(I18n.locale) survey_questions.each do |question| qid = question.id.to_s diff --git a/app/models/survey_answer.rb b/app/models/survey_answer.rb index a88d9d7..58d792e 100644 --- a/app/models/survey_answer.rb +++ b/app/models/survey_answer.rb @@ -8,5 +8,33 @@ class SurveyAnswer field :individual_total, type: Array, :default => [] field :select_question, type: Array, :default => [] belongs_to :questionnaire_survey - + after_create do + if self.questionnaire_survey + answer_group = SurveyAnswerGroup.where(:questionnaire_survey_id=>self.questionnaire_survey.id,:user=>user).first + if answer_group.nil? + answer_group = SurveyAnswerGroup.new(:questionnaire_survey_id=>self.questionnaire_survey.id,:user=>user_id) + end + answer_group.last_modified = self.updated_at + answer_group.survey_answer_ids << self.id + answer_group.save + end + end + after_save do + answer_group = SurveyAnswerGroup.where(:questionnaire_survey_id=>self.questionnaire_survey.id,:user=>user).first + if answer_group + answer_group.last_modified = self.updated_at + answer_group.save + end + end + before_destroy do + answer_group = SurveyAnswerGroup.where(:user=>user).first + if answer_group + answer_group.survey_answer_ids.delete(self.id) + if answer_group.survey_answer_ids.count == 0 + answer_group.destroy + else + answer_group.save + end + 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 new file mode 100644 index 0000000..90074b5 --- /dev/null +++ b/app/models/survey_answer_group.rb @@ -0,0 +1,10 @@ +class SurveyAnswerGroup + include Mongoid::Document + field :user, type: BSON::ObjectId + field :survey_answer_ids, type: Array, default: [] + field :last_modified, type: Time, default: Time.now + belongs_to :questionnaire_survey + def survey_answers + SurveyAnswer.where(:id.in=>survey_answer_ids) + end +end \ No newline at end of file diff --git a/app/models/survey_question_option.rb b/app/models/survey_question_option.rb index 0908bdc..e9748f7 100644 --- a/app/models/survey_question_option.rb +++ b/app/models/survey_question_option.rb @@ -1,7 +1,7 @@ class SurveyQuestionOption include Mongoid::Document - field :name, :localize => true + field :name, :localize => true, :type => String field :jump_to, :default => 0 field :points, :type => Integer, :default => 0 field :question_type, :type => Integer, :default => 0 diff --git a/app/views/admin/surveys/_form.html.erb b/app/views/admin/surveys/_form.html.erb index 0642691..c153820 100644 --- a/app/views/admin/surveys/_form.html.erb +++ b/app/views/admin/surveys/_form.html.erb @@ -96,6 +96,14 @@ +
+ <%= f.label :answer_repeat, t("survey.same_user_can_answer_repeatedly"), :class=>"control-label muted" %> +
+ +
+
@@ -135,4 +143,7 @@ \ No newline at end of file diff --git a/app/views/admin/surveys/_index.html.erb b/app/views/admin/surveys/_index.html.erb index 072d720..7137f16 100644 --- a/app/views/admin/surveys/_index.html.erb +++ b/app/views/admin/surveys/_index.html.erb @@ -41,7 +41,7 @@ <%= (survey.postdate) ? (format_value survey.postdate) : t(:no_deadline) %> <%= (survey.deadline) ? (format_value survey.deadline) : t(:no_deadline) %> - <%= survey.survey_answers.count %> + <%= survey.survey_answer_groups.count %> <%# if survey.needs_login %> <%# else %> diff --git a/app/views/admin/surveys/answer_set.html.erb b/app/views/admin/surveys/answer_set.html.erb index f894bf2..d55fc88 100644 --- a/app/views/admin/surveys/answer_set.html.erb +++ b/app/views/admin/surveys/answer_set.html.erb @@ -61,9 +61,10 @@
A <% case sq.type %> - <% when SurveyQuestion::Radio, SurveyQuestion::Select %> + <% when SurveyQuestion::Radio, SurveyQuestion::Select %> <%= SurveysHelper.parse_value(@survey_answer[sq.id.to_s]) %> <% when SurveyQuestion::Check %> + <% puts sq.id %> <%= SurveysHelper.parse_checkbox_value_html(@survey_answer[sq.id.to_s]) %> <% when SurveyQuestion::Radiogroup %>
diff --git a/app/views/admin/surveys/answer_sets.html.erb b/app/views/admin/surveys/answer_sets.html.erb index ac0da0b..6e9508d 100644 --- a/app/views/admin/surveys/answer_sets.html.erb +++ b/app/views/admin/surveys/answer_sets.html.erb @@ -1,30 +1,131 @@ + + +

<%= @survey.title %>

+
+ <% if @is_answer_list %> +

<%=t('survey.taken_by')%>: <%=@user.member_name%>

+ <% else %> + + <% end %> +
<% @table_fields.each do |f| %> <%= thead(f) %> <% end %> - - <% @survey_answers.each do |sa| %> + <% (@survey_answer_groups || @survey_answers).each do |sa| %> <% user = sa.user.nil? ? nil : (User.find(sa.user) rescue nil) %> <% if !user.nil? %> - + <% else %> <% end %> - - + + <% end %>
<%= user.name %><%= user.member_name rescue user.name %>NA<%= sa.created_at.strftime("%h %d, %Y - %H:%M") rescue nil %><%= t("survey.view_answers") %><%= (@is_answer_list ? sa.updated_at : sa.last_modified).strftime("%h %d, %Y - %H:%M") rescue nil %> + <% if @answer_repeat && !@is_answer_list %> + <%= t("survey.view") %>(<%=sa.survey_answer_ids.count%>) + + <% else %> + <%= t("survey.view_answers") %> + <% end %> +
<%= content_tag :div, class: "bottomnav clearfix" do - content_tag :div, paginate(@survey_answers), class: "pagination pagination-centered" + content_tag :div, paginate((@survey_answer_groups || @survey_answers)), class: "pagination pagination-centered" end -%> \ No newline at end of file +%> + \ No newline at end of file diff --git a/app/views/survey_export/export.xlsx.axlsx b/app/views/survey_export/export.xlsx.axlsx index cd7e2f3..75a4919 100644 --- a/app/views/survey_export/export.xlsx.axlsx +++ b/app/views/survey_export/export.xlsx.axlsx @@ -1,29 +1,42 @@ # encoding: utf-8 - +require 'axlsx' wb = xlsx_package.workbook -wb.add_worksheet(name: "WorkSheet1") do |sheet| - - row = [] +title = survey.title +title = "WorkSheet1" if title.blank? +wb.add_worksheet(name: title) do |sheet| + row = [I18n.t("survey.taken_by")] + row2 = [""] survey_questions.each_with_index do |question, i| - if question.type == 2 or question.type == 3 or question.type == 4 + qnum = question.title.match(/^\d+./).nil? ? "#{i+1}. " : "" + start_col = row2.count + if question.type == 2 or question.type == 3 or question.type == 4 + col_size = question.survey_question_options.count - 1 + sheet.merge_cells "#{Axlsx::cell_r(start_col,0)}:#{Axlsx::cell_r(start_col+col_size,0)}" question.survey_question_options.each do |option| - row << "#{i+1}. #{question.title} - #{option.name}" + row << "#{qnum}#{question.title}" + row2 << "#{option.name}" end elsif question.type == 5 + col_size = question.survey_question_options.count * question.survey_question_radiogroups.count - 1 + sheet.merge_cells "#{Axlsx::cell_r(start_col,0)}:#{Axlsx::cell_r(start_col+col_size,0)}" question.survey_question_options.each do |option| question.survey_question_radiogroups.each do |radiogroup| - row << "#{i+1}. #{question.title} - #{option.name} - #{radiogroup.name}" + row << "#{qnum}#{question.title}" + row2 << "#{option.name} - #{radiogroup.name}" end end else - row << "#{i+1}. #{question.title}" + row << "#{qnum}#{question.title}" + row2 << "" end if question.custom_option_new_option - row << "#{i+1}. #{question.title} - #{t('survey_question.use_custom_option')}" + row << "#{qnum}#{question.title}" + row2 << "#{t('survey_question.use_custom_option')}" end end sheet.add_row row + sheet.add_row row2 wrap = wb.styles.add_style alignment: {wrap_text: true} survey_answers.each do |answer| answer_row = [] diff --git a/app/views/surveys/my_record.html.erb b/app/views/surveys/my_record.html.erb new file mode 100644 index 0000000..0c6a382 --- /dev/null +++ b/app/views/surveys/my_record.html.erb @@ -0,0 +1,63 @@ +<% + data = action_data + @survey = data["survey"] + @user = data["user"] + @survey_answers = data["survey_answers"] + @table_fields = data["table_fields"] + @is_answer_list = data["is_answer_list"] +%> +<% if @user.nil? %> +

"><%=t("survey.please_login_first")%>

+ +<% else %> + +

<%= @survey.title %>

+
+

<%=t('survey.taken_by')%>: <%=@user.member_name%>

+
+ + + + <% @table_fields.each do |f| %> + <%= thead(f) %> + <% end %> + + + + <% (@survey_answer_groups || @survey_answers).each do |sa| %> + + <% user = sa.user.nil? ? nil : (User.find(sa.user) rescue nil) %> + <% if !user.nil? %> + + <% else %> + + <% end %> + + + + <% end %> + +
<%= user.member_name rescue user.name %>NA<%= (@is_answer_list ? sa.updated_at : sa.last_modified).strftime("%h %d, %Y - %H:%M") rescue nil %> + <% if @answer_repeat && !@is_answer_list %> + "><%= t("survey.view") %>(<%=sa.survey_answer_ids.count%>) + + <% else %> + "><%= t("survey.view_answers") %> + <% end %> +
+ <%= create_pagination((@survey_answer_groups || @survey_answers).total_pages).html_safe %> +<% end %> \ No newline at end of file diff --git a/app/views/surveys/show.html.erb b/app/views/surveys/show.html.erb index 1a8b49b..55c450f 100644 --- a/app/views/surveys/show.html.erb +++ b/app/views/surveys/show.html.erb @@ -33,8 +33,12 @@ s = qnums.index(-1) e = @questions.count len = e-s - qnum_start = qnums[0...s].compact[-1] + 1 - qnums[s,len] = (qnum_start...(qnum_start+len)).to_a + qnum_start = qnums[0...s].compact[-1] + 1 rescue nil + if qnum_start + qnums[s,len] = (qnum_start...(qnum_start+len)).to_a + else + qnums[s,len] = (s+1..s+len).to_a + end end headers = @survey.survey_sections.pluck(:start_question) footers = @survey.survey_sections.pluck(:end_question) @@ -46,9 +50,9 @@ section_index = "[other]" pagination_index = 0 qnum = 0 + show_page_url = data["show_page_url"] %> - <% if @survey.needs_login && current_user.nil? %>