# encoding: utf-8 class QuestionnaireSurvey include Mongoid::Document include Mongoid::Timestamps include Slug ResultChart = 0 ResultExtern = 1 ResultFile = 2 ResultCriteria = 3 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 field :description, :localize => true field :create_user_id field :update_user_id field :postdate, :type => DateTime field :deadline, :type => DateTime 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 field :extern_link mount_uploader :upload_file, AssetUploader field :result_criteria, type: Array, :default => [] field :jump_mode, :type => Boolean, :default => false field :redirect_mode, :type => Boolean, :default => false field :redirect_url, :type => String # validates :title, :at_least_one => true # validates :title, :presence => { :message => I18n.t("survey.title") } 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 before_save :check_deadline#, :update_avliable_language 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 def update_user=(user) self.update_user_id = user.id end def self.time_range(data) r = "#{data.postdate.to_date}" if data.deadline r += " - #{data.deadline.to_date}" else r += " - #{I18n.t(:no_deadline)}" end r end def self.result(data) if ( data.result_type == QuestionnaireSurvey::ResultChart && data.deadline && Time.now > data.deadline ) || ( data.result_type == QuestionnaireSurvey::ResultExtern && !data.extern_link.blank? ) || ( data.result_type == QuestionnaireSurvey::ResultFile && data.upload_file? ) ('').html_safe else '' end end def self.write(data) unless data.deadline && Time.now > data.deadline ('').html_safe else '' end end def generate_chart_data(match_args={}) survey_questions = self.survey_questions.all 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 use_custom_option = question.custom_option_new_option chart_data[qid] = {} case question.type when SurveyQuestion::Radio, SurveyQuestion::Select options = question.survey_question_options.map{|v| [v.name,v.id.to_s]} survey_answers.each_with_index do |answer,i| answers[i][qid] = SurveysHelper.parse_exel_value(answer[qid], options: options, chart_data: chart_data[qid], use_custom_option: use_custom_option) end when SurveyQuestion::Check options = question.survey_question_options.map{|v| [v.name,v.id.to_s]} survey_answers.each_with_index do |answer,i| answers[i][qid] = SurveysHelper.parse_exel_checkbox_value(answer[qid], options: options, chart_data: chart_data[qid], use_custom_option: use_custom_option) end when SurveyQuestion::Radiogroup options = question.survey_question_options.map{|v| [v.name,v.id.to_s]} radiogroups = question.survey_question_radiogroups.map{|v| [v.name,v.id.to_s]} survey_answers.each_with_index do |answer,i| answers[i][qid] = SurveysHelper.parse_exel_rg_value(answer[qid], options: options, radiogroups: radiogroups, chart_data: chart_data[qid], use_custom_option: use_custom_option) end when SurveyQuestion::DoubleLevelOption custom_option_title = question.custom_option_title.to_s survey_answers.each_with_index do |answer,i| answers[i][qid] = SurveysHelper.parse_exel_double_level_value(answer[qid], other_title: custom_option_title, use_custom_option: use_custom_option, chart_data: chart_data[qid]) end else survey_answers.each_with_index do |answer,i| answers[i][qid] = answer[qid] end end end [chart_data, survey_questions, answers] end def expired? (self.deadline < Time.now) rescue false end def clone_new(clone_mode=false) @records_all = {} if clone_mode clone_target = self.class.find(object.copy_id) rescue nil else clone_target = self end new_object,clone_target = clone_new_for_object(self,clone_target,clone_mode) new_object end def clone_new_for_object(object,clone_target=nil,clone_mode=false) if clone_mode new_object = object clone_target = object.class.find(object.copy_id) rescue nil if clone_target.nil? else clone_target = object if clone_target.nil? new_object = object.dup end return if (self.except_clone_relations.to_s.include?(new_object.class.to_s.underscore) rescue false) @records_all["#{new_object.class.to_s.underscore.singularize}_ids"] = {} if @records_all["#{new_object.class.to_s.underscore.singularize}_ids"].nil? begin @records_all["#{new_object.class.to_s.underscore.singularize}_ids"][clone_target.id] = object.id rescue nil end if !clone_target.nil? && !new_object.nil? initialize_fields = ["uid","created_at","updated_at"] initialize_fields.each do |f| new_object.send("#{f}=",nil) if new_object.fields.keys.include?(f) end relations_fields = clone_target.relations.except("impressions").keys all_fields = clone_target.fields.keys - relations_fields all_fields = all_fields - relations_fields.map{|k| "#{k}_id"} all_fields = all_fields - relations_fields.map{|k| "#{k.singularize}_ids"} new_object_class_name = new_object.class.to_s.underscore relations_fields = clone_target.relations.except("impressions").keys unsort_relation_keys = clone_target.relations.keys unless @parent_level fields_to_delete = [new_object_class_name] tmp_relations_fields = [new_object_class_name] while relations_fields.count > 0 tmp_singularize_relations_fields = tmp_relations_fields.map{|f| f.singularize} approve_append = nil relations_fields.each do |k| belongs_to_class = clone_target.relations[k].class_name.constantize.relations.select{|k,v| v.macro == :belongs_to}.keys has_many_class = clone_target.relations[k].class_name.constantize.relations.select{|k,v| v.macro == :has_many}.keys if (belongs_to_class - tmp_singularize_relations_fields).count == 0 other_has_many_class = (has_many_class - unsort_relation_keys) if other_has_many_class.count == 0 tmp_relations_fields << k else result = other_has_many_class.map do |k| belongs_to_class = k.classify.constantize.relations.select{|kk,v| v.macro == :belongs_to}.keys has_many_class = k.classify.constantize.relations.select{|kk,v| v.macro == :has_many}.keys if (belongs_to_class - tmp_singularize_relations_fields).count == 0 true else fields_to_delete = fields_to_delete.concat(belongs_to_class) tmp_relations_fields.concat(belongs_to_class) false end end if result.select{|t| !t}.count == 0 if (fields_to_delete.map{|f| f.pluralize} - tmp_relations_fields).count == 0 tmp_relations_fields << k elsif clone_target.relations[k].class_name.constantize.fields.keys.include?("key") tmp_relations_fields << k elsif (clone_target.relations[k].class_name.constantize.relations.keys.map{|f| f.singularize} & fields_to_delete).count != 0 approve_append = k end end end elsif !unsort_relation_keys.include?(clone_target.relations[k].class_name.underscore) && !unsort_relation_keys.include?(clone_target.relations[k].class_name.underscore.pluralize) tmp_relations_fields << k end end tmp_relations_fields << approve_append if approve_append.present? approve_append = nil relations_fields = relations_fields - tmp_relations_fields end relations_fields = tmp_relations_fields fields_to_delete.each{|f| relations_fields.delete(f)} @clone_mode = clone_mode end @parent_level = true if clone_mode all_fields.each do |f| next if f == "uid" unless new_object.send("#{f}_changed?") && new_object.send("#{f}_changed_from_default?") new_object.send("#{f}=",clone_target.send(f)) end end end relations_fields.each do |f| no_dup_flag = false if clone_target.relations[f].macro == :belongs_to || clone_target.relations[f].macro == :has_one no_dup_flag = new_object.send(f).present? elsif clone_target.relations[f].macro == :has_many no_dup_flag = new_object.send(f).to_a.count != 0 elsif clone_target.relations[f].macro == :embeds_many #Fix localize fields if new_object.send(f).to_a.count != 0 need_fix_fields = new_object.send(f).to_a[0].fields.select{|k,v| (v.options[:localize] rescue false)}.keys locale = I18n.locale.to_s embeded_records = new_object.send(f).map do |embeded_record| need_fix_fields.each do |f| if (embeded_record[f][locale].class != String rescue false) embeded_record.send("#{f}_translations=",embeded_record[f][locale]) else embeded_record.send("#{f}_translations=",embeded_record[f]) end end embeded_record end new_object.send("#{f}=",embeded_records) end end if clone_target.relations[f].macro == :belongs_to || clone_target.relations[f].class_name == "MemberProfile" if @records_all["#{f}_ids"].nil? new_object.send("#{f}_id=",clone_target.send("#{f}_id")) else new_object.send("#{f}_id=",(@records_all["#{f}_ids"][clone_target.send("#{f}_id")])) end elsif clone_target.relations[f].macro == :has_one next if (self.except_clone_relations.to_s.include?(f) rescue false) need_clone_relation = clone_target.send(f) clone_relation = new_object.send(f) clone_relation = need_clone_relation.dup if clone_relation.nil? initialize_fields.each do |f| clone_relation.send("#{f}=",nil) if clone_relation.fields.keys.include?(f) end check_fields = clone_relation.fields.except(initialize_fields) check_fields.keys.each do |f| if (clone_relation.send(f).class.to_s.match(/uploader/i) rescue false) if clone_relation[f].blank? && (clone_relation.send(f).file.nil? rescue true) clone_relation[f] = r[f] source_filepath = r.send(f).file.file if @clone_mode dest_filepath = clone_relation.send(f).file.file FileUtils.mkdir_p(File.dirname(dest_filepath)) FileUtils.cp(source_filepath,dest_filepath) end elsif (clone_relation.send(f).file rescue nil) clone_relation[f] = File.basename(clone_relation.send(f).file.file.to_s) end file_flag = true end end new_object.send("#{f}=",clone_relation) elsif clone_target.relations[f].macro == :has_many next if (self.except_clone_relations.to_s.include?(f) rescue false) clone_relations = [] need_clone_relations = clone_target.send(f).asc(:_id).to_a file_flag = false need_clone_relations.each_with_index do |r,i| clone_relation = new_object.send(f)[i] clone_relation = r.dup if clone_relation.nil? initialize_fields.each do |f| clone_relation.send("#{f}=",nil) if clone_relation.fields.keys.include?(f) end check_fields = clone_relation.fields.except(initialize_fields) check_fields.keys.each do |f| if (clone_relation.send(f).class.to_s.match(/uploader/i) rescue false) if clone_relation[f].blank? && (clone_relation.send(f).file.nil? rescue true) clone_relation[f] = r[f] source_filepath = r.send(f).file.file if @clone_mode dest_filepath = clone_relation.send(f).file.file FileUtils.mkdir_p(File.dirname(dest_filepath)) FileUtils.cp(source_filepath,dest_filepath) end elsif (clone_relation.send(f).file rescue nil) clone_relation[f] = File.basename(clone_relation.send(f).file.file.to_s) end file_flag = true end end clone_relations << clone_relation end if !no_dup_flag || (no_dup_flag && file_flag) new_object_relations = new_object.send(f).to_a if new_object_relations.count != 0 if clone_relations.count > new_object_relations.count clone_relations = clone_relations[0...new_object_relations.count] else clone_relations = clone_relations.concat(new_object.send(f)[clone_relations.count...new_object_relations.count]) end new_object.send("#{f}=",clone_relations) else new_object.send("#{f}=",clone_relations) end end count_array = (0...new_object.send(f).to_a.count).to_a count_array.each do |i| clone_new_for_object(new_object.send(f)[i],need_clone_relations[i],true) end end end new_object.copy_id = clone_target.id if new_object.fields.keys.include?("copy_id") return new_object, clone_target end end protected def check_deadline if(!self.deadline.nil? and (self.deadline < self.postdate )) self.deadline = nil end end # def update_avliable_language # VALID_LOCALES.each do |locale| # if (title_translations[locale].blank? rescue true) # self["available_for_#{locale}".to_sym] = false # else # self["available_for_#{locale}".to_sym] = true # end # end # end # paginates_per 10 end