395 lines
12 KiB
Ruby
395 lines
12 KiB
Ruby
class Panel::Survey::BackEnd::SurveysController < OrbitBackendController
|
|
|
|
require 'csv'
|
|
require 'iconv'
|
|
require 'roo'
|
|
|
|
include AdminHelper
|
|
include OrbitControllerLib::DivisionForDisable
|
|
|
|
def initialize
|
|
super
|
|
@app_title = 'survey'
|
|
end
|
|
|
|
def index
|
|
@surveys = (params[:sort]) ? get_sorted_and_filtered("survey") : get_viewable("survey")
|
|
|
|
respond_to do |format|
|
|
format.html # index.html.erb
|
|
format.xml { render :xml => @qas }
|
|
format.js
|
|
end
|
|
end
|
|
|
|
def new
|
|
@survey = ::Survey.new
|
|
@primary_locale = I18n.locale.to_s
|
|
@secondary_locale = (I18n.locale == :zh_tw) ? "en" : "zh_tw"
|
|
|
|
respond_to do |format|
|
|
format.html # new.html.erb
|
|
format.xml { render :xml => @survey }
|
|
end
|
|
end
|
|
|
|
def create
|
|
@survey = ::Survey.new(params[:survey])
|
|
|
|
@survey.create_user_id = current_user.id
|
|
@survey.update_user_id = current_user.id
|
|
|
|
respond_to do |format|
|
|
if @survey.save
|
|
format.html { redirect_to(panel_survey_back_end_surveys_url) }
|
|
format.xml { render :xml => @survey, :status => :created, :location => @survey }
|
|
else
|
|
format.html { render :action => "new" }
|
|
format.xml { render :xml => @survey.errors, :status => :unprocessable_entity }
|
|
end
|
|
end
|
|
end
|
|
|
|
def edit
|
|
@primary_locale = I18n.locale.to_s
|
|
@secondary_locale = (I18n.locale == :zh_tw) ? "en" : "zh_tw"
|
|
@survey = ::Survey.find(params[:id])
|
|
@sqs = []
|
|
@survey.survey_questions.each do |sq|
|
|
sq['title_translations'] = sq.title_translations
|
|
sq['description_translations'] = sq.description_translations
|
|
temp = []
|
|
sq.survey_question_options.each do |sqo|
|
|
sqo['name_translations'] = sqo.name_translations
|
|
temp << sqo
|
|
end
|
|
temp = []
|
|
sq.survey_question_radiogroups.each do |sqr|
|
|
sqr['name_translations'] = sqr.name_translations
|
|
temp << sqr
|
|
end
|
|
sq.survey_question_radiogroups = temp
|
|
@sqs << sq
|
|
end
|
|
end
|
|
|
|
def update
|
|
@survey = ::Survey.find(params[:id])
|
|
@survey.update_user_id = current_user.id
|
|
|
|
respond_to do |format|
|
|
if @survey.update_attributes(params[:survey])
|
|
format.html { redirect_to(panel_survey_back_end_surveys_url(:page => params[:page])) }
|
|
format.xml { head :ok }
|
|
else
|
|
format.html { render :action => "edit" }
|
|
format.xml { render :xml => @survey.errors, :status => :unprocessable_entity }
|
|
end
|
|
end
|
|
end
|
|
|
|
def destroy
|
|
@survey = ::Survey.find(params[:id])
|
|
|
|
@survey.destroy
|
|
|
|
respond_to do |format|
|
|
|
|
format.html { redirect_to(panel_survey_back_end_surveys_url) }
|
|
format.js
|
|
end
|
|
end
|
|
|
|
def delete
|
|
if params[:ids]
|
|
surveys = ::Survey.any_in(:_id => params[:ids]).destroy_all
|
|
end
|
|
redirect_to panel_survey_back_end_surveys_url(:direction => params[:direction], :sort => params[:sort], :sort_options => params[:sort_options])
|
|
end
|
|
|
|
def set_import
|
|
@survey = ::Survey.find(params[:id])
|
|
end
|
|
|
|
def import
|
|
@survey = ::Survey.find(params[:id])
|
|
@chart_data, @survey_questions, @survey_answers = @survey.generate_chart_data
|
|
@file = params[:file]
|
|
|
|
case File.extname(@file.original_filename)
|
|
when ".csv" then @spreadsheet = Roo::CSV.new(@file.path, csv_options: {encoding: Encoding::Big5})
|
|
# when ".xls" then Excel.new(file.path, nil, :ignore)
|
|
# when ".xlsx" then Excelx.new(file.path, nil, :ignore)
|
|
else raise "Unknown file type: #{file.original_filename}"
|
|
end
|
|
|
|
# Modify titles if changed
|
|
titles = @spreadsheet.row(1) - [" "]
|
|
@survey_questions.each_with_index do |question, index|
|
|
question.update_attributes(title: titles[index])
|
|
end
|
|
|
|
@survey_answers.destroy
|
|
|
|
# Start and end of speadsheet
|
|
@end_row = @spreadsheet.count
|
|
|
|
@max_row_start = 0
|
|
@survey_questions.each do |question|
|
|
case question.type
|
|
when ::SurveyQuestion::Radio, ::SurveyQuestion::Select, ::SurveyQuestion::Check
|
|
if question.survey_question_options.count > @max_row_start
|
|
@max_row_start = question.survey_question_options.count
|
|
end
|
|
when ::SurveyQuestion::Radiogroup
|
|
if question.survey_question_options.count * question.survey_question_radiogroups.count > @max_row_start
|
|
@max_row_start = question.survey_question_options.count * question.survey_question_radiogroups.count
|
|
end
|
|
end
|
|
end
|
|
@start_row = @max_row_start + 2
|
|
|
|
# Modify multiline options if changed
|
|
(@start_row..@end_row).each do |row|
|
|
@answer_model = @survey.survey_answers.new
|
|
@survey_questions.each_with_index do |question, index|
|
|
case question.type
|
|
|
|
when ::SurveyQuestion::Oneline, ::SurveyQuestion::Multiline
|
|
@answer_model[question.id.to_s] = @spreadsheet.row(row)[index * 2]
|
|
|
|
when ::SurveyQuestion::Radio, ::SurveyQuestion::Select
|
|
if !@spreadsheet.row(row)[index*2].nil? && @spreadsheet.row(row)[index*2] != " "
|
|
@answer_model[question.id.to_s] = @spreadsheet.row(row)[index*2]
|
|
end
|
|
|
|
when ::SurveyQuestion::Check
|
|
if !@spreadsheet.row(row)[index*2].nil? && @spreadsheet.row(row)[index*2] != " "
|
|
@answer_model[question.id.to_s] = @spreadsheet.row(row)[index*2].split("\"").select.each_with_index { |str, i| i.odd? }
|
|
end
|
|
|
|
when ::SurveyQuestion::Radiogroup
|
|
radio_groups = []
|
|
spreadsheet_radiogroups_lines =
|
|
question.survey_question_options.count * question.survey_question_radiogroups.count + 2
|
|
|
|
# Grab each radiogroups line for update
|
|
(2...spreadsheet_radiogroups_lines).each do |line|
|
|
radio_groups << @spreadsheet.row(line)[index * 2]
|
|
end
|
|
|
|
# Grab answers info
|
|
answers = []
|
|
if not @spreadsheet.row(row)[index * 2].blank?
|
|
answers << eval(@spreadsheet.row(row)[index * 2])
|
|
end
|
|
|
|
# Save the answers
|
|
answers.each do |answer|
|
|
options = Hash[question.survey_question_options.collect { |o| [ o.id.to_s, o.name ] }]
|
|
# @answer_model = @survey.survey_answers.new
|
|
@answer_model[question.id.to_s] = {}
|
|
|
|
answer.each do |option, value|
|
|
@answer_model[question.id.to_s][options.invert[option]] = value
|
|
end
|
|
|
|
# @answer_model.save!
|
|
end
|
|
|
|
# Parse the needed info in the array
|
|
radio_titles = []
|
|
radio_options = []
|
|
radio_groups.each do |group|
|
|
option_with_radio = group.split(' - ')
|
|
radio_titles << option_with_radio[0]
|
|
radio_options << option_with_radio[1]
|
|
end
|
|
|
|
# Update the spreadsheet info to the DB
|
|
groups_of_options = []
|
|
groups_of_radios = []
|
|
radio_titles.each_slice(question.survey_question_radiogroups.count) do |options|
|
|
groups_of_options << options
|
|
end
|
|
|
|
radio_options.each_slice(question.survey_question_radiogroups.count) do |options|
|
|
groups_of_radios << options
|
|
end
|
|
|
|
# Update option names
|
|
question.survey_question_options.each_with_index do |option, index|
|
|
groups_of_options[index].each do |modified_option|
|
|
if option.name_translations["zh_tw"] != modified_option
|
|
option.update_attributes(name: modified_option)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
# Update radio names
|
|
question.survey_question_radiogroups.each_with_index do |option, index|
|
|
groups_of_radios.each do |radios|
|
|
if radios[index] != option.name_translations["zh_tw"]
|
|
option.update_attributes(name: radios[index])
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
@answer_model.save!
|
|
|
|
end #end row
|
|
|
|
redirect_to panel_survey_back_end_surveys_url, :notice => :success
|
|
end
|
|
|
|
def export
|
|
@survey = ::Survey.find(params[:id])
|
|
@chart_data, @survey_questions, @survey_answers = @survey.generate_chart_data
|
|
|
|
csv = CSV.generate do |csv|
|
|
row = []
|
|
@survey_questions.each do |question|
|
|
row << question.title
|
|
row << ' '
|
|
end
|
|
csv << row
|
|
csv_stats = []
|
|
@survey_questions.each do |question|
|
|
csv_options = []
|
|
csv_counts = []
|
|
case question.type
|
|
when ::SurveyQuestion::Radio, ::SurveyQuestion::Select, ::SurveyQuestion::Check
|
|
question.survey_question_options.map do |option|
|
|
csv_options << option.name
|
|
csv_counts << "#{(@chart_data[question.id.to_s][option.name] || 0 rescue 0)}"
|
|
end
|
|
when ::SurveyQuestion::Radiogroup
|
|
question.survey_question_options.map do |option|
|
|
question.survey_question_radiogroups.map do |group|
|
|
csv_options << "#{option.name} - #{group.name}"
|
|
csv_counts << "#{(@chart_data[question.id.to_s][option.name][group.name] || 0 rescue 0)}"
|
|
end
|
|
end.flatten
|
|
else
|
|
csv_options << " "
|
|
csv_counts << " "
|
|
end
|
|
csv_stats << csv_options
|
|
csv_stats << csv_counts
|
|
end
|
|
max_length = csv_stats.map(&:length).max
|
|
csv_stats.map do |l|
|
|
while l.length < max_length
|
|
l.push ' '
|
|
end
|
|
l
|
|
end.transpose.each do |l|
|
|
csv << l
|
|
end
|
|
@survey_answers.each do |answer|
|
|
row = []
|
|
@survey_questions.each do |question|
|
|
if question.type == ::SurveyQuestion::Radiogroup
|
|
options = Hash[question.survey_question_options.collect{|o| [ o.id.to_s, o.name ] }]
|
|
row << Hash[answer[question.id.to_s].map {|o, g| [options[o], g]}]
|
|
else
|
|
row << answer[question.id.to_s]
|
|
end
|
|
row << ' '
|
|
end
|
|
csv << row
|
|
end
|
|
|
|
end
|
|
|
|
respond_to do |format|
|
|
format.csv do
|
|
response.headers["Content-Type"] = "text/csv; charset=big5"
|
|
render :text => csv.encode('Big5')
|
|
end
|
|
end
|
|
end
|
|
|
|
def set_answers
|
|
@survey = ::Survey.find(params[:id])
|
|
end
|
|
|
|
def jump
|
|
@survey = ::Survey.find(params[:id])
|
|
@questions = @survey.survey_questions.all
|
|
|
|
@jump_to_options = [[ t('survey.not_jump'), 0 ], [t('survey.jump_to_end'), 1]]
|
|
@jump_to_options += @questions.collect {|q| [ q.title, q.id.to_s ] }
|
|
end
|
|
|
|
def duplicate_it
|
|
@survey = ::Survey.find(params[:id])
|
|
|
|
@new_survey = ::Survey.new
|
|
|
|
@survey.attributes.each do |key, value|
|
|
unless ['_id', 'created_at', 'updated_at', 'update_user_id'].include? key
|
|
if @survey.respond_to?(key + '_translations')
|
|
@new_survey.send(key + '_translations=', value)
|
|
else
|
|
@new_survey.write_attribute(key, value)
|
|
end
|
|
end
|
|
end
|
|
|
|
@survey.survey_questions.all.each do |question|
|
|
new_question = @new_survey.survey_questions.new
|
|
question.attributes.each do |key, value|
|
|
unless ['_id', 'survey_id'].include? key
|
|
if question.respond_to?(key + '_translations')
|
|
new_question.send(key + '_translations=', value)
|
|
else
|
|
new_question.write_attribute(key, value)
|
|
end
|
|
end
|
|
end
|
|
|
|
# question.survey_question_options.all.each do |option|
|
|
# new_option = new_question.survey_question_options.new
|
|
# option.attributes.each do |key, value|
|
|
# unless ['_id', 'survey_question_id'].include? key
|
|
# if option.respond_to?(key + '_translations')
|
|
# new_option.name_translations = value
|
|
# else
|
|
# new_option.write_attribute(key, value)
|
|
# end
|
|
# end
|
|
# end
|
|
# end
|
|
|
|
# question.survey_question_radiogroups.all.each do |radiogroup|
|
|
# new_radiogroup = new_question.survey_question_radiogroups.new
|
|
# radiogroup.attributes.each do |key, value|
|
|
# unless ['_id', 'survey_question_id'].include? key
|
|
# if radiogroup.respond_to?(key + '_translations')
|
|
# new_option.name_translations = value
|
|
# else
|
|
# new_radiogroup.write_attribute(key, value)
|
|
# end
|
|
# end
|
|
# end
|
|
# end
|
|
end
|
|
|
|
@new_survey.create_user_id = current_user.id
|
|
@new_survey.update_user_id = current_user.id
|
|
|
|
@new_survey.save!
|
|
|
|
respond_to do |format|
|
|
format.html { redirect_to(panel_survey_back_end_surveys_url) }
|
|
format.xml { render :xml => @survey, :status => :created, :location => @new_survey }
|
|
end
|
|
end
|
|
|
|
end
|