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