orbit-survey/app/controllers/panel/survey/back_end/surveys_controller.rb

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