survey/app/helpers/surveys_helper.rb

235 lines
7.1 KiB
Ruby

module SurveysHelper
QuestionTypeMap = ['radio','check','title']
QuestionTypeOptionMap = ['radio','check']
SelectableQuestionTypeMap = ['check','radio']
CustomOptionTypeMap = ['for_each_option','new_option']
OptionLayoutTypeMap = ['list_each_option_for_one_line','continuous_list_arrangement']
def self.set_locale(locale)
@locale = locale
@use_custom_option_title = I18n.t('survey_question.use_custom_option')
end
def self.get_locale(locale)
locale = locale || @locale || I18n.locale
if defined?(@locale).nil?
self.set_locale(locale)
end
locale
end
def self.parse_value(answer,locale=nil)
locale = self.get_locale(locale)
tmp = self.parse_exel_value(answer,locale: locale)
tmp[1].nil? ? tmp[0] : "#{tmp[0]}(#{tmp[1]})"
end
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)
end.join(", ")
end
def self.convert_bool_to_exel_value(flag)
flag ? '1' : ''
end
def self.parse_exel_value(answer,xargs)
locale = xargs[:locale]
locale = self.get_locale(locale)
options = xargs[:options]
chart_data = xargs[:chart_data]
use_custom_option = xargs[:use_custom_option]
case answer
when BSON::Document
if options
values = options.collect do |name,id|
flag = (id==answer['oid'])
if flag
chart_data[name] ||= 0
chart_data[name] += 1
end
end
if use_custom_option
values << answer['other']
end
else
values = [answer['value'][locale],answer['other']].compact
end
else
if options
flag = false
if answer.nil?
values = options.map{|name,id| ''}
else
values = options.collect do |name,id|
flag = (name==answer)
if flag
chart_data[name] ||= 0
chart_data[name] += 1
end
convert_bool_to_exel_value(flag)
end
end
if !flag
if use_custom_option
values << answer
end
chart_data[@use_custom_option_title] ||= 0
chart_data[@use_custom_option_title] += 1
elsif use_custom_option
values << ''
end
else
values = [answer]
end
end
values
end
def self.parse_exel_checkbox_value(answers,xargs)
locale = xargs[:locale]
locale = self.get_locale(locale)
options = xargs[:options]
chart_data = xargs[:chart_data]
use_custom_option = xargs[:use_custom_option]
answers = Array(answers)
no_value_flag = true
values = options.collect do |name,id|
flag = false
answers.each_with_index do |answer,i|
case answer
when BSON::Document
flag = (id==answer['oid'])
else
flag = (name==answer)
end
if flag
no_value_flag = false
chart_data[name] ||= 0
chart_data[name] += 1
answers.delete_at(i)
break
end
end
convert_bool_to_exel_value(flag)
end
if use_custom_option
if no_value_flag
chart_data[@use_custom_option_title] ||= 0
chart_data[@use_custom_option_title] += 1
end
values << answers.join(',')
end
values
end
def self.parse_exel_rg_value(answers,xargs)
locale = xargs[:locale]
locale = self.get_locale(locale)
options = xargs[:options]
chart_data = xargs[:chart_data]
use_custom_option = xargs[:use_custom_option]
radiogroups = xargs[:radiogroups]
values = []
options.each do |name,opt_id|
chart_data[opt_id] ||= {}
answer = answers.blank? ? nil : answers[opt_id]
radiogroups.each do |rg_name,rg_id|
flag = (answer.class == BSON::Document && answer['rgid']==rg_id) || (answer == rg_name)
values << self.convert_bool_to_exel_value(flag)
if flag
chart_data[opt_id][rg_name] ||= 0
chart_data[opt_id][rg_name] += 1
end
end
end
if use_custom_option
values << answers["custom_option"].to_s
end
values
end
def self.parse_double_level_value(answer,other_title,locale=nil)
locale = self.get_locale(locale)
case answer
when BSON::Document
level1 = answer['level1'][locale]
level2 = answer['level2'].collect{|v| v[locale]}.join(', ')
other = answer['other'].blank? ? '' : ", #{level1}-#{other_title}: #{answer['other']}"
"#{level1}: #{level2}#{other}"
else
answer
end
end
def self.parse_exel_double_level_value(answers,xargs)
other_title = xargs[:other_title]
use_custom_option = xargs[:use_custom_option]
locale = xargs[:locale]
chart_data = xargs[:chart_data]
locale = self.get_locale(locale)
values = []
custom_option_value = nil
answers.each do |answer|
case answer
when BSON::Document
level1 = answer['level1'][locale]
chart_data[level1] ||= {value: 0,children: {}}
chart_data[level1][:value] += 1
level2 = answer['level2'].collect do |v|
tmp = v[locale]
chart_data[level1][:children][tmp] ||= 0
chart_data[level1][:children][tmp] += 1
tmp
end.join(', ')
other = answer['other'].blank? ? '' : ", #{level1}-#{other_title}: #{answer['other']}"
values << "#{level1}: #{level2}#{other}"
else
custom_option_value = answer
end
end
values = [values.join("\r\n")]
if use_custom_option
chart_data[other_title] ||= {value: 0,children: {}}
chart_data[other_title][:value] += 1
chart_data[other_title][:children][other_title] ||= 0
chart_data[other_title][:children][other_title] += 1
values << custom_option_value
end
values
end
def self.generate_xlsx(id,locale)
def self.remove_illegal_utf8(str)
if String.method_defined?(:encode)
str.encode!('UTF-8', 'UTF-8', :invalid => :replace)
else
ic = Iconv.new('UTF-8', 'UTF-8//IGNORE')
str = ic.iconv(str)
end
str
end
I18n.with_locale(locale) do
survey = QuestionnaireSurvey.find(id)
puts survey.inspect
chart_data, survey_questions, survey_answers = survey.generate_chart_data
ac = ActionController::Base.new()
xlsx = ac.render_to_string handlers: [:axlsx],
formats: [:xlsx],
template: "survey_export/export",
locals: {survey: survey,
survey_questions: survey_questions,
survey_answers: survey_answers,
}
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)
puts 'success'
end
end
end